From 5a76e633ea9b5adb215e93fdc11e1c0c08b3fc74 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Thu, 17 Nov 2016 16:48:38 -0800 Subject: Integrated internal changes from Google --- src/google/protobuf/compiler/cpp/cpp_file.cc | 561 ++++++++++++++------------- 1 file changed, 287 insertions(+), 274 deletions(-) (limited to 'src/google/protobuf/compiler/cpp/cpp_file.cc') diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 369497ce..63aee4ff 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -60,33 +60,42 @@ namespace cpp { FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) : file_(file), options_(options), - message_generators_( - new google::protobuf::scoped_ptr[file->message_type_count()]), - enum_generators_( - new google::protobuf::scoped_ptr[file->enum_type_count()]), - service_generators_( - new google::protobuf::scoped_ptr[file->service_count()]), - extension_generators_( - new google::protobuf::scoped_ptr[file->extension_count()]) { + message_generators_owner_( + new google::protobuf::scoped_ptr[ file->message_type_count() ]), + enum_generators_owner_( + new google::protobuf::scoped_ptr[ file->enum_type_count() ]), + service_generators_owner_( + new google::protobuf::scoped_ptr[ file->service_count() ]), + extension_generators_owner_( + new google::protobuf::scoped_ptr[ file->extension_count() ]) { for (int i = 0; i < file->message_type_count(); i++) { - message_generators_[i].reset( - new MessageGenerator(file->message_type(i), options)); + message_generators_owner_[i].reset( + new MessageGenerator(file->message_type(i), options)); + message_generators_owner_[i]->Flatten(&message_generators_); + } + + for (int i = 0; i < message_generators_.size(); i++) { + message_generators_[i]->AddGenerators(&enum_generators_, + &extension_generators_); } for (int i = 0; i < file->enum_type_count(); i++) { - enum_generators_[i].reset( - new EnumGenerator(file->enum_type(i), options)); + enum_generators_owner_[i].reset( + new EnumGenerator(file->enum_type(i), options)); + enum_generators_.push_back(enum_generators_owner_[i].get()); } for (int i = 0; i < file->service_count(); i++) { - service_generators_[i].reset( - new ServiceGenerator(file->service(i), options)); + service_generators_owner_[i].reset( + new ServiceGenerator(file->service(i), options)); + service_generators_.push_back(service_generators_owner_[i].get()); } for (int i = 0; i < file->extension_count(); i++) { - extension_generators_[i].reset( - new ExtensionGenerator(file->extension(i), options)); + extension_generators_owner_[i].reset( + new ExtensionGenerator(file->extension(i), options)); + extension_generators_.push_back(extension_generators_owner_[i].get()); } package_parts_ = Split(file_->package(), ".", true); @@ -94,29 +103,7 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) FileGenerator::~FileGenerator() {} -void FileGenerator::GenerateProtoHeader(io::Printer* printer, - const string& info_path) { - if (!options_.proto_h) { - return; - } - - string filename_identifier = FilenameIdentifier(file_->name()); - GenerateTopHeaderGuard(printer, filename_identifier); - - - GenerateLibraryIncludes(printer); - - for (int i = 0; i < file_->public_dependency_count(); i++) { - const FileDescriptor* dep = file_->public_dependency(i); - const char* extension = ".proto.h"; - string dependency = StripProto(dep->name()) + extension; - printer->Print( - "#include \"$dependency$\" // IWYU pragma: export\n", - "dependency", dependency); - } - - GenerateMetadataPragma(printer, info_path); - +void FileGenerator::GenerateHeader(io::Printer* printer) { printer->Print( "// @@protoc_insertion_point(includes)\n"); @@ -166,6 +153,32 @@ void FileGenerator::GenerateProtoHeader(io::Printer* printer, "\n" "// @@protoc_insertion_point(global_scope)\n" "\n"); +} + +void FileGenerator::GenerateProtoHeader(io::Printer* printer, + const string& info_path) { + if (!options_.proto_h) { + return; + } + + string filename_identifier = FilenameIdentifier(file_->name()); + GenerateTopHeaderGuard(printer, filename_identifier); + + + GenerateLibraryIncludes(printer); + + for (int i = 0; i < file_->public_dependency_count(); i++) { + const FileDescriptor* dep = file_->public_dependency(i); + const char* extension = ".proto.h"; + string dependency = StripProto(dep->name()) + extension; + printer->Print( + "#include \"$dependency$\" // IWYU pragma: export\n", + "dependency", dependency); + } + + GenerateMetadataPragma(printer, info_path); + + GenerateHeader(printer); GenerateBottomHeaderGuard(printer, filename_identifier); } @@ -185,59 +198,29 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer, GenerateDependencyIncludes(printer); GenerateMetadataPragma(printer, info_path); - printer->Print( - "// @@protoc_insertion_point(includes)\n"); - - - - // Open namespace. - GenerateNamespaceOpeners(printer); - if (!options_.proto_h) { - GenerateGlobalStateFunctionDeclarations(printer); - GenerateMessageForwardDeclarations(printer); - - printer->Print("\n"); - - GenerateEnumDefinitions(printer); - - printer->Print(kThickSeparator); - printer->Print("\n"); - - GenerateMessageDefinitions(printer); - - printer->Print("\n"); - printer->Print(kThickSeparator); - printer->Print("\n"); - - GenerateServiceDefinitions(printer); - - GenerateExtensionIdentifiers(printer); - - printer->Print("\n"); - printer->Print(kThickSeparator); - printer->Print("\n"); - - GenerateInlineFunctionDefinitions(printer); - } - - printer->Print( - "\n" - "// @@protoc_insertion_point(namespace_scope)\n"); + GenerateHeader(printer); + } else { + // This is unfortunately necessary for some plugins. I don't see why we + // need two of the same insertion points. + // TODO(gerbens) remove this. + printer->Print( + "// @@protoc_insertion_point(includes)\n"); - // Close up namespace. - GenerateNamespaceClosers(printer); + // Open namespace. + GenerateNamespaceOpeners(printer); + printer->Print( + "\n" + "// @@protoc_insertion_point(namespace_scope)\n"); + // Close up namespace. + GenerateNamespaceClosers(printer); - if (!options_.proto_h) { - // We need to specialize some templates in the ::google::protobuf namespace: - GenerateProto2NamespaceEnumSpecializations(printer); + printer->Print( + "\n" + "// @@protoc_insertion_point(global_scope)\n" + "\n"); } - printer->Print( - "\n" - "// @@protoc_insertion_point(global_scope)\n" - "\n"); - GenerateBottomHeaderGuard(printer, filename_identifier); } @@ -267,7 +250,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) { "right", use_system_include ? ">" : "\""); // Unknown fields implementation in lite mode uses StringOutputStream - if (!UseUnknownFieldSet(file_, options_) && file_->message_type_count() > 0) { + if (!UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) { printer->Print( "#include \n"); } @@ -297,25 +280,48 @@ void FileGenerator::GenerateSource(io::Printer* printer) { GenerateNamespaceOpeners(printer); + for (int i = 0; i < message_generators_.size(); i++) { + if (IsMapEntryMessage(message_generators_[i]->descriptor_)) continue; + printer->Print( + "class $classname$DefaultTypeInternal : " + "public ::google::protobuf::internal::ExplicitlyConstructed<$classname$> {};\n" + "$classname$DefaultTypeInternal _$classname$_default_instance_;\n", + "classname", message_generators_[i]->classname_); + } + if (HasDescriptorMethods(file_, options_)) { printer->Print( "\n" "namespace {\n" "\n"); - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateDescriptorDeclarations(printer); + + if (!message_generators_.empty()) { + printer->Print("::google::protobuf::Metadata file_level_metadata[$size$];\n", + "size", SimpleItoa(message_generators_.size())); } - for (int i = 0; i < file_->enum_type_count(); i++) { + if (!enum_generators_.empty()) { printer->Print( - "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n", - "name", ClassName(file_->enum_type(i), false)); + "const ::google::protobuf::EnumDescriptor* " + "file_level_enum_descriptors[$size$];\n", + "size", SimpleItoa(enum_generators_.size())); + } + if (HasGenericServices(file_, options_) && file_->service_count() > 0) { + printer->Print( + "const ::google::protobuf::ServiceDescriptor* " + "file_level_service_descriptors[$size$];\n", + "size", SimpleItoa(file_->service_count())); } + for (int i = 0; i < message_generators_.size(); i++) { + message_generators_[i]->index_in_metadata_ = i; + message_generators_[i]->GenerateDescriptorDeclarations(printer); + } + for (int i = 0; i < enum_generators_.size(); i++) { + enum_generators_[i]->index_in_metadata_ = i; + } if (HasGenericServices(file_, options_)) { - for (int i = 0; i < file_->service_count(); i++) { - printer->Print( - "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n", - "name", file_->service(i)->name()); + for (int i = 0; i < service_generators_.size(); i++) { + service_generators_[i]->index_in_metadata_ = i; } } @@ -330,26 +336,12 @@ void FileGenerator::GenerateSource(io::Printer* printer) { GenerateBuildDescriptors(printer); // Generate enums. - for (int i = 0; i < file_->enum_type_count(); i++) { + for (int i = 0; i < enum_generators_.size(); i++) { enum_generators_[i]->GenerateMethods(printer); } // Generate classes. - for (int i = 0; i < file_->message_type_count(); i++) { - if (i == 0 && HasGeneratedMethods(file_, options_)) { - printer->Print( - "\n" - "namespace {\n" - "\n" - "static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD" - " GOOGLE_ATTRIBUTE_NORETURN;\n" - "static void MergeFromFail(int line) {\n" - " ::google::protobuf::internal::MergeFromFail(__FILE__, line);\n" - "}\n" - "\n" - "} // namespace\n" - "\n"); - } + for (int i = 0; i < message_generators_.size(); i++) { printer->Print("\n"); printer->Print(kThickSeparator); printer->Print("\n"); @@ -364,7 +356,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) { if (HasGenericServices(file_, options_)) { // Generate services. - for (int i = 0; i < file_->service_count(); i++) { + for (int i = 0; i < service_generators_.size(); i++) { if (i == 0) printer->Print("\n"); printer->Print(kThickSeparator); printer->Print("\n"); @@ -373,7 +365,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) { } // Define extensions. - for (int i = 0; i < file_->extension_count(); i++) { + for (int i = 0; i < extension_generators_.size(); i++) { extension_generators_[i]->GenerateDefinition(printer); } @@ -391,8 +383,9 @@ void FileGenerator::GenerateSource(io::Printer* printer) { class FileGenerator::ForwardDeclarations { public: ~ForwardDeclarations() { - for (map::iterator it = namespaces_.begin(), - end = namespaces_.end(); + for (std::map::iterator + it = namespaces_.begin(), + end = namespaces_.end(); it != end; ++it) { delete it->second; } @@ -407,11 +400,11 @@ class FileGenerator::ForwardDeclarations { return ns; } - map& classes() { return classes_; } - map& enums() { return enums_; } + std::map& classes() { return classes_; } + std::map& enums() { return enums_; } void Print(io::Printer* printer) const { - for (map::const_iterator + for (std::map::const_iterator it = enums_.begin(), end = enums_.end(); it != end; ++it) { @@ -420,13 +413,21 @@ class FileGenerator::ForwardDeclarations { printer->Print("bool $enumname$_IsValid(int value);\n", "enumname", it->first); } - for (map::const_iterator it = classes_.begin(), - end = classes_.end(); + for (std::map::const_iterator + it = classes_.begin(), + end = classes_.end(); it != end; ++it) { printer->Print("class $classname$;\n", "classname", it->first); printer->Annotate("classname", it->second); + + printer->Print( + "class $classname$DefaultTypeInternal;\n" + "extern $classname$DefaultTypeInternal " + "_$classname$_default_instance_;\n", // NOLINT + "classname", + it->first); } - for (map::const_iterator + for (std::map::const_iterator it = namespaces_.begin(), end = namespaces_.end(); it != end; ++it) { @@ -440,9 +441,9 @@ class FileGenerator::ForwardDeclarations { private: - map namespaces_; - map classes_; - map enums_; + std::map namespaces_; + std::map classes_; + std::map enums_; }; void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { @@ -465,75 +466,135 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { // and we only use AddDescriptors() to allocate default instances. if (HasDescriptorMethods(file_, options_)) { - printer->Print( - "\n" - "void $assigndescriptorsname$() GOOGLE_ATTRIBUTE_COLD;\n" - "void $assigndescriptorsname$() {\n", - "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name())); - printer->Indent(); - - // Make sure the file has found its way into the pool. If a descriptor - // is requested *during* static init then AddDescriptors() may not have - // been called yet, so we call it manually. Note that it's fine if - // AddDescriptors() is called multiple times. - printer->Print( - "$adddescriptorsname$();\n", - "adddescriptorsname", GlobalAddDescriptorsName(file_->name())); + if (!message_generators_.empty()) { + printer->Print( + "\n" + "const ::google::protobuf::uint32* $offsetfunname$() GOOGLE_ATTRIBUTE_COLD;\n" + "const ::google::protobuf::uint32* $offsetfunname$() {\n", + "offsetfunname", GlobalOffsetTableName(file_->name())); + printer->Indent(); - // Get the file's descriptor from the pool. - printer->Print( - "const ::google::protobuf::FileDescriptor* file =\n" - " ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n" - " \"$filename$\");\n" - // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file" - // being unused when compiling an empty .proto file. - "GOOGLE_CHECK(file != NULL);\n", - "filename", file_->name()); + printer->Print("static const ::google::protobuf::uint32 offsets[] = {\n"); + printer->Indent(); + std::vector > pairs; + for (int i = 0; i < message_generators_.size(); i++) { + pairs.push_back(message_generators_[i]->GenerateOffsets(printer)); + } + printer->Outdent(); + printer->Outdent(); + printer->Print( + " };\n" + " return offsets;\n" + "}\n" + "\n"); - // Go through all the stuff defined in this file and generated code to - // assign the global descriptor pointers based on the file descriptor. - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateDescriptorInitializer(printer, i); - } - for (int i = 0; i < file_->enum_type_count(); i++) { - enum_generators_[i]->GenerateDescriptorInitializer(printer, i); - } - if (HasGenericServices(file_, options_)) { - for (int i = 0; i < file_->service_count(); i++) { - service_generators_[i]->GenerateDescriptorInitializer(printer, i); + printer->Print( + "static const ::google::protobuf::internal::MigrationSchema schemas[] = {\n"); + printer->Indent(); + { + int offset = 0; + for (int i = 0; i < message_generators_.size(); i++) { + message_generators_[i]->GenerateSchema(printer, offset, + pairs[i].second); + offset += pairs[i].first; + } + } + printer->Outdent(); + printer->Print( + "};\n" + "\n" + "static const ::google::protobuf::internal::DefaultInstanceData " + "file_default_instances[] = {\n"); + printer->Indent(); + for (int i = 0; i < message_generators_.size(); i++) { + const Descriptor* descriptor = message_generators_[i]->descriptor_; + if (IsMapEntryMessage(descriptor)) continue; + + string oneof_default = "NULL"; + if (message_generators_[i]->descriptor_->oneof_decl_count()) { + oneof_default = + "&" + ClassName(descriptor, false) + "_default_oneof_instance_"; + } + printer->Print( + "{reinterpret_cast(&_$classname$_default_instance_), " + "$oneof_default$},\n", + "classname", ClassName(descriptor, false), "oneof_default", + oneof_default); } + printer->Outdent(); + printer->Print( + "};\n" + "\n"); + } else { + // we still need these symbols to exist + printer->Print( + "inline ::google::protobuf::uint32* $offsetfunname$() { return NULL; }\n" + "static const ::google::protobuf::internal::MigrationSchema* schemas = NULL;\n" + "static const ::google::protobuf::internal::DefaultInstanceData* " + "file_default_instances = NULL;\n", + "offsetfunname", + GlobalOffsetTableName(file_->name())); } - printer->Outdent(); - printer->Print( - "}\n" - "\n"); - // --------------------------------------------------------------- // protobuf_AssignDescriptorsOnce(): The first time it is called, calls // AssignDescriptors(). All later times, waits for the first call to // complete and then returns. + string message_factory = "NULL"; printer->Print( "namespace {\n" "\n" - "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n" + "void protobuf_AssignDescriptors() {\n" + // Make sure the file has found its way into the pool. If a descriptor + // is requested *during* static init then AddDescriptors() may not have + // been called yet, so we call it manually. Note that it's fine if + // AddDescriptors() is called multiple times. + " $adddescriptorsname$();\n" + " ::google::protobuf::MessageFactory* factory = $factory$;\n" + " AssignDescriptors(\n" + " \"$filename$\", schemas, file_default_instances, " + "$offsetfunname$(), factory,\n" + " $metadata$, $enum_descriptors$, $service_descriptors$);\n" + "}\n" + "\n" "void protobuf_AssignDescriptorsOnce() {\n" - " ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n" - " &$assigndescriptorsname$);\n" + " static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n" + " ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);\n" "}\n" "\n", - "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name())); - - // protobuf_RegisterTypes(): Calls - // MessageFactory::InternalRegisterGeneratedType() for each message type. + "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), + "offsetfunname", GlobalOffsetTableName(file_->name()), "filename", + file_->name(), "metadata", + !message_generators_.empty() ? "file_level_metadata" : "NULL", + "enum_descriptors", + !enum_generators_.empty() ? "file_level_enum_descriptors" : "NULL", + "service_descriptors", + HasGenericServices(file_, options_) && file_->service_count() > 0 + ? "file_level_service_descriptors" + : "NULL", + "factory", message_factory); + + // Only here because of useless string reference that we don't want in + // protobuf_AssignDescriptorsOnce, because that is called from all the + // GetMetadata member methods. printer->Print( "void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;\n" "void protobuf_RegisterTypes(const ::std::string&) {\n" " protobuf_AssignDescriptorsOnce();\n"); printer->Indent(); - for (int i = 0; i < file_->message_type_count(); i++) { + // All normal messages can be done generically + if (!message_generators_.empty()) { + printer->Print( + "::google::protobuf::internal::RegisterAllTypes(file_level_metadata, $size$);\n", + "size", SimpleItoa(message_generators_.size())); + } + + // Map types are treated special + // TODO(gerbens) find a way to treat maps more like normal messages. + for (int i = 0; i < message_generators_.size(); i++) { message_generators_[i]->GenerateTypeRegistrations(printer); } @@ -553,7 +614,7 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { "shutdownfilename", GlobalShutdownFileName(file_->name())); printer->Indent(); - for (int i = 0; i < file_->message_type_count(); i++) { + for (int i = 0; i < message_generators_.size(); i++) { message_generators_[i]->GenerateShutdownCode(printer); } @@ -566,8 +627,8 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { // Now generate the InitDefaults() function. printer->Print( "void $initdefaultsname$_impl() {\n" - " GOOGLE_PROTOBUF_VERIFY_VERSION;\n" - "\n", + " GOOGLE_PROTOBUF_VERIFY_VERSION;\n\n" + "", // Vars. "initdefaultsname", GlobalInitDefaultsName(file_->name())); @@ -586,26 +647,28 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { "name", add_desc_name); } + // Force initialization of primitive values we depend on. + printer->Print("::google::protobuf::internal::InitProtobufDefaults();\n"); + // Allocate and initialize default instances. This can't be done lazily // since default instances are returned by simple accessors and are used with // extensions. Speaking of which, we also register extensions at this time. - for (int i = 0; i < file_->message_type_count(); i++) { + for (int i = 0; i < message_generators_.size(); i++) { message_generators_[i]->GenerateDefaultInstanceAllocator(printer); } - for (int i = 0; i < file_->extension_count(); i++) { + for (int i = 0; i < extension_generators_.size(); i++) { extension_generators_[i]->GenerateRegistration(printer); } - for (int i = 0; i < file_->message_type_count(); i++) { + for (int i = 0; i < message_generators_.size(); i++) { message_generators_[i]->GenerateDefaultInstanceInitializer(printer); } printer->Outdent(); printer->Print( "}\n" "\n" - "GOOGLE_PROTOBUF_DECLARE_ONCE($initdefaultsname$_once_);\n" "void $initdefaultsname$() {\n" - " ::google::protobuf::GoogleOnceInit(&$initdefaultsname$_once_,\n" - " &$initdefaultsname$_impl);\n" + " static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n" + " ::google::protobuf::GoogleOnceInit(&once, &$initdefaultsname$_impl);\n" "}\n", "initdefaultsname", GlobalInitDefaultsName(file_->name())); @@ -614,8 +677,6 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { // Now generate the AddDescriptors() function. printer->Print( "void $adddescriptorsname$_impl() {\n" - " GOOGLE_PROTOBUF_VERIFY_VERSION;\n" - "\n" " $initdefaultsname$();\n", // Vars. "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), @@ -632,60 +693,42 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { string file_data; file_proto.SerializeToString(&file_data); + printer->Print("static const char descriptor[] = {\n"); + printer->Indent(); + #ifdef _MSC_VER bool breakdown_large_file = true; #else bool breakdown_large_file = false; #endif - // Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535 - // bytes in length". Declare a static array of characters rather than use a - // string literal. - if (breakdown_large_file && file_data.size() > 65535) { - // This has to be explicitly marked as a signed char because the generated - // code puts negative values in the array, and sometimes plain char is - // unsigned. That implicit narrowing conversion is not allowed in C++11. - // - // has details on why. - printer->Print( - "static const signed char descriptor[] = {\n"); - printer->Indent(); - - // Only write 25 bytes per line. + if (breakdown_large_file && file_data.size() > 66538) { + // Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535 + // bytes in length". Declare a static array of characters rather than use + // a string literal. Only write 25 bytes per line. static const int kBytesPerLine = 25; for (int i = 0; i < file_data.size();) { - for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) { - printer->Print( - "$char$, ", - "char", SimpleItoa(file_data[i])); - } - printer->Print( - "\n"); + for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) { + printer->Print("'$char$', ", "char", + CEscape(file_data.substr(i, 1))); + } + printer->Print("\n"); } - - printer->Outdent(); - printer->Print( - "};\n"); - - printer->Print( - "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(descriptor, $size$);\n", - "size", SimpleItoa(file_data.size())); - } else { - printer->Print( - "::google::protobuf::DescriptorPool::InternalAddGeneratedFile("); - // Only write 40 bytes per line. static const int kBytesPerLine = 40; for (int i = 0; i < file_data.size(); i += kBytesPerLine) { - printer->Print("\n \"$data$\"", - "data", - EscapeTrigraphs( - CEscape(file_data.substr(i, kBytesPerLine)))); + printer->Print(" \"$data$\"\n", "data", + EscapeTrigraphs(CEscape( + file_data.substr(i, kBytesPerLine)))); + } } + + printer->Outdent(); + printer->Print("};\n"); printer->Print( - ", $size$);\n", + "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(\n" + " descriptor, $size$);\n", "size", SimpleItoa(file_data.size())); - } // Call MessageFactory::InternalRegisterGeneratedFile(). printer->Print( @@ -777,14 +820,11 @@ void FileGenerator::FillForwardDeclarations(ForwardDeclarations* decls) { decls = decls->AddOrGetNamespace(package_parts_[i]); } // Generate enum definitions. - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->FillEnumForwardDeclarations(&decls->enums()); - } - for (int i = 0; i < file_->enum_type_count(); i++) { + for (int i = 0; i < enum_generators_.size(); i++) { enum_generators_[i]->FillForwardDeclaration(&decls->enums()); } // Generate forward declarations of classes. - for (int i = 0; i < file_->message_type_count(); i++) { + for (int i = 0; i < message_generators_.size(); i++) { message_generators_[i]->FillMessageForwardDeclarations( &decls->classes()); } @@ -840,12 +880,10 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { printer->Print( "#include \n" "#include \n" - "#include \n"); - if (UseUnknownFieldSet(file_, options_)) { - printer->Print( - "#include \n"); - } - if (file_->message_type_count() > 0) { + "#include \n" + "#include \n"); + + if (!message_generators_.empty()) { if (HasDescriptorMethods(file_, options_)) { printer->Print( "#include \n"); @@ -855,8 +893,10 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { } } printer->Print( - "#include \n" - "#include \n"); + "#include " + " // IWYU pragma: export\n" + "#include " + " // IWYU pragma: export\n"); if (HasMapFields(file_)) { printer->Print( "#include \n"); @@ -884,7 +924,7 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { "#include \n"); } - if (UseUnknownFieldSet(file_, options_) && file_->message_type_count() > 0) { + if (UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) { printer->Print( "#include \n"); } @@ -910,7 +950,7 @@ void FileGenerator::GenerateMetadataPragma(io::Printer* printer, } void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) { - set public_import_names; + std::set public_import_names; for (int i = 0; i < file_->public_dependency_count(); i++) { public_import_names.insert(file_->public_dependency(i)->name()); } @@ -943,33 +983,11 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations( "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), "dllexport_decl", options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " "); - - printer->Print( - // Note that we don't put dllexport_decl on these because they are only - // called by the .pb.cc file in which they are defined. - "void $assigndescriptorsname$();\n" - "void $shutdownfilename$();\n" - "\n", - "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()), - "shutdownfilename", GlobalShutdownFileName(file_->name())); -} - -void FileGenerator::GenerateMessageForwardDeclarations(io::Printer* printer) { - map classes; - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->FillMessageForwardDeclarations(&classes); - } - for (map::const_iterator it = classes.begin(), - end = classes.end(); - it != end; ++it) { - printer->Print("class $classname$;\n", "classname", it->first); - printer->Annotate("classname", it->second); - } } void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) { // Generate class definitions. - for (int i = 0; i < file_->message_type_count(); i++) { + for (int i = 0; i < message_generators_.size(); i++) { if (i > 0) { printer->Print("\n"); printer->Print(kThinSeparator); @@ -981,10 +999,7 @@ void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) { void FileGenerator::GenerateEnumDefinitions(io::Printer* printer) { // Generate enum definitions. - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateEnumDefinitions(printer); - } - for (int i = 0; i < file_->enum_type_count(); i++) { + for (int i = 0; i < enum_generators_.size(); i++) { enum_generators_[i]->GenerateDefinition(printer); } } @@ -992,7 +1007,7 @@ void FileGenerator::GenerateEnumDefinitions(io::Printer* printer) { void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) { if (HasGenericServices(file_, options_)) { // Generate service definitions. - for (int i = 0; i < file_->service_count(); i++) { + for (int i = 0; i < service_generators_.size(); i++) { if (i > 0) { printer->Print("\n"); printer->Print(kThinSeparator); @@ -1008,9 +1023,10 @@ void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) { } void FileGenerator::GenerateExtensionIdentifiers(io::Printer* printer) { - // Declare extension identifiers. + // Declare extension identifiers. These are in global scope and so only + // the global scope extensions. for (int i = 0; i < file_->extension_count(); i++) { - extension_generators_[i]->GenerateDeclaration(printer); + extension_generators_owner_[i]->GenerateDeclaration(printer); } } @@ -1051,7 +1067,7 @@ void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) { printer->Print("#if !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); // Generate class inline methods. - for (int i = 0; i < file_->message_type_count(); i++) { + for (int i = 0; i < message_generators_.size(); i++) { if (i > 0) { printer->Print(kThinSeparator); printer->Print("\n"); @@ -1061,7 +1077,7 @@ void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) { } printer->Print("#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); - for (int i = 0; i < file_->message_type_count(); i++) { + for (int i = 0; i < message_generators_.size(); i++) { if (i > 0) { printer->Print(kThinSeparator); printer->Print("\n"); @@ -1084,10 +1100,7 @@ void FileGenerator::GenerateProto2NamespaceEnumSpecializations( "#ifndef SWIG\n" "namespace google {\nnamespace protobuf {\n" "\n"); - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); - } - for (int i = 0; i < file_->enum_type_count(); i++) { + for (int i = 0; i < enum_generators_.size(); i++) { enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); } printer->Print( -- cgit v1.2.3