diff options
author | kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d> | 2009-07-29 01:13:20 +0000 |
---|---|---|
committer | kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d> | 2009-07-29 01:13:20 +0000 |
commit | 80b1d62bfcea65c59e2160da71dad84b1bd19cef (patch) | |
tree | 5423b830c53174fec83a7ea01ff0877e11c1ddb6 /src/google/protobuf/compiler/cpp/cpp_file.cc | |
parent | d2fd0638c309113ccae3731a58e30419f522269a (diff) |
Submit recent changes from internal branch, including "lite mode" for
C++ and Java. See CHANGES.txt for more details.
Diffstat (limited to 'src/google/protobuf/compiler/cpp/cpp_file.cc')
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_file.cc | 315 |
1 files changed, 183 insertions, 132 deletions
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index f056ed57..51859bb3 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -125,13 +125,18 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { // OK, it's now safe to #include other files. printer->Print( - "#include <google/protobuf/generated_message_reflection.h>\n" + "#include <google/protobuf/generated_message_util.h>\n" "#include <google/protobuf/repeated_field.h>\n" "#include <google/protobuf/extension_set.h>\n"); - if (file_->service_count() > 0) { + if (HasDescriptorMethods(file_)) { printer->Print( - "#include <google/protobuf/service.h>\n"); + "#include <google/protobuf/generated_message_reflection.h>\n"); + + if (file_->service_count() > 0) { + printer->Print( + "#include <google/protobuf/service.h>\n"); + } } for (int i = 0; i < file_->dependency_count(); i++) { @@ -193,19 +198,21 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { printer->Print(kThickSeparator); printer->Print("\n"); - // Generate service definitions. - for (int i = 0; i < file_->service_count(); i++) { - if (i > 0) { - printer->Print("\n"); - printer->Print(kThinSeparator); - printer->Print("\n"); + if (HasDescriptorMethods(file_)) { + // Generate service definitions. + for (int i = 0; i < file_->service_count(); i++) { + if (i > 0) { + printer->Print("\n"); + printer->Print(kThinSeparator); + printer->Print("\n"); + } + service_generators_[i]->GenerateDeclarations(printer); } - service_generators_[i]->GenerateDeclarations(printer); - } - printer->Print("\n"); - printer->Print(kThickSeparator); - printer->Print("\n"); + printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); + } // Declare extension identifiers. for (int i = 0; i < file_->extension_count(); i++) { @@ -228,6 +235,30 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { // Close up namespace. GenerateNamespaceClosers(printer); + // Emit GetEnumDescriptor specializations into google::protobuf namespace: + if (HasDescriptorMethods(file_)) { + // The SWIG conditional is to avoid a null-pointer dereference + // (bug 1984964) in swig-1.3.21 resulting from the following syntax: + // namespace X { void Y<Z::W>(); } + // which appears in GetEnumDescriptor() specializations. + printer->Print( + "\n" + "#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++) { + enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); + } + printer->Print( + "\n" + "} // namespace google\n} // namespace protobuf\n" + "#endif // SWIG\n" + "\n"); + } + printer->Print( "#endif // PROTOBUF_$filename_identifier$__INCLUDED\n", "filename_identifier", filename_identifier); @@ -237,40 +268,52 @@ void FileGenerator::GenerateSource(io::Printer* printer) { printer->Print( "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" "\n" + // The generated code calls accessors that might be deprecated. We don't + // want the compiler to warn in generated code. + "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n" "#include \"$basename$.pb.h\"\n" + "#include <google/protobuf/stubs/once.h>\n" - "#include <google/protobuf/descriptor.h>\n" "#include <google/protobuf/io/coded_stream.h>\n" - "#include <google/protobuf/reflection_ops.h>\n" - "#include <google/protobuf/wire_format_inl.h>\n", + "#include <google/protobuf/wire_format_lite_inl.h>\n", "basename", StripProto(file_->name())); + if (HasDescriptorMethods(file_)) { + printer->Print( + "#include <google/protobuf/descriptor.h>\n" + "#include <google/protobuf/reflection_ops.h>\n" + "#include <google/protobuf/wire_format.h>\n"); + } + GenerateNamespaceOpeners(printer); - printer->Print( - "\n" - "namespace {\n" - "\n"); - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateDescriptorDeclarations(printer); - } - for (int i = 0; i < file_->enum_type_count(); i++) { + if (HasDescriptorMethods(file_)) { printer->Print( - "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n", - "name", ClassName(file_->enum_type(i), false)); - } - for (int i = 0; i < file_->service_count(); i++) { + "\n" + "namespace {\n" + "\n"); + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateDescriptorDeclarations(printer); + } + for (int i = 0; i < file_->enum_type_count(); i++) { + printer->Print( + "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n", + "name", ClassName(file_->enum_type(i), false)); + } + for (int i = 0; i < file_->service_count(); i++) { + printer->Print( + "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n", + "name", file_->service(i)->name()); + } + printer->Print( - "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n", - "name", file_->service(i)->name()); + "\n" + "} // namespace\n" + "\n"); } - printer->Print( - "\n" - "} // namespace\n" - "\n"); - - // Define our externally-visible BuildDescriptors() function. + // Define our externally-visible BuildDescriptors() function. (For the lite + // library, all this does is initialize default instances.) GenerateBuildDescriptors(printer); // Generate enums. @@ -286,12 +329,14 @@ void FileGenerator::GenerateSource(io::Printer* printer) { message_generators_[i]->GenerateClassMethods(printer); } - // Generate services. - for (int i = 0; i < file_->service_count(); i++) { - if (i == 0) printer->Print("\n"); - printer->Print(kThickSeparator); - printer->Print("\n"); - service_generators_[i]->GenerateImplementation(printer); + if (HasDescriptorMethods(file_)) { + // Generate services. + for (int i = 0; i < file_->service_count(); i++) { + if (i == 0) printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); + service_generators_[i]->GenerateImplementation(printer); + } } // Define extensions. @@ -317,80 +362,84 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { // anyone calls descriptor() or GetReflection() on one of the types defined // in the file. - printer->Print( - "\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())); + // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors() + // and we only use AddDescriptors() to allocate default instances. + if (HasDescriptorMethods(file_)) { + printer->Print( + "\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())); - // 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()); - - // 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); - } - for (int i = 0; i < file_->service_count(); i++) { - service_generators_[i]->GenerateDescriptorInitializer(printer, i); - } + // 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()); + + // 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); + } + for (int i = 0; i < file_->service_count(); i++) { + service_generators_[i]->GenerateDescriptorInitializer(printer, i); + } - printer->Outdent(); - printer->Print( - "}\n" - "\n"); + 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. - printer->Print( - "namespace {\n" - "\n" - "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n" - "inline void protobuf_AssignDescriptorsOnce() {\n" - " ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n" - " &$assigndescriptorsname$);\n" - "}\n" - "\n", - "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name())); + // protobuf_AssignDescriptorsOnce(): The first time it is called, calls + // AssignDescriptors(). All later times, waits for the first call to + // complete and then returns. + printer->Print( + "namespace {\n" + "\n" + "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n" + "inline void protobuf_AssignDescriptorsOnce() {\n" + " ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n" + " &$assigndescriptorsname$);\n" + "}\n" + "\n", + "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name())); + + // protobuf_RegisterTypes(): Calls + // MessageFactory::InternalRegisterGeneratedType() for each message type. + printer->Print( + "void protobuf_RegisterTypes(const ::std::string&) {\n" + " protobuf_AssignDescriptorsOnce();\n"); + printer->Indent(); - // protobuf_RegisterTypes(): Calls - // MessageFactory::InternalRegisterGeneratedType() for each message type. - printer->Print( - "void protobuf_RegisterTypes() {\n" - " protobuf_AssignDescriptorsOnce();\n"); - printer->Indent(); + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateTypeRegistrations(printer); + } - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateTypeRegistrations(printer); + printer->Outdent(); + printer->Print( + "}\n" + "\n" + "} // namespace\n"); } - printer->Outdent(); - printer->Print( - "}\n" - "\n" - "} // namespace\n"); - // ----------------------------------------------------------------- // ShutdownFile(): Deletes descriptors, default instances, etc. on shutdown. @@ -442,32 +491,34 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { "name", GlobalAddDescriptorsName(dependency->name())); } - // Embed the descriptor. We simply serialize the entire FileDescriptorProto - // and embed it as a string literal, which is parsed and built into real - // descriptors at initialization time. - FileDescriptorProto file_proto; - file_->CopyTo(&file_proto); - string file_data; - file_proto.SerializeToString(&file_data); + if (HasDescriptorMethods(file_)) { + // Embed the descriptor. We simply serialize the entire FileDescriptorProto + // and embed it as a string literal, which is parsed and built into real + // descriptors at initialization time. + FileDescriptorProto file_proto; + file_->CopyTo(&file_proto); + string file_data; + file_proto.SerializeToString(&file_data); - printer->Print( - "::google::protobuf::DescriptorPool::InternalAddGeneratedFile("); + 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", CEscape(file_data.substr(i, kBytesPerLine))); - } - printer->Print( - ", $size$);\n", - "size", SimpleItoa(file_data.size())); + // 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", CEscape(file_data.substr(i, kBytesPerLine))); + } + printer->Print( + ", $size$);\n", + "size", SimpleItoa(file_data.size())); - // Call MessageFactory::InternalRegisterGeneratedFile(). - printer->Print( - "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n" - " \"$filename$\", &protobuf_RegisterTypes);\n", - "filename", file_->name()); + // Call MessageFactory::InternalRegisterGeneratedFile(). + printer->Print( + "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n" + " \"$filename$\", &protobuf_RegisterTypes);\n", + "filename", file_->name()); + } // Allocate and initialize default instances. This can't be done lazily // since default instances are returned by simple accessors and are used with |