1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 // Author: kenton@google.com (Kenton Varda) 9 // Based on original Protocol Buffers design by 10 // Sanjay Ghemawat, Jeff Dean, and others. 11 12 #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__ 13 #define GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__ 14 15 #include <string> 16 17 #include "absl/container/flat_hash_map.h" 18 #include "absl/strings/string_view.h" 19 #include "google/protobuf/compiler/cpp/helpers.h" 20 #include "google/protobuf/compiler/cpp/options.h" 21 #include "google/protobuf/port.h" 22 23 // Must be included last. 24 #include "google/protobuf/port_def.inc" 25 26 namespace google { 27 namespace protobuf { 28 class FieldDescriptor; // descriptor.h 29 namespace io { 30 class Printer; // printer.h 31 } 32 } // namespace protobuf 33 } // namespace google 34 35 namespace google { 36 namespace protobuf { 37 namespace compiler { 38 namespace cpp { 39 40 class MessageSCCAnalyzer; 41 42 // Generates code for an extension, which may be within the scope of some 43 // message or may be at file scope. This is much simpler than FieldGenerator 44 // since extensions are just simple identifiers with interesting types. 45 class PROTOC_EXPORT ExtensionGenerator { 46 public: 47 // See generator.cc for the meaning of dllexport_decl. 48 explicit ExtensionGenerator(const FieldDescriptor* descriptor, 49 const Options& options, 50 MessageSCCAnalyzer* scc_analyzer); 51 ExtensionGenerator(const ExtensionGenerator&) = delete; 52 ExtensionGenerator& operator=(const ExtensionGenerator&) = delete; 53 ~ExtensionGenerator(); 54 55 // Header stuff. 56 void GenerateDeclaration(io::Printer* p) const; 57 58 // Source file stuff. 59 void GenerateDefinition(io::Printer* p); 60 61 // Extension registration can happen at different priority levels depending on 62 // the features used. 63 // 64 // For Weak Descriptor messages, we must use a two phase approach where we 65 // first register all the extensions that are fully linked in, and then we 66 // register the rest. To do that, we register the linked in extensions on 67 // priority 101 and the rest as priority 102. 68 // For extensions that are missing prototypes we need to create the prototypes 69 // before we can register them, but for that we need to successfully parse 70 // its descriptors, which might require other extensions to be registered 71 // first. All extensions required for descriptor parsing will be fully linked 72 // in and registered in the first phase. 73 void GenerateRegistration(io::Printer* p, InitPriority priority); 74 bool WillGenerateRegistration(InitPriority priority); 75 76 bool IsScoped() const; 77 78 private: 79 const FieldDescriptor* descriptor_; 80 std::string type_traits_; 81 Options options_; 82 MessageSCCAnalyzer* scc_analyzer_; 83 84 absl::flat_hash_map<absl::string_view, std::string> variables_; 85 }; 86 87 } // namespace cpp 88 } // namespace compiler 89 } // namespace protobuf 90 } // namespace google 91 92 #include "google/protobuf/port_undef.inc" 93 94 #endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ 95