aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler/cpp/cpp_file.cc
diff options
context:
space:
mode:
authorGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-07-29 01:13:20 +0000
committerGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-07-29 01:13:20 +0000
commit80b1d62bfcea65c59e2160da71dad84b1bd19cef (patch)
tree5423b830c53174fec83a7ea01ff0877e11c1ddb6 /src/google/protobuf/compiler/cpp/cpp_file.cc
parentd2fd0638c309113ccae3731a58e30419f522269a (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.cc315
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