aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler
diff options
context:
space:
mode:
authorGravatar Feng Xiao <xfxyjwf@gmail.com>2015-08-22 18:25:48 -0700
committerGravatar Feng Xiao <xfxyjwf@gmail.com>2015-08-22 18:25:48 -0700
commiteee38b0c018b3279f77d03dff796f440f40d3516 (patch)
tree7ff0978e30238d493fc7899b75abeb6d66939f07 /src/google/protobuf/compiler
parentc3bc155aceda36ecb01cde2367a3b427f2d7ce40 (diff)
Down-integrate from google3.
Diffstat (limited to 'src/google/protobuf/compiler')
-rw-r--r--src/google/protobuf/compiler/code_generator.cc1
-rw-r--r--src/google/protobuf/compiler/command_line_interface.cc5
-rw-r--r--src/google/protobuf/compiler/command_line_interface_unittest.cc33
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc3
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum.cc8
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum.h5
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum_field.cc1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_field.cc1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.cc254
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.h32
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_generator.cc13
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.cc24
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.h7
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_map_field.cc9
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_map_field.h1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.cc187
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.h9
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.cc616
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.h20
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.cc31
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.h1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc2
-rw-r--r--src/google/protobuf/compiler/importer_unittest.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_enum.cc4
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field_lite.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_enum_lite.cc226
-rw-r--r--src/google/protobuf/compiler/java/java_enum_lite.h99
-rw-r--r--src/google/protobuf/compiler/java/java_field.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_field.h1
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.h4
-rw-r--r--src/google/protobuf/compiler/java/java_map_field.cc24
-rw-r--r--src/google/protobuf/compiler/java/java_map_field_lite.cc24
-rw-r--r--src/google/protobuf/compiler/java/java_message.cc132
-rw-r--r--src/google/protobuf/compiler/java/java_message.h1
-rw-r--r--src/google/protobuf/compiler/java/java_message_field.cc13
-rw-r--r--src/google/protobuf/compiler/java/java_message_field_lite.cc14
-rw-r--r--src/google/protobuf/compiler/java/java_message_lite.cc92
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field_lite.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_service.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_string_field.cc22
-rw-r--r--src/google/protobuf/compiler/java/java_string_field_lite.cc189
-rw-r--r--src/google/protobuf/compiler/parser.cc1
-rw-r--r--src/google/protobuf/compiler/parser.h6
-rw-r--r--src/google/protobuf/compiler/plugin.cc1
-rw-r--r--src/google/protobuf/compiler/plugin.pb.cc36
-rw-r--r--src/google/protobuf/compiler/plugin.pb.h28
-rw-r--r--src/google/protobuf/compiler/python/python_generator.cc1
-rw-r--r--src/google/protobuf/compiler/python/python_generator.h1
-rw-r--r--src/google/protobuf/compiler/subprocess.cc1
51 files changed, 1679 insertions, 511 deletions
diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc
index 0039b00a..473eb4e6 100644
--- a/src/google/protobuf/compiler/code_generator.cc
+++ b/src/google/protobuf/compiler/code_generator.cc
@@ -34,6 +34,7 @@
#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index e8871861..26a4f0b0 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -70,6 +70,7 @@
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/stubs/map_util.h>
@@ -1657,7 +1658,11 @@ bool CommandLineInterface::WriteDescriptorSet(
&already_seen, file_set.mutable_file());
}
} else {
+ set<const FileDescriptor*> already_seen;
for (int i = 0; i < parsed_files.size(); i++) {
+ if (!already_seen.insert(parsed_files[i]).second) {
+ continue;
+ }
FileDescriptorProto* file_proto = file_set.add_file();
parsed_files[i]->CopyTo(file_proto);
if (source_info_in_descriptor_set_) {
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index e5b77c33..46ea5c4e 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -886,6 +886,39 @@ TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) {
EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
}
+TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithDuplicates) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+ CreateTempFile("baz.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Baz {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+ "--proto_path=$tmpdir bar.proto foo.proto bar.proto baz.proto");
+
+ ExpectNoErrors();
+
+ FileDescriptorSet descriptor_set;
+ ReadDescriptorSet("descriptor_set", &descriptor_set);
+ if (HasFatalFailure()) return;
+ EXPECT_EQ(3, descriptor_set.file_size());
+ EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
+ EXPECT_EQ("foo.proto", descriptor_set.file(1).name());
+ EXPECT_EQ("baz.proto", descriptor_set.file(2).name());
+ // Descriptor set should not have source code info.
+ EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
+}
+
TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithSourceInfo) {
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
index 13ed0b64..c3e9fe74 100644
--- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -133,8 +133,7 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) {
CppGenerator generator;
MockGeneratorContext context;
string error;
- string parameter;
- parameter = "dllexport_decl=LIBPROTOBUF_EXPORT";
+ string parameter = "dllexport_decl=LIBPROTOBUF_EXPORT";
ASSERT_TRUE(generator.Generate(proto_file, parameter,
&context, &error));
parameter = "dllexport_decl=LIBPROTOC_EXPORT";
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc
index 70d3a600..de4d7cc7 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -32,7 +32,6 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
-#include <set>
#include <map>
#include <google/protobuf/compiler/cpp/cpp_enum.h>
@@ -70,14 +69,11 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
EnumGenerator::~EnumGenerator() {}
-void EnumGenerator::GenerateForwardDeclaration(io::Printer* printer) {
+void EnumGenerator::FillForwardDeclaration(set<string>* enum_names) {
if (!options_.proto_h) {
return;
}
- map<string, string> vars;
- vars["classname"] = classname_;
- printer->Print(vars, "enum $classname$ : int;\n");
- printer->Print(vars, "bool $classname$_IsValid(int value);\n");
+ enum_names->insert(classname_);
}
void EnumGenerator::GenerateDefinition(io::Printer* printer) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/google/protobuf/compiler/cpp/cpp_enum.h
index 3e930856..f3aa72e4 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.h
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.h
@@ -35,6 +35,7 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
+#include <set>
#include <string>
#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/descriptor.h>
@@ -60,11 +61,11 @@ class EnumGenerator {
// Header stuff.
- // Generate header code to forward-declare the enum. This is for use when
+ // Fills the name to use when declaring the enum. This is for use when
// generating other .proto.h files. This code should be placed within the
// enum's package namespace, but NOT within any class, even for nested
// enums.
- void GenerateForwardDeclaration(io::Printer* printer);
+ void FillForwardDeclaration(set<string>* enum_names);
// Generate header code defining the enum. This code should be placed
// within the enum's package namespace, but NOT within any class, even for
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index 965327b1..824e2205 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -35,7 +35,6 @@
#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
-#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc
index 43df1d88..8d47d4e0 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_field.cc
@@ -47,6 +47,7 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 1f0a8205..5dae4cdd 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -33,6 +33,7 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/cpp_file.h>
+#include <map>
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
@@ -93,22 +94,36 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
FileGenerator::~FileGenerator() {}
-void FileGenerator::GenerateHeader(io::Printer* printer) {
- GenerateTopHeaderGuard(printer);
+void FileGenerator::GenerateProtoHeader(io::Printer* printer) {
+ if (!options_.proto_h) {
+ return;
+ }
+
+ string filename_identifier = FilenameIdentifier(file_->name());
+ GenerateTopHeaderGuard(printer, filename_identifier);
+
GenerateLibraryIncludes(printer);
- GenerateDependencyIncludes(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);
+ }
printer->Print(
"// @@protoc_insertion_point(includes)\n");
+ GenerateForwardDeclarations(printer);
// Open namespace.
GenerateNamespaceOpeners(printer);
GenerateGlobalStateFunctionDeclarations(printer);
- GenerateMessageForwardDeclarations(printer);
printer->Print("\n");
@@ -133,6 +148,11 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
GenerateInlineFunctionDefinitions(printer);
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(namespace_scope)\n"
+ "\n");
+
// Close up namespace.
GenerateNamespaceClosers(printer);
@@ -144,19 +164,89 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
"// @@protoc_insertion_point(global_scope)\n"
"\n");
- GenerateBottomHeaderGuard(printer);
+ GenerateBottomHeaderGuard(printer, filename_identifier);
+}
+
+void FileGenerator::GeneratePBHeader(io::Printer* printer) {
+ string filename_identifier =
+ FilenameIdentifier(file_->name() + (options_.proto_h ? ".pb.h" : ""));
+ GenerateTopHeaderGuard(printer, filename_identifier);
+
+ if (options_.proto_h) {
+ printer->Print("#include \"$basename$.proto.h\" // IWYU pragma: export\n",
+ "basename", StripProto(file_->name()));
+ } else {
+ GenerateLibraryIncludes(printer);
+ }
+ GenerateDependencyIncludes(printer);
+
+ 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");
+
+ // 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");
+
+ GenerateBottomHeaderGuard(printer, filename_identifier);
}
void FileGenerator::GenerateSource(io::Printer* printer) {
+ string header =
+ StripProto(file_->name()) + (options_.proto_h ? ".proto.h" : ".pb.h");
printer->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
"// source: $filename$\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 \"$header$\"\n"
"\n"
"#include <algorithm>\n" // for swap()
"\n"
@@ -165,7 +255,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
"#include <google/protobuf/io/coded_stream.h>\n"
"#include <google/protobuf/wire_format_lite_inl.h>\n",
"filename", file_->name(),
- "basename", StripProto(file_->name()));
+ "header", header);
// Unknown fields implementation in lite mode uses StringOutputStream
if (!UseUnknownFieldSet(file_) && file_->message_type_count() > 0) {
@@ -181,6 +271,18 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
"#include <google/protobuf/wire_format.h>\n");
}
+ if (options_.proto_h) {
+ // Use the smaller .proto.h files.
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ const FileDescriptor* dep = file_->dependency(i);
+ const char* extension = ".proto.h";
+ string dependency = StripProto(dep->name()) + extension;
+ printer->Print(
+ "#include \"$dependency$\"\n",
+ "dependency", dependency);
+ }
+ }
+
printer->Print(
"// @@protoc_insertion_point(includes)\n");
@@ -276,6 +378,59 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
"// @@protoc_insertion_point(global_scope)\n");
}
+class FileGenerator::ForwardDeclarations {
+ public:
+ ~ForwardDeclarations() {
+ for (map<string, ForwardDeclarations *>::iterator it = namespaces_.begin(),
+ end = namespaces_.end();
+ it != end; ++it) {
+ delete it->second;
+ }
+ namespaces_.clear();
+ }
+
+ ForwardDeclarations* AddOrGetNamespace(const string& ns_name) {
+ ForwardDeclarations*& ns = namespaces_[ns_name];
+ if (ns == NULL) {
+ ns = new ForwardDeclarations;
+ }
+ return ns;
+ }
+
+ set<string>& classes() { return classes_; }
+ set<string>& enums() { return enums_; }
+
+ void Print(io::Printer* printer) const {
+ for (set<string>::const_iterator it = enums_.begin(), end = enums_.end();
+ it != end; ++it) {
+ printer->Print("enum $enumname$ : int;\n"
+ "bool $enumname$_IsValid(int value);\n",
+ "enumname", it->c_str());
+ }
+ for (set<string>::const_iterator it = classes_.begin(),
+ end = classes_.end();
+ it != end; ++it) {
+ printer->Print("class $classname$;\n", "classname", it->c_str());
+ }
+ for (map<string, ForwardDeclarations *>::const_iterator
+ it = namespaces_.begin(),
+ end = namespaces_.end();
+ it != end; ++it) {
+ printer->Print("namespace $nsname$ {\n",
+ "nsname", it->first);
+ it->second->Print(printer);
+ printer->Print("} // namespace $nsname$\n",
+ "nsname", it->first);
+ }
+ }
+
+
+ private:
+ map<string, ForwardDeclarations*> namespaces_;
+ set<string> classes_;
+ set<string> enums_;
+};
+
void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// AddDescriptors() is a file-level procedure which adds the encoded
// FileDescriptorProto for this .proto file to the global DescriptorPool for
@@ -434,12 +589,17 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
string file_data;
file_proto.SerializeToString(&file_data);
+#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 (file_data.size() > 65535) {
+ if (breakdown_large_file && file_data.size() > 65535) {
printer->Print(
- "static const char descriptor[] = {\n");
+ "static const char descriptor[] = {\n");
printer->Indent();
// Only write 25 bytes per line.
@@ -447,26 +607,25 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
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]));
+ "$char$, ",
+ "char", SimpleItoa(file_data[i]));
}
printer->Print(
- "\n");
+ "\n");
}
printer->Outdent();
printer->Print(
- "};\n");
+ "};\n");
printer->Print(
- "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(descriptor, $size$);\n",
- "size", SimpleItoa(file_data.size()));
+ "::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) {
@@ -474,11 +633,10 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
"data",
EscapeTrigraphs(
CEscape(file_data.substr(i, kBytesPerLine))));
- }
- printer->Print(
- ", $size$);\n",
+ }
+ printer->Print(
+ ", $size$);\n",
"size", SimpleItoa(file_data.size()));
-
}
// Call MessageFactory::InternalRegisterGeneratedFile().
@@ -548,8 +706,40 @@ void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) {
}
}
-void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer) {
- string filename_identifier = FilenameIdentifier(file_->name());
+void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) {
+ ForwardDeclarations decls;
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ FileGenerator dependency(file_->dependency(i), options_);
+ dependency.FillForwardDeclarations(&decls);
+ }
+ FillForwardDeclarations(&decls);
+ decls.Print(printer);
+}
+
+void FileGenerator::FillForwardDeclarations(ForwardDeclarations* decls) {
+ for (int i = 0; i < file_->public_dependency_count(); i++) {
+ FileGenerator dependency(file_->public_dependency(i), options_);
+ dependency.FillForwardDeclarations(decls);
+ }
+ for (int i = 0; i < package_parts_.size(); i++) {
+ 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++) {
+ enum_generators_[i]->FillForwardDeclaration(&decls->enums());
+ }
+ // Generate forward declarations of classes.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->FillMessageForwardDeclarations(
+ &decls->classes());
+ }
+}
+
+void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer,
+ const string& filename_identifier) {
// Generate top of header.
printer->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
@@ -564,8 +754,8 @@ void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer) {
"filename_identifier", filename_identifier);
}
-void FileGenerator::GenerateBottomHeaderGuard(io::Printer* printer) {
- string filename_identifier = FilenameIdentifier(file_->name());
+void FileGenerator::GenerateBottomHeaderGuard(
+ io::Printer* printer, const string& filename_identifier) {
printer->Print(
"#endif // PROTOBUF_$filename_identifier$__INCLUDED\n",
"filename_identifier", filename_identifier);
@@ -696,9 +886,13 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations(
}
void FileGenerator::GenerateMessageForwardDeclarations(io::Printer* printer) {
- // Generate forward declarations of classes.
+ set<string> classes;
for (int i = 0; i < file_->message_type_count(); i++) {
- message_generators_[i]->GenerateMessageForwardDeclaration(printer);
+ message_generators_[i]->FillMessageForwardDeclarations(&classes);
+ }
+ for (set<string>::const_iterator it = classes.begin(), end = classes.end();
+ it != end; ++it) {
+ printer->Print("class $classname$;\n", "classname", it->c_str());
}
}
@@ -804,10 +998,6 @@ void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) {
// Methods of the dependent base class must always be inline in the header.
message_generators_[i]->GenerateDependentInlineMethods(printer);
}
-
- printer->Print(
- "\n"
- "// @@protoc_insertion_point(namespace_scope)\n");
}
void FileGenerator::GenerateProto2NamespaceEnumSpecializations(
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h
index e68f67bb..29cdaea5 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.h
+++ b/src/google/protobuf/compiler/cpp/cpp_file.h
@@ -69,10 +69,14 @@ class FileGenerator {
const Options& options);
~FileGenerator();
- void GenerateHeader(io::Printer* printer);
+ void GenerateProtoHeader(io::Printer* printer);
+ void GeneratePBHeader(io::Printer* printer);
void GenerateSource(io::Printer* printer);
private:
+ // Internal type used by GenerateForwardDeclarations (defined in file.cc).
+ class ForwardDeclarations;
+
// Generate the BuildDescriptors() procedure, which builds all descriptors
// for types defined in the file.
void GenerateBuildDescriptors(io::Printer* printer);
@@ -80,9 +84,19 @@ class FileGenerator {
void GenerateNamespaceOpeners(io::Printer* printer);
void GenerateNamespaceClosers(io::Printer* printer);
+ // For other imports, generates their forward-declarations.
+ void GenerateForwardDeclarations(io::Printer* printer);
+
+ // Internal helper used by GenerateForwardDeclarations: fills 'decls'
+ // with all necessary forward-declarations for this file and its
+ // transient depednencies.
+ void FillForwardDeclarations(ForwardDeclarations* decls);
+
// Generates top or bottom of a header file.
- void GenerateTopHeaderGuard(io::Printer* printer);
- void GenerateBottomHeaderGuard(io::Printer* printer);
+ void GenerateTopHeaderGuard(io::Printer* printer,
+ const string& filename_identifier);
+ void GenerateBottomHeaderGuard(io::Printer* printer,
+ const string& filename_identifier);
// Generates #include directives.
void GenerateLibraryIncludes(io::Printer* printer);
@@ -92,10 +106,20 @@ class FileGenerator {
void GenerateGlobalStateFunctionDeclarations(io::Printer* printer);
// Generates types for classes.
- void GenerateMessageForwardDeclarations(io::Printer* printer);
void GenerateMessageDefinitions(io::Printer* printer);
+ // Generates forward-declarations for just this file's classes. This is
+ // used for .pb.h headers, but not in proto_h mode.
+ void GenerateMessageForwardDeclarations(io::Printer* printer);
+
+ // Fills in types for forward declarations. This is used internally, and
+ // also by other FileGenerators to determine imports' declarations.
+ void FillMessageForwardDeclarations(ForwardDeclarations* decls);
+ void FillMessageDefinitions(ForwardDeclarations* decls);
+
// Generates enum definitions.
+ void GenerateEnumForwardDeclarations(io::Printer* printer);
+ void FillEnumForwardDeclarations(ForwardDeclarations* decls);
void GenerateEnumDefinitions(io::Printer* printer);
// Generates generic service definitions.
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc
index 99416372..781526b5 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -100,16 +100,23 @@ bool CppGenerator::Generate(const FileDescriptor* file,
string basename = StripProto(file->name());
- basename.append(".pb");
FileGenerator file_generator(file, file_options);
- // Generate header.
+ // Generate header(s).
+ if (file_options.proto_h) {
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(basename + ".proto.h"));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateProtoHeader(&printer);
+ }
+
+ basename.append(".pb");
{
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
generator_context->Open(basename + ".h"));
io::Printer printer(output.get(), '$');
- file_generator.GenerateHeader(&printer);
+ file_generator.GeneratePBHeader(&printer);
}
// Generate cc file.
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index 0f3688d0..678a995a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -39,6 +39,7 @@
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
@@ -68,7 +69,7 @@ const char* const kKeywordList[] = {
"constexpr", "const_cast", "continue", "decltype", "default", "delete", "do",
"double", "dynamic_cast", "else", "enum", "explicit", "extern", "false",
"float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable",
- "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or",
+ "namespace", "new", "noexcept", "not", "not_eq", "NULL", "operator", "or",
"or_eq", "private", "protected", "public", "register", "reinterpret_cast",
"return", "short", "signed", "sizeof", "static", "static_assert",
"static_cast", "struct", "switch", "template", "this", "thread_local",
@@ -174,6 +175,14 @@ string SuperClassName(const Descriptor* descriptor) {
"::google::protobuf::Message" : "::google::protobuf::MessageLite";
}
+string DependentBaseDownCast() {
+ return "reinterpret_cast<T*>(this)->";
+}
+
+string DependentBaseConstDownCast() {
+ return "reinterpret_cast<const T*>(this)->";
+}
+
string FieldName(const FieldDescriptor* field) {
string result = field->name();
LowerString(&result);
@@ -208,6 +217,19 @@ string FieldConstantName(const FieldDescriptor *field) {
}
bool IsFieldDependent(const FieldDescriptor* field) {
+ if (field->containing_oneof() != NULL &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ return true;
+ }
+ if (field->is_map()) {
+ const Descriptor* map_descriptor = field->message_type();
+ for (int i = 0; i < map_descriptor->field_count(); i++) {
+ if (IsFieldDependent(map_descriptor->field(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
return false;
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index 4bbf8303..29c1f90b 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -70,8 +70,15 @@ string ClassName(const EnumDescriptor* enum_descriptor, bool qualified);
// This is a class name, like "ProtoName_InternalBase".
string DependentBaseClassTemplateName(const Descriptor* descriptor);
+// Name of the base class: either the dependent base class (for use with
+// proto_h) or google::protobuf::Message.
string SuperClassName(const Descriptor* descriptor);
+// Returns a string that down-casts from the dependent base class to the
+// derived class.
+string DependentBaseDownCast();
+string DependentBaseConstDownCast();
+
// Get the (unqualified) name that should be used for this field in C++ code.
// The name is coerced to lower-case to emulate proto1 behavior. People
// should be using lowercase-with-underscores style for proto field names
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index 0ff0d27c..a14d8986 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -100,8 +100,9 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
MapFieldGenerator::
MapFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options)
- : descriptor_(descriptor) {
+ const Options& options)
+ : descriptor_(descriptor),
+ dependent_field_(options.proto_h && IsFieldDependent(descriptor)) {
SetMessageVariables(descriptor, &variables_, options);
}
@@ -152,7 +153,9 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
void MapFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
- printer->Print(variables_, "$name$_.Clear();\n");
+ map<string, string> variables(variables_);
+ variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
+ printer->Print(variables, "$this_message$$name$_.Clear();\n");
}
void MapFieldGenerator::
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h
index d27d4851..5e205623 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h
@@ -63,6 +63,7 @@ class MapFieldGenerator : public FieldGenerator {
private:
const FieldDescriptor* descriptor_;
+ const bool dependent_field_;
map<string, string> variables_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator);
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index b0e38755..aa10b0bb 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -39,7 +39,6 @@
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
-#include <set>
#include <utility>
#include <vector>
#include <google/protobuf/compiler/cpp/cpp_message.h>
@@ -415,31 +414,34 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor,
use_dependent_base_ = true;
}
}
+ if (options.proto_h && descriptor->oneof_decl_count() > 0) {
+ // Always make oneofs dependent.
+ use_dependent_base_ = true;
+ }
}
MessageGenerator::~MessageGenerator() {}
void MessageGenerator::
-GenerateMessageForwardDeclaration(io::Printer* printer) {
- printer->Print("class $classname$;\n",
- "classname", classname_);
+FillMessageForwardDeclarations(set<string>* class_names) {
+ class_names->insert(classname_);
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// map entry message doesn't need forward declaration. Since map entry
// message cannot be a top level class, we just need to avoid calling
// GenerateForwardDeclaration here.
if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
- nested_generators_[i]->GenerateMessageForwardDeclaration(printer);
+ nested_generators_[i]->FillMessageForwardDeclarations(class_names);
}
}
void MessageGenerator::
-GenerateEnumForwardDeclaration(io::Printer* printer) {
+FillEnumForwardDeclarations(set<string>* enum_names) {
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
- nested_generators_[i]->GenerateEnumForwardDeclaration(printer);
+ nested_generators_[i]->FillEnumForwardDeclarations(enum_names);
}
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
- enum_generators_[i]->GenerateForwardDeclaration(printer);
+ enum_generators_[i]->FillForwardDeclaration(enum_names);
}
}
@@ -484,13 +486,6 @@ GenerateDependentFieldAccessorDeclarations(io::Printer* printer) {
field_generators_.get(field).GenerateDependentAccessorDeclarations(printer);
printer->Print("\n");
}
- for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
- const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
- PrintFieldComment(printer, oneof);
- printer->Print(
- "void clear_$oneof_name$();\n",
- "oneof_name", oneof->name());
- }
}
void MessageGenerator::
@@ -505,7 +500,9 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) {
vars["constant_name"] = FieldConstantName(field);
bool dependent_field = use_dependent_base_ && IsFieldDependent(field);
- if (dependent_field) {
+ if (dependent_field &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !field->is_map()) {
// If this field is dependent, the dependent base class determines
// the message type from the derived class (which is a template
// parameter). This typedef is for that:
@@ -594,8 +591,8 @@ GenerateDependentFieldAccessorDefinitions(io::Printer* printer) {
vars["tmpl"] = "template<class T>\n";
vars["dependent_classname"] =
DependentBaseClassTemplateName(descriptor_) + "<T>";
- vars["this_message"] = "reinterpret_cast<T*>(this)->";
- vars["this_const_message"] = "reinterpret_cast<const T*>(this)->";
+ vars["this_message"] = DependentBaseDownCast();
+ vars["this_const_message"] = DependentBaseConstDownCast();
GenerateFieldClear(field, vars, printer);
}
@@ -721,13 +718,15 @@ GenerateFieldClear(const FieldDescriptor* field,
printer->Print(vars,
"if ($this_message$has_$name$()) {\n");
printer->Indent();
- field_generators_.get(field).GenerateClearingCode(printer);
+ field_generators_.get(field)
+ .GenerateClearingCode(printer);
printer->Print(vars,
"$this_message$clear_has_$oneof_name$();\n");
printer->Outdent();
printer->Print("}\n");
} else {
- field_generators_.get(field).GenerateClearingCode(printer);
+ field_generators_.get(field)
+ .GenerateClearingCode(printer);
if (HasFieldPresence(descriptor_->file())) {
if (!field->is_repeated()) {
printer->Print(vars,
@@ -752,6 +751,18 @@ GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) {
map<string, string> vars;
SetCommonFieldVariables(field, &vars, options_);
vars["inline"] = is_inline ? "inline " : "";
+ if (use_dependent_base_ && IsFieldDependent(field)) {
+ vars["tmpl"] = "template<class T>\n";
+ vars["dependent_classname"] =
+ DependentBaseClassTemplateName(descriptor_) + "<T>";
+ vars["this_message"] = "reinterpret_cast<T*>(this)->";
+ vars["this_const_message"] = "reinterpret_cast<const T*>(this)->";
+ } else {
+ vars["tmpl"] = "";
+ vars["dependent_classname"] = vars["classname"];
+ vars["this_message"] = "";
+ vars["this_const_message"] = "";
+ }
// Generate has_$name$() or $name$_size().
if (field->is_repeated()) {
@@ -775,10 +786,6 @@ GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) {
}
if (!use_dependent_base_ || !IsFieldDependent(field)) {
- vars["tmpl"] = "";
- vars["dependent_classname"] = vars["classname"];
- vars["this_message"] = "";
- vars["this_const_message"] = "";
GenerateFieldClear(field, vars, printer);
}
@@ -915,15 +922,32 @@ GenerateClassDefinition(io::Printer* printer) {
"}\n"
"\n");
} else {
- printer->Print(
- "inline const ::std::string& unknown_fields() const {\n"
- " return _unknown_fields_;\n"
- "}\n"
- "\n"
- "inline ::std::string* mutable_unknown_fields() {\n"
- " return &_unknown_fields_;\n"
- "}\n"
- "\n");
+ if (SupportsArenas(descriptor_)) {
+ printer->Print(
+ "inline const ::std::string& unknown_fields() const {\n"
+ " return _unknown_fields_.Get(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
+ "}\n"
+ "\n"
+ "inline ::std::string* mutable_unknown_fields() {\n"
+ " return _unknown_fields_.Mutable(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
+ " GetArenaNoVirtual());\n"
+ "}\n"
+ "\n");
+ } else {
+ printer->Print(
+ "inline const ::std::string& unknown_fields() const {\n"
+ " return _unknown_fields_.GetNoArena(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
+ "}\n"
+ "\n"
+ "inline ::std::string* mutable_unknown_fields() {\n"
+ " return _unknown_fields_.MutableNoArena(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
+ "}\n"
+ "\n");
+ }
}
}
@@ -1068,6 +1092,10 @@ GenerateClassDefinition(io::Printer* printer) {
}
}
uses_string_ = false;
+ if (PreserveUnknownFields(descriptor_) &&
+ !UseUnknownFieldSet(descriptor_->file())) {
+ uses_string_ = true;
+ }
for (int i = 0; i < descriptors.size(); i++) {
const FieldDescriptor* field = descriptors[i];
if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
@@ -1201,18 +1229,11 @@ GenerateClassDefinition(io::Printer* printer) {
// Generate oneof function declarations
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
- if (use_dependent_base_) {
- printer->Print(
- "inline bool has_$oneof_name$() const;\n"
- "inline void clear_has_$oneof_name$();\n\n",
- "oneof_name", descriptor_->oneof_decl(i)->name());
- } else {
- printer->Print(
- "inline bool has_$oneof_name$() const;\n"
- "void clear_$oneof_name$();\n"
- "inline void clear_has_$oneof_name$();\n\n",
- "oneof_name", descriptor_->oneof_decl(i)->name());
- }
+ printer->Print(
+ "inline bool has_$oneof_name$() const;\n"
+ "void clear_$oneof_name$();\n"
+ "inline void clear_has_$oneof_name$();\n\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name());
}
if (HasGeneratedMethods(descriptor_->file()) &&
@@ -1262,7 +1283,7 @@ GenerateClassDefinition(io::Printer* printer) {
"::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;\n");
} else {
printer->Print(
- "::std::string _unknown_fields_;\n"
+ "::google::protobuf::internal::ArenaStringPtr _unknown_fields_;\n"
"::google::protobuf::Arena* _arena_ptr_;\n"
"\n");
}
@@ -1919,6 +1940,13 @@ GenerateSharedConstructorCode(io::Printer* printer) {
uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "",
"_cached_size_ = 0;\n").c_str());
+ if (PreserveUnknownFields(descriptor_) &&
+ !UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print(
+ "_unknown_fields_.UnsafeSetDefault(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
+ }
+
for (int i = 0; i < descriptor_->field_count(); i++) {
if (!descriptor_->field(i)->containing_oneof()) {
field_generators_.get(descriptor_->field(i))
@@ -1955,6 +1983,22 @@ GenerateSharedDestructorCode(io::Printer* printer) {
"}\n"
"\n");
}
+
+ // Write the desctructor for _unknown_fields_ in lite runtime.
+ if (PreserveUnknownFields(descriptor_) &&
+ !UseUnknownFieldSet(descriptor_->file())) {
+ if (SupportsArenas(descriptor_)) {
+ printer->Print(
+ "_unknown_fields_.Destroy(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
+ " GetArenaNoVirtual());\n");
+ } else {
+ printer->Print(
+ "_unknown_fields_.DestroyNoArena(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
+ }
+ }
+
// Write the destructors for each field except oneof members.
for (int i = 0; i < descriptor_->field_count(); i++) {
if (!descriptor_->field(i)->containing_oneof()) {
@@ -2463,8 +2507,16 @@ GenerateClear(io::Printer* printer) {
" mutable_unknown_fields()->Clear();\n"
"}\n");
} else {
- printer->Print(
- "mutable_unknown_fields()->clear();\n");
+ if (SupportsArenas(descriptor_)) {
+ printer->Print(
+ "_unknown_fields_.ClearToEmpty(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
+ " GetArenaNoVirtual());\n");
+ } else {
+ printer->Print(
+ "_unknown_fields_.ClearToEmptyNoArena(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
+ }
}
}
@@ -2481,33 +2533,22 @@ GenerateOneofClear(io::Printer* printer) {
oneof_vars["oneofname"] = descriptor_->oneof_decl(i)->name();
string message_class;
- if (use_dependent_base_) {
- oneof_vars["tmpl"] = "template<class T>\n";
- oneof_vars["inline"] = "inline ";
- oneof_vars["dependent_classname"] =
- DependentBaseClassTemplateName(descriptor_) + "<T>";
- oneof_vars["this_message"] = "reinterpret_cast<T*>(this)->";
- message_class = "T::";
- } else {
- oneof_vars["tmpl"] = "";
- oneof_vars["inline"] = "";
- oneof_vars["dependent_classname"] = classname_;
- oneof_vars["this_message"] = "";
- }
-
printer->Print(oneof_vars,
- "$tmpl$"
- "$inline$"
- "void $dependent_classname$::clear_$oneofname$() {\n");
+ "void $classname$::clear_$oneofname$() {\n");
printer->Indent();
+ // In .proto.h mode, fields with a dependent type will generate
+ // clearing code that down casts from the dependent base class.
+ // However, clear_oneof() methods are always in the .cc file, and thus
+ // must remain in the derived base. So, to make the clearing code work,
+ // we add a typedef so that the down cast works (it will be a no-op).
printer->Print(oneof_vars,
- "switch($this_message$$oneofname$_case()) {\n");
+ "typedef $classname$ T;\n"
+ "switch($oneofname$_case()) {\n");
printer->Indent();
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
printer->Print(
- "case $message_class$k$field_name$: {\n",
- "message_class", message_class,
+ "case k$field_name$: {\n",
"field_name", UnderscoresToCamelCase(field->name(), true));
printer->Indent();
// We clear only allocated objects in oneofs
@@ -2524,20 +2565,16 @@ GenerateOneofClear(io::Printer* printer) {
"}\n");
}
printer->Print(
- "case $message_class$$cap_oneof_name$_NOT_SET: {\n"
+ "case $cap_oneof_name$_NOT_SET: {\n"
" break;\n"
"}\n",
- "message_class", message_class,
"cap_oneof_name",
ToUpper(descriptor_->oneof_decl(i)->name()));
printer->Outdent();
printer->Print(
"}\n"
- "$this_message$_oneof_case_[$oneof_index$] = "
- "$message_class$$cap_oneof_name$_NOT_SET;\n",
- "this_message", oneof_vars["this_message"],
+ "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n",
"oneof_index", SimpleItoa(i),
- "message_class", message_class,
"cap_oneof_name",
ToUpper(descriptor_->oneof_decl(i)->name()));
printer->Outdent();
@@ -2612,7 +2649,7 @@ GenerateSwap(io::Printer* printer) {
printer->Print(
"_internal_metadata_.Swap(&other->_internal_metadata_);\n");
} else {
- printer->Print("_unknown_fields_.swap(other->_unknown_fields_);\n");
+ printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
}
} else {
// Still swap internal_metadata as it may contain more than just
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h
index 23dad10c..8e19a3f0 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -39,8 +39,8 @@
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
+#include <set>
#include <string>
-#include <vector>
#include <google/protobuf/compiler/cpp/cpp_field.h>
#include <google/protobuf/compiler/cpp/cpp_options.h>
@@ -66,9 +66,10 @@ class MessageGenerator {
// Header stuff.
- // Generate foward declarations for this class and all its nested types.
- void GenerateMessageForwardDeclaration(io::Printer* printer);
- void GenerateEnumForwardDeclaration(io::Printer* printer);
+ // Return names for foward declarations of this class and all its nested
+ // types.
+ void FillMessageForwardDeclarations(set<string>* class_names);
+ void FillEnumForwardDeclarations(set<string>* enum_names);
// Generate definitions of all nested enums (must come before class
// definitions because those classes use the enums definitions).
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index ba318d10..b4545892 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -63,6 +63,14 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
SafeFunctionName(descriptor->containing_type(),
descriptor, "release_");
(*variables)["full_name"] = descriptor->full_name();
+ if (options.proto_h && IsFieldDependent(descriptor)) {
+ (*variables)["dependent_type"] = "T::" + DependentTypeName(descriptor);
+ (*variables)["dependent_typename"] =
+ "typename T::" + DependentTypeName(descriptor);
+ } else {
+ (*variables)["dependent_type"] = FieldMessageTypeName(descriptor);
+ (*variables)["dependent_typename"] = FieldMessageTypeName(descriptor);
+ }
}
} // namespace
@@ -85,7 +93,21 @@ GeneratePrivateMembers(io::Printer* printer) const {
}
void MessageFieldGenerator::
+GenerateGetterDeclaration(io::Printer* printer) const {
+ printer->Print(variables_,
+ "const $type$& $name$() const$deprecation$;\n");
+}
+
+void MessageFieldGenerator::
GenerateDependentAccessorDeclarations(io::Printer* printer) const {
+ if (!dependent_field_) {
+ return;
+ }
+ // Arena manipulation code is out-of-line in the derived message class.
+ printer->Print(variables_,
+ "$type$* mutable_$name$()$deprecation$;\n"
+ "$type$* $release_name$()$deprecation$;\n"
+ "void set_allocated_$name$($type$* $name$)$deprecation$;\n");
}
void MessageFieldGenerator::
@@ -103,11 +125,13 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
"$type$* _slow_$release_name$()$deprecation$;\n"
"public:\n");
}
- printer->Print(variables_,
- "const $type$& $name$() const$deprecation$;\n"
- "$type$* mutable_$name$()$deprecation$;\n"
- "$type$* $release_name$()$deprecation$;\n"
- "void set_allocated_$name$($type$* $name$)$deprecation$;\n");
+ GenerateGetterDeclaration(printer);
+ if (!dependent_field_) {
+ printer->Print(variables_,
+ "$type$* mutable_$name$()$deprecation$;\n"
+ "$type$* $release_name$()$deprecation$;\n"
+ "void set_allocated_$name$($type$* $name$)$deprecation$;\n");
+ }
if (SupportsArenas(descriptor_)) {
printer->Print(variables_,
"$type$* unsafe_arena_release_$name$()$deprecation$;\n"
@@ -123,12 +147,12 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
"void $classname$::_slow_mutable_$name$() {\n");
if (SupportsArenas(descriptor_->message_type())) {
printer->Print(variables_,
- " $name$_ = ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
- " GetArenaNoVirtual());\n");
+ " $name$_ = ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
+ " GetArenaNoVirtual());\n");
} else {
printer->Print(variables_,
- " $name$_ = ::google::protobuf::Arena::Create< $type$ >(\n"
- " GetArenaNoVirtual());\n");
+ " $name$_ = ::google::protobuf::Arena::Create< $type$ >(\n"
+ " GetArenaNoVirtual());\n");
}
printer->Print(variables_,
"}\n"
@@ -151,7 +175,7 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
if (SupportsArenas(descriptor_->message_type())) {
// NOTE: the same logic is mirrored in weak_message_field.cc. Any
// arena-related semantics changes should be made in both places.
- printer->Print(variables_,
+ printer->Print(variables_,
"void $classname$::_slow_set_allocated_$name$(\n"
" ::google::protobuf::Arena* message_arena, $type$** $name$) {\n"
" if (message_arena != NULL && \n"
@@ -189,15 +213,139 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
void MessageFieldGenerator::
GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
+ if (!dependent_field_) {
+ return;
+ }
+
+ map<string, string> variables(variables_);
+ // For the CRTP base class, all mutation methods are dependent, and so
+ // they must be in the header.
+ variables["dependent_classname"] =
+ DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>";
+ variables["this_message"] = DependentBaseDownCast();
+ if (!variables["set_hasbit"].empty()) {
+ variables["set_hasbit"] =
+ variables["this_message"] + variables["set_hasbit"];
+ }
+ if (!variables["clear_hasbit"].empty()) {
+ variables["clear_hasbit"] =
+ variables["this_message"] + variables["clear_hasbit"];
+ }
+
+ if (SupportsArenas(descriptor_)) {
+ printer->Print(variables,
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::mutable_$name$() {\n"
+ " $set_hasbit$\n"
+ " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " if ($name$_ == NULL) {\n"
+ " $this_message$_slow_mutable_$name$();\n"
+ " }\n"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::$release_name$() {\n"
+ " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " $clear_hasbit$\n"
+ " if ($this_message$GetArenaNoVirtual() != NULL) {\n"
+ " return $this_message$_slow_$release_name$();\n"
+ " } else {\n"
+ " $dependent_typename$* temp = $name$_;\n"
+ " $name$_ = NULL;\n"
+ " return temp;\n"
+ " }\n"
+ "}\n"
+ "template <class T>\n"
+ "inline void $dependent_classname$::"
+ "set_allocated_$name$($type$* $name$) {\n"
+ " ::google::protobuf::Arena* message_arena = $this_message$GetArenaNoVirtual();\n"
+ " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " if (message_arena == NULL) {\n"
+ " delete $name$_;\n"
+ " }\n"
+ " if ($name$ != NULL) {\n");
+ if (SupportsArenas(descriptor_->message_type())) {
+ // If we're on an arena and the incoming message is not, simply Own() it
+ // rather than copy to the arena -- either way we need a heap dealloc,
+ // so we might as well defer it. Otherwise, if incoming message is on a
+ // different ownership domain (specific arena, or the heap) than we are,
+ // copy to our arena (or heap, as the case may be).
+ printer->Print(variables,
+ " $this_message$_slow_set_allocated_$name$(message_arena, "
+ "&$name$);\n");
+ } else {
+ printer->Print(variables,
+ " if (message_arena != NULL) {\n"
+ " message_arena->Own($name$);\n"
+ " }\n");
+ }
+ printer->Print(variables,
+ " }\n"
+ " $name$_ = $name$;\n"
+ " if ($name$) {\n"
+ " $set_hasbit$\n"
+ " } else {\n"
+ " $clear_hasbit$\n"
+ " }\n"
+ // TODO(dlj): move insertion points to message class.
+ " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ "}\n");
+ } else {
+ printer->Print(variables,
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::mutable_$name$() {\n"
+ " $set_hasbit$\n"
+ " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " if ($name$_ == NULL) {\n"
+ " $name$_ = new $dependent_typename$;\n"
+ " }\n"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::$release_name$() {\n"
+ " $clear_hasbit$\n"
+ " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " $dependent_typename$* temp = $name$_;\n"
+ " $name$_ = NULL;\n"
+ " return temp;\n"
+ "}\n"
+ "template <class T>\n"
+ "inline void $dependent_classname$::"
+ "set_allocated_$name$($type$* $name$) {\n"
+ " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " delete $name$_;\n");
+
+ if (SupportsArenas(descriptor_->message_type())) {
+ printer->Print(variables,
+ " if ($name$ != NULL && static_cast< $dependent_typename$* >($name$)"
+ "->GetArena() != NULL) {\n"
+ " $dependent_typename$* new_$name$ = new $dependent_typename$;\n"
+ " new_$name$->CopyFrom(*$name$);\n"
+ " $name$ = new_$name$;\n"
+ " }\n");
+ }
+
+ printer->Print(variables,
+ " $name$_ = $name$;\n"
+ " if ($name$) {\n"
+ " $set_hasbit$\n"
+ " } else {\n"
+ " $clear_hasbit$\n"
+ " }\n"
+ " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ "}\n");
+ }
}
void MessageFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer,
bool is_inline) const {
map<string, string> variables(variables_);
- variables["inline"] = is_inline ? "inline" : "";
+ variables["inline"] = is_inline ? "inline " : "";
printer->Print(variables,
- "$inline$ const $type$& $classname$::$name$() const {\n"
+ "$inline$const $type$& $classname$::$name$() const {\n"
" // @@protoc_insertion_point(field_get:$full_name$)\n");
PrintHandlingOptionalStaticInitializers(
@@ -206,19 +354,25 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n",
// Without.
" return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n");
+ printer->Print(variables, "}\n");
+
+ if (dependent_field_) {
+ return;
+ }
if (SupportsArenas(descriptor_)) {
printer->Print(variables,
- "}\n"
- "$inline$ $type$* $classname$::mutable_$name$() {\n"
+ "$inline$"
+ "$type$* $classname$::mutable_$name$() {\n"
" $set_hasbit$\n"
" if ($name$_ == NULL) {\n"
- " _slow_mutable_$name$();"
+ " _slow_mutable_$name$();\n"
" }\n"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return $name$_;\n"
"}\n"
- "$inline$ $type$* $classname$::$release_name$() {\n"
+ "$inline$"
+ "$type$* $classname$::$release_name$() {\n"
" $clear_hasbit$\n"
" if (GetArenaNoVirtual() != NULL) {\n"
" return _slow_$release_name$();\n"
@@ -228,7 +382,8 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" return temp;\n"
" }\n"
"}\n"
- "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n"
+ "$inline$ "
+ "void $classname$::set_allocated_$name$($type$* $name$) {\n"
" ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();\n"
" if (message_arena == NULL) {\n"
" delete $name$_;\n"
@@ -260,8 +415,8 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
"}\n");
} else {
printer->Print(variables,
- "}\n"
- "$inline$ $type$* $classname$::mutable_$name$() {\n"
+ "$inline$"
+ "$type$* $classname$::mutable_$name$() {\n"
" $set_hasbit$\n"
" if ($name$_ == NULL) {\n"
" $name$_ = new $type$;\n"
@@ -269,13 +424,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return $name$_;\n"
"}\n"
- "$inline$ $type$* $classname$::$release_name$() {\n"
+ "$inline$"
+ "$type$* $classname$::$release_name$() {\n"
" $clear_hasbit$\n"
" $type$* temp = $name$_;\n"
" $name$_ = NULL;\n"
" return temp;\n"
"}\n"
- "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n"
+ "$inline$"
+ "void $classname$::set_allocated_$name$($type$* $name$) {\n"
" delete $name$_;\n");
if (SupportsArenas(descriptor_->message_type())) {
@@ -301,15 +458,19 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
void MessageFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
+ map<string, string> variables(variables_);
+ variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
if (!HasFieldPresence(descriptor_->file())) {
// If we don't have has-bits, message presence is indicated only by ptr !=
// NULL. Thus on clear, we need to delete the object.
- printer->Print(variables_,
- "if (GetArenaNoVirtual() == NULL && $name$_ != NULL) delete $name$_;\n"
- "$name$_ = NULL;\n");
+ printer->Print(variables,
+ "if ($this_message$GetArenaNoVirtual() == NULL && "
+ "$this_message$$name$_ != NULL) delete $this_message$$name$_;\n"
+ "$this_message$$name$_ = NULL;\n");
} else {
- printer->Print(variables_,
- "if ($name$_ != NULL) $name$_->$type$::Clear();\n");
+ printer->Print(variables,
+ "if ($this_message$$name$_ != NULL) $this_message$$name$_->"
+ "$dependent_type$::Clear();\n");
}
}
@@ -370,79 +531,149 @@ GenerateByteSize(io::Printer* printer) const {
MessageOneofFieldGenerator::
MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
- : MessageFieldGenerator(descriptor, options) {
+ : MessageFieldGenerator(descriptor, options),
+ dependent_base_(options.proto_h) {
SetCommonOneofFieldVariables(descriptor, &variables_);
}
MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
+
+void MessageOneofFieldGenerator::
+GenerateDependentAccessorDeclarations(io::Printer* printer) const {
+ // Oneof field getters must be dependent as they call default_instance().
+ // Otherwise, the logic is the same as MessageFields.
+ if (!dependent_field_) {
+ return;
+ }
+ printer->Print(variables_,
+ "const $type$& $name$() const$deprecation$;\n");
+ MessageFieldGenerator::GenerateDependentAccessorDeclarations(printer);
+}
+
+void MessageOneofFieldGenerator::
+GenerateGetterDeclaration(io::Printer* printer) const {
+ // Oneof field getters must be dependent as they call default_instance().
+ // Unlike MessageField, this means there is no (non-dependent) getter to
+ // generate.
+ if (dependent_field_) {
+ return;
+ }
+ printer->Print(variables_,
+ "const $type$& $name$() const$deprecation$;\n");
+}
+
void MessageOneofFieldGenerator::
GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
+ // For the CRTP base class, all mutation methods are dependent, and so
+ // they must be in the header.
+ if (!dependent_base_) {
+ return;
+ }
+ map<string, string> variables(variables_);
+ variables["inline"] = "inline ";
+ variables["dependent_classname"] =
+ DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>";
+ variables["this_message"] = "reinterpret_cast<T*>(this)->";
+ // Const message access is needed for the dependent getter.
+ variables["this_const_message"] = "reinterpret_cast<const T*>(this)->";
+ variables["tmpl"] = "template <class T>\n";
+ variables["field_member"] = variables["this_message"] +
+ variables["oneof_prefix"] + variables["name"] +
+ "_";
+ InternalGenerateInlineAccessorDefinitions(variables, printer);
}
void MessageOneofFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer,
bool is_inline) const {
+ if (dependent_base_) {
+ return;
+ }
map<string, string> variables(variables_);
- variables["inline"] = is_inline ? "inline" : "";
+ variables["inline"] = is_inline ? "inline " : "";
+ variables["dependent_classname"] = variables["classname"];
+ variables["this_message"] = "";
+ variables["this_const_message"] = "";
+ variables["tmpl"] = "";
+ variables["field_member"] =
+ variables["oneof_prefix"] + variables["name"] + "_";
+ variables["dependent_type"] = variables["type"];
+ InternalGenerateInlineAccessorDefinitions(variables, printer);
+}
+
+void MessageOneofFieldGenerator::
+GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
+ map<string, string> variables(variables_);
+ variables["field_member"] =
+ variables["oneof_prefix"] + variables["name"] + "_";
+
+ //printer->Print(variables,
+}
+
+void MessageOneofFieldGenerator::
+InternalGenerateInlineAccessorDefinitions(const map<string, string>& variables,
+ io::Printer* printer) const {
+ printer->Print(variables,
+ "$tmpl$"
+ "$inline$ "
+ "const $type$& $dependent_classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return $this_const_message$has_$name$()\n"
+ " ? *$this_const_message$$oneof_prefix$$name$_\n"
+ " : $dependent_type$::default_instance();\n"
+ "}\n");
+
if (SupportsArenas(descriptor_)) {
printer->Print(variables,
- "$inline$ const $type$& $classname$::$name$() const {\n"
- " // @@protoc_insertion_point(field_get:$full_name$)\n"
- " return has_$name$() ? *$oneof_prefix$$name$_\n"
- " : $type$::default_instance();\n"
- "}\n"
- "$inline$ $type$* $classname$::mutable_$name$() {\n"
- " if (!has_$name$()) {\n"
- " clear_$oneof_name$();\n"
- " set_has_$name$();\n");
+ "$tmpl$"
+ "$inline$"
+ "$type$* $dependent_classname$::mutable_$name$() {\n"
+ " if (!$this_message$has_$name$()) {\n"
+ " $this_message$clear_$oneof_name$();\n"
+ " $this_message$set_has_$name$();\n");
if (SupportsArenas(descriptor_->message_type())) {
printer->Print(variables,
- " $oneof_prefix$$name$_ = \n"
- " ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
- " GetArenaNoVirtual());\n");
+ " $field_member$ = \n"
+ " ::google::protobuf::Arena::CreateMessage< $dependent_typename$ >(\n"
+ " $this_message$GetArenaNoVirtual());\n");
} else {
printer->Print(variables,
- " $oneof_prefix$$name$_ = \n"
- " ::google::protobuf::Arena::Create< $type$ >(\n"
- " GetArenaNoVirtual());\n");
+ " $this_message$$oneof_prefix$$name$_ = \n"
+ " ::google::protobuf::Arena::Create< $dependent_typename$ >(\n"
+ " $this_message$GetArenaNoVirtual());\n");
}
printer->Print(variables,
" }\n"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
- " return $oneof_prefix$$name$_;\n"
+ " return $field_member$;\n"
"}\n"
- "$inline$ $type$* $classname$::$release_name$() {\n"
- " if (has_$name$()) {\n"
- " clear_has_$oneof_name$();\n"
- " if (GetArenaNoVirtual() != NULL) {\n"
+ "$tmpl$"
+ "$inline$"
+ "$type$* $dependent_classname$::$release_name$() {\n"
+ " if ($this_message$has_$name$()) {\n"
+ " $this_message$clear_has_$oneof_name$();\n"
+ " if ($this_message$GetArenaNoVirtual() != NULL) {\n"
// N.B.: safe to use the underlying field pointer here because we are sure
// that it is non-NULL (because has_$name$() returned true).
- " $type$* temp = new $type$;\n"
- " temp->MergeFrom(*$oneof_prefix$$name$_);\n"
- " $oneof_prefix$$name$_ = NULL;\n"
+ " $dependent_typename$* temp = new $dependent_typename$;\n"
+ " temp->MergeFrom(*$field_member$);\n"
+ " $field_member$ = NULL;\n"
" return temp;\n"
" } else {\n"
- " $type$* temp = $oneof_prefix$$name$_;\n"
- " $oneof_prefix$$name$_ = NULL;\n"
+ " $dependent_typename$* temp = $field_member$;\n"
+ " $field_member$ = NULL;\n"
" return temp;\n"
" }\n"
" } else {\n"
" return NULL;\n"
" }\n"
"}\n"
- "$inline$ $type$* $classname$::unsafe_arena_release_$name$() {\n"
- " if (has_$name$()) {\n"
- " clear_has_$oneof_name$();\n"
- " $type$* temp = $oneof_prefix$$name$_;\n"
- " $oneof_prefix$$name$_ = NULL;\n"
- " return temp;\n"
- " } else {\n"
- " return NULL;\n"
- " }\n"
- "}\n"
- "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n"
- " clear_$oneof_name$();\n"
+ "$tmpl$"
+ "$inline$"
+ "void $dependent_classname$::"
+ "set_allocated_$name$($type$* $name$) {\n"
+ " $this_message$clear_$oneof_name$();\n"
" if ($name$) {\n");
if (SupportsArenas(descriptor_->message_type())) {
@@ -450,32 +681,42 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
// If incoming message is on the heap and we are on an arena, just Own()
// it (see above). If it's on a different arena than we are or one of us
// is on the heap, we make a copy to our arena/heap.
- " if (GetArenaNoVirtual() != NULL &&\n"
+ " if ($this_message$GetArenaNoVirtual() != NULL &&\n"
" ::google::protobuf::Arena::GetArena($name$) == NULL) {\n"
- " GetArenaNoVirtual()->Own($name$);\n"
- " } else if (GetArenaNoVirtual() !=\n"
+ " $this_message$GetArenaNoVirtual()->Own($name$);\n"
+ " } else if ($this_message$GetArenaNoVirtual() !=\n"
" ::google::protobuf::Arena::GetArena($name$)) {\n"
- " $type$* new_$name$ = \n"
- " ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
- " GetArenaNoVirtual());\n"
+ " $dependent_typename$* new_$name$ = \n"
+ " ::google::protobuf::Arena::CreateMessage< $dependent_typename$ >(\n"
+ " $this_message$GetArenaNoVirtual());\n"
" new_$name$->CopyFrom(*$name$);\n"
" $name$ = new_$name$;\n"
" }\n");
} else {
printer->Print(variables,
- " if (GetArenaNoVirtual() != NULL) {\n"
- " GetArenaNoVirtual()->Own($name$);\n"
+ " if ($this_message$GetArenaNoVirtual() != NULL) {\n"
+ " $this_message$GetArenaNoVirtual()->Own($name$);\n"
" }\n");
}
printer->Print(variables,
- " set_has_$name$();\n"
- " $oneof_prefix$$name$_ = $name$;\n"
+ " $this_message$set_has_$name$();\n"
+ " $field_member$ = $name$;\n"
" }\n"
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
"}\n"
- "$inline$ void $classname$::unsafe_arena_set_allocated_$name$("
- "$type$* $name$) {\n"
+ "$inline$ $type$* $classname$::unsafe_arena_release_$name$() {\n"
+ " if (has_$name$()) {\n"
+ " clear_has_$oneof_name$();\n"
+ " $type$* temp = $oneof_prefix$$name$_;\n"
+ " $oneof_prefix$$name$_ = NULL;\n"
+ " return temp;\n"
+ " } else {\n"
+ " return NULL;\n"
+ " }\n"
+ "}\n"
+ "$inline$ void $classname$::unsafe_arena_set_allocated_$name$"
+ "($type$* $name$) {\n"
// We rely on the oneof clear method to free the earlier contents of this
// oneof. We can directly use the pointer we're given to set the new
// value.
@@ -489,44 +730,47 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
"}\n");
} else {
printer->Print(variables,
- "$inline$ const $type$& $classname$::$name$() const {\n"
- " // @@protoc_insertion_point(field_get:$full_name$)\n"
- " return has_$name$() ? *$oneof_prefix$$name$_\n"
- " : $type$::default_instance();\n"
- "}\n"
- "$inline$ $type$* $classname$::mutable_$name$() {\n"
- " if (!has_$name$()) {\n"
- " clear_$oneof_name$();\n"
- " set_has_$name$();\n"
- " $oneof_prefix$$name$_ = new $type$;\n"
+ "$tmpl$"
+ "$inline$"
+ "$type$* $dependent_classname$::mutable_$name$() {\n"
+ " if (!$this_message$has_$name$()) {\n"
+ " $this_message$clear_$oneof_name$();\n"
+ " $this_message$set_has_$name$();\n"
+ " $field_member$ = new $dependent_typename$;\n"
" }\n"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
- " return $oneof_prefix$$name$_;\n"
+ " return $field_member$;\n"
"}\n"
- "$inline$ $type$* $classname$::$release_name$() {\n"
- " if (has_$name$()) {\n"
- " clear_has_$oneof_name$();\n"
- " $type$* temp = $oneof_prefix$$name$_;\n"
- " $oneof_prefix$$name$_ = NULL;\n"
+ "$tmpl$"
+ "$inline$"
+ "$type$* $dependent_classname$::$release_name$() {\n"
+ " if ($this_message$has_$name$()) {\n"
+ " $this_message$clear_has_$oneof_name$();\n"
+ " $dependent_typename$* temp = $field_member$;\n"
+ " $field_member$ = NULL;\n"
" return temp;\n"
" } else {\n"
" return NULL;\n"
" }\n"
"}\n"
- "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n"
- " clear_$oneof_name$();\n"
+ "$tmpl$"
+ "$inline$"
+ "void $dependent_classname$::"
+ "set_allocated_$name$($type$* $name$) {\n"
+ " $this_message$clear_$oneof_name$();\n"
" if ($name$) {\n");
if (SupportsArenas(descriptor_->message_type())) {
printer->Print(variables,
- " if ($name$->GetArena() != NULL) {\n"
- " $type$* new_$name$ = new $type$;\n"
+ " if (static_cast< $dependent_typename$*>($name$)->"
+ "GetArena() != NULL) {\n"
+ " $dependent_typename$* new_$name$ = new $dependent_typename$;\n"
" new_$name$->CopyFrom(*$name$);\n"
" $name$ = new_$name$;\n"
" }\n");
}
printer->Print(variables,
- " set_has_$name$();\n"
- " $oneof_prefix$$name$_ = $name$;\n"
+ " $this_message$set_has_$name$();\n"
+ " $field_member$ = $name$;\n"
" }\n"
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
"}\n");
@@ -535,14 +779,16 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
void MessageOneofFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
+ map<string, string> variables(variables_);
+ variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- "if (GetArenaNoVirtual() == NULL) {\n"
- " delete $oneof_prefix$$name$_;\n"
+ printer->Print(variables,
+ "if ($this_message$GetArenaNoVirtual() == NULL) {\n"
+ " delete $this_message$$oneof_prefix$$name$_;\n"
"}\n");
} else {
- printer->Print(variables_,
- "delete $oneof_prefix$$name$_;\n");
+ printer->Print(variables,
+ "delete $this_message$$oneof_prefix$$name$_;\n");
}
}
@@ -562,7 +808,9 @@ GenerateConstructorCode(io::Printer* printer) const {
RepeatedMessageFieldGenerator::
RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
- : descriptor_(descriptor) {
+ : descriptor_(descriptor),
+ dependent_field_(options.proto_h && IsFieldDependent(descriptor)),
+ dependent_getter_(dependent_field_ && options.safe_boundary_check) {
SetMessageVariables(descriptor, &variables_, options);
}
@@ -575,60 +823,160 @@ GeneratePrivateMembers(io::Printer* printer) const {
}
void RepeatedMessageFieldGenerator::
-GenerateDependentAccessorDeclarations(io::Printer* printer) const {
-}
-
-void RepeatedMessageFieldGenerator::
-GenerateAccessorDeclarations(io::Printer* printer) const {
+InternalGenerateTypeDependentAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "const $type$& $name$(int index) const$deprecation$;\n"
"$type$* mutable_$name$(int index)$deprecation$;\n"
"$type$* add_$name$()$deprecation$;\n");
+ if (dependent_getter_) {
+ printer->Print(variables_,
+ "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ " $name$() const$deprecation$;\n");
+ }
printer->Print(variables_,
- "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
- " $name$() const$deprecation$;\n"
"::google::protobuf::RepeatedPtrField< $type$ >*\n"
" mutable_$name$()$deprecation$;\n");
}
void RepeatedMessageFieldGenerator::
-GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
+GenerateDependentAccessorDeclarations(io::Printer* printer) const {
+ if (dependent_getter_) {
+ printer->Print(variables_,
+ "const $type$& $name$(int index) const$deprecation$;\n");
+ }
+ if (dependent_field_) {
+ InternalGenerateTypeDependentAccessorDeclarations(printer);
+ }
}
void RepeatedMessageFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer,
- bool is_inline) const {
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ if (!dependent_getter_) {
+ printer->Print(variables_,
+ "const $type$& $name$(int index) const$deprecation$;\n");
+ }
+ if (!dependent_field_) {
+ InternalGenerateTypeDependentAccessorDeclarations(printer);
+ }
+ if (!dependent_getter_) {
+ printer->Print(variables_,
+ "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ " $name$() const$deprecation$;\n");
+ }
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
+ if (!dependent_field_) {
+ return;
+ }
map<string, string> variables(variables_);
- variables["inline"] = is_inline ? "inline" : "";
+ // For the CRTP base class, all mutation methods are dependent, and so
+ // they must be in the header.
+ variables["dependent_classname"] =
+ DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>";
+ variables["this_message"] = DependentBaseDownCast();
+ variables["this_const_message"] = DependentBaseConstDownCast();
+
+ if (dependent_getter_) {
+ printer->Print(variables,
+ "template <class T>\n"
+ "inline const $type$& $dependent_classname$::$name$(int index) const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return $this_const_message$$name$_.$cppget$(index);\n"
+ "}\n");
+ }
+
+ // Generate per-element accessors:
printer->Print(variables,
- "$inline$ const $type$& $classname$::$name$(int index) const {\n"
- " // @@protoc_insertion_point(field_get:$full_name$)\n"
- " return $name$_.$cppget$(index);\n"
- "}\n"
- "$inline$ $type$* $classname$::mutable_$name$(int index) {\n"
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::mutable_$name$(int index) {\n"
+ // TODO(dlj): move insertion points
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
- " return $name$_.Mutable(index);\n"
+ " return $this_message$$name$_.Mutable(index);\n"
"}\n"
- "$inline$ $type$* $classname$::add_$name$() {\n"
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::add_$name$() {\n"
" // @@protoc_insertion_point(field_add:$full_name$)\n"
- " return $name$_.Add();\n"
+ " return $this_message$$name$_.Add();\n"
"}\n");
+
+
+ if (dependent_getter_) {
+ printer->Print(variables,
+ "template <class T>\n"
+ "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ "$dependent_classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
+ " return $this_const_message$$name$_;\n"
+ "}\n");
+ }
+
+ // Generate mutable access to the entire list:
printer->Print(variables,
- "$inline$ const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
- "$classname$::$name$() const {\n"
- " // @@protoc_insertion_point(field_list:$full_name$)\n"
- " return $name$_;\n"
- "}\n"
- "$inline$ ::google::protobuf::RepeatedPtrField< $type$ >*\n"
- "$classname$::mutable_$name$() {\n"
+ "template <class T>\n"
+ "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
+ "$dependent_classname$::mutable_$name$() {\n"
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
- " return &$name$_;\n"
+ " return &$this_message$$name$_;\n"
"}\n");
}
void RepeatedMessageFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer,
+ bool is_inline) const {
+ map<string, string> variables(variables_);
+ variables["inline"] = is_inline ? "inline " : "";
+
+ if (!dependent_getter_) {
+ printer->Print(variables,
+ "$inline$"
+ "const $type$& $classname$::$name$(int index) const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return $name$_.$cppget$(index);\n"
+ "}\n");
+ }
+
+ if (!dependent_field_) {
+ printer->Print(variables,
+ "$inline$"
+ "$type$* $classname$::mutable_$name$(int index) {\n"
+ // TODO(dlj): move insertion points
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return $name$_.Mutable(index);\n"
+ "}\n"
+ "$inline$"
+ "$type$* $classname$::add_$name$() {\n"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
+ " return $name$_.Add();\n"
+ "}\n");
+ }
+
+
+ if (!dependent_field_) {
+ printer->Print(variables,
+ "$inline$"
+ "::google::protobuf::RepeatedPtrField< $type$ >*\n"
+ "$classname$::mutable_$name$() {\n"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+ " return &$name$_;\n"
+ "}\n");
+ }
+ if (!dependent_getter_) {
+ printer->Print(variables,
+ "$inline$"
+ "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ "$classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n");
+ }
+}
+
+void RepeatedMessageFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
- printer->Print(variables_, "$name$_.Clear();\n");
+ map<string, string> variables(variables_);
+ variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
+ printer->Print(variables, "$this_message$$name$_.Clear();\n");
}
void RepeatedMessageFieldGenerator::
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h
index 9ddf9643..35efd0fa 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -68,6 +68,11 @@ class MessageFieldGenerator : public FieldGenerator {
void GenerateByteSize(io::Printer* printer) const;
protected:
+ void GenerateArenaManipulationCode(const map<string, string>& variables,
+ io::Printer* printer) const;
+
+ virtual void GenerateGetterDeclaration(io::Printer* printer) const;
+
const FieldDescriptor* descriptor_;
const bool dependent_field_;
map<string, string> variables_;
@@ -83,15 +88,23 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator {
~MessageOneofFieldGenerator();
// implements FieldGenerator ---------------------------------------
+ void GenerateDependentAccessorDeclarations(io::Printer* printer) const;
void GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const;
void GenerateInlineAccessorDefinitions(io::Printer* printer,
bool is_inline) const;
- void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {}
+ void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
void GenerateClearingCode(io::Printer* printer) const;
void GenerateSwappingCode(io::Printer* printer) const;
void GenerateConstructorCode(io::Printer* printer) const;
+ protected:
+ void GenerateGetterDeclaration(io::Printer* printer) const;
+
private:
+ void InternalGenerateInlineAccessorDefinitions(
+ const map<string, string>& variables, io::Printer* printer) const;
+
+ const bool dependent_base_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator);
};
@@ -118,7 +131,12 @@ class RepeatedMessageFieldGenerator : public FieldGenerator {
void GenerateByteSize(io::Printer* printer) const;
private:
+ void InternalGenerateTypeDependentAccessorDeclarations(
+ io::Printer* printer) const;
+
const FieldDescriptor* descriptor_;
+ const bool dependent_field_;
+ const bool dependent_getter_;
map<string, string> variables_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index 1a3896a1..d1af6dda 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -421,7 +421,8 @@ GenerateByteSize(io::Printer* printer) const {
StringOneofFieldGenerator::
StringOneofFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
- : StringFieldGenerator(descriptor, options) {
+ : StringFieldGenerator(descriptor, options),
+ dependent_field_(options.proto_h) {
SetCommonOneofFieldVariables(descriptor, &variables_);
}
@@ -604,13 +605,29 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
void StringOneofFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
+ map<string, string> variables(variables_);
+ if (dependent_field_) {
+ variables["this_message"] = DependentBaseDownCast();
+ // This clearing code may be in the dependent base class. If the default
+ // value is an empty string, then the $default_variable$ is a global
+ // singleton. If the default is not empty, we need to down-cast to get the
+ // default value's global singleton instance. See SetStringVariables() for
+ // possible values of default_variable.
+ if (!descriptor_->default_value_string().empty()) {
+ variables["default_variable"] =
+ DependentBaseDownCast() + variables["default_variable"];
+ }
+ } else {
+ variables["this_message"] = "";
+ }
if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- "$oneof_prefix$$name$_.Destroy($default_variable$,\n"
- " GetArenaNoVirtual());\n");
+ printer->Print(variables,
+ "$this_message$$oneof_prefix$$name$_.Destroy($default_variable$,\n"
+ " $this_message$GetArenaNoVirtual());\n");
} else {
- printer->Print(variables_,
- "$oneof_prefix$$name$_.DestroyNoArena($default_variable$);\n");
+ printer->Print(variables,
+ "$this_message$$oneof_prefix$$name$_."
+ "DestroyNoArena($default_variable$);\n");
}
}
@@ -664,7 +681,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
RepeatedStringFieldGenerator::
RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
- : descriptor_(descriptor) {
+ : descriptor_(descriptor) {
SetStringVariables(descriptor, &variables_, options);
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h
index d1f19cd9..616e2067 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -93,6 +93,7 @@ class StringOneofFieldGenerator : public StringFieldGenerator {
void GenerateMergeFromCodedStream(io::Printer* printer) const;
private:
+ const bool dependent_field_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOneofFieldGenerator);
};
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index bd1c0fde..e5ef6ecd 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -67,7 +67,9 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/stubs/callback.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/testing/googletest.h>
diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc
index 43eb0ed5..33c9328f 100644
--- a/src/google/protobuf/compiler/importer_unittest.cc
+++ b/src/google/protobuf/compiler/importer_unittest.cc
@@ -44,6 +44,7 @@
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/stubs/strutil.h>
diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc
index 0353b607..8a09f3a8 100644
--- a/src/google/protobuf/compiler/java/java_enum.cc
+++ b/src/google/protobuf/compiler/java/java_enum.cc
@@ -181,8 +181,8 @@ void EnumGenerator::Generate(io::Printer* printer) {
" internalGetValueMap() {\n"
" return internalValueMap;\n"
"}\n"
- "private static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
- " internalValueMap =\n"
+ "private static final com.google.protobuf.Internal.EnumLiteMap<\n"
+ " $classname$> internalValueMap =\n"
" new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
" public $classname$ findValueByNumber(int number) {\n"
" return $classname$.valueOf(number);\n"
diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc
index 39318a19..558da968 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -35,6 +35,7 @@
#include <map>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
index 697a07a7..2c3608c2 100644
--- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
@@ -35,6 +35,7 @@
#include <map>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc
index e69de29b..62186386 100644
--- a/src/google/protobuf/compiler/java/java_enum_lite.cc
+++ b/src/google/protobuf/compiler/java/java_enum_lite.cc
@@ -0,0 +1,226 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_enum_lite.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+bool EnumHasCustomOptions(const EnumDescriptor* descriptor) {
+ if (descriptor->options().unknown_fields().field_count() > 0) return true;
+ for (int i = 0; i < descriptor->value_count(); ++i) {
+ const EnumValueDescriptor* value = descriptor->value(i);
+ if (value->options().unknown_fields().field_count() > 0) return true;
+ }
+ return false;
+}
+} // namespace
+
+EnumLiteGenerator::EnumLiteGenerator(const EnumDescriptor* descriptor,
+ bool immutable_api,
+ Context* context)
+ : descriptor_(descriptor), immutable_api_(immutable_api),
+ name_resolver_(context->GetNameResolver()) {
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ const EnumValueDescriptor* value = descriptor_->value(i);
+ const EnumValueDescriptor* canonical_value =
+ descriptor_->FindValueByNumber(value->number());
+
+ if (value == canonical_value) {
+ canonical_values_.push_back(value);
+ } else {
+ Alias alias;
+ alias.value = value;
+ alias.canonical_value = canonical_value;
+ aliases_.push_back(alias);
+ }
+ }
+}
+
+EnumLiteGenerator::~EnumLiteGenerator() {}
+
+void EnumLiteGenerator::Generate(io::Printer* printer) {
+ WriteEnumDocComment(printer, descriptor_);
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public enum $classname$\n"
+ " implements com.google.protobuf.ProtocolMessageEnum {\n",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "public enum $classname$\n"
+ " implements com.google.protobuf.Internal.EnumLite {\n",
+ "classname", descriptor_->name());
+ }
+ printer->Indent();
+
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ map<string, string> vars;
+ vars["name"] = canonical_values_[i]->name();
+ vars["index"] = SimpleItoa(canonical_values_[i]->index());
+ vars["number"] = SimpleItoa(canonical_values_[i]->number());
+ WriteEnumValueDocComment(printer, canonical_values_[i]);
+ if (canonical_values_[i]->options().deprecated()) {
+ printer->Print("@java.lang.Deprecated\n");
+ }
+ printer->Print(vars,
+ "$name$($index$, $number$),\n");
+ }
+
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print("UNRECOGNIZED(-1, -1),\n");
+ }
+
+ printer->Print(
+ ";\n"
+ "\n");
+
+ // -----------------------------------------------------------------
+
+ for (int i = 0; i < aliases_.size(); i++) {
+ map<string, string> vars;
+ vars["classname"] = descriptor_->name();
+ vars["name"] = aliases_[i].value->name();
+ vars["canonical_name"] = aliases_[i].canonical_value->name();
+ WriteEnumValueDocComment(printer, aliases_[i].value);
+ printer->Print(vars,
+ "public static final $classname$ $name$ = $canonical_name$;\n");
+ }
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ map<string, string> vars;
+ vars["name"] = descriptor_->value(i)->name();
+ vars["number"] = SimpleItoa(descriptor_->value(i)->number());
+ WriteEnumValueDocComment(printer, descriptor_->value(i));
+ printer->Print(vars,
+ "public static final int $name$_VALUE = $number$;\n");
+ }
+ printer->Print("\n");
+
+ // -----------------------------------------------------------------
+
+ printer->Print(
+ "\n"
+ "public final int getNumber() {\n");
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ " if (index == -1) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Can't get the number of an unknown enum value.\");\n"
+ " }\n");
+ }
+ printer->Print(
+ " return value;\n"
+ "}\n"
+ "\n"
+ "public static $classname$ valueOf(int value) {\n"
+ " switch (value) {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ printer->Print(
+ "case $number$: return $name$;\n",
+ "name", canonical_values_[i]->name(),
+ "number", SimpleItoa(canonical_values_[i]->number()));
+ }
+
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " default: return null;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "public static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
+ " internalGetValueMap() {\n"
+ " return internalValueMap;\n"
+ "}\n"
+ "private static final com.google.protobuf.Internal.EnumLiteMap<\n"
+ " $classname$> internalValueMap =\n"
+ " new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
+ " public $classname$ findValueByNumber(int number) {\n"
+ " return $classname$.valueOf(number);\n"
+ " }\n"
+ " };\n"
+ "\n",
+ "classname", descriptor_->name());
+
+ printer->Print(
+ "private final int value;\n\n"
+ "private $classname$(int index, int value) {\n",
+ "classname", descriptor_->name());
+ printer->Print(
+ " this.value = value;\n"
+ "}\n");
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(enum_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+bool EnumLiteGenerator::CanUseEnumValues() {
+ if (canonical_values_.size() != descriptor_->value_count()) {
+ return false;
+ }
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ if (descriptor_->value(i)->name() != canonical_values_[i]->name()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/java/java_enum_lite.h b/src/google/protobuf/compiler/java/java_enum_lite.h
index e69de29b..ee2f5f7a 100644
--- a/src/google/protobuf/compiler/java/java_enum_lite.h
+++ b/src/google/protobuf/compiler/java/java_enum_lite.h
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__
+
+#include <string>
+#include <vector>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+ namespace compiler {
+ namespace java {
+ class Context; // context.h
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class EnumLiteGenerator {
+ public:
+ explicit EnumLiteGenerator(const EnumDescriptor* descriptor,
+ bool immutable_api,
+ Context* context);
+ ~EnumLiteGenerator();
+
+ void Generate(io::Printer* printer);
+
+ private:
+ const EnumDescriptor* descriptor_;
+
+ // The proto language allows multiple enum constants to have the same numeric
+ // value. Java, however, does not allow multiple enum constants to be
+ // considered equivalent. We treat the first defined constant for any
+ // given numeric value as "canonical" and the rest as aliases of that
+ // canonical value.
+ vector<const EnumValueDescriptor*> canonical_values_;
+
+ struct Alias {
+ const EnumValueDescriptor* value;
+ const EnumValueDescriptor* canonical_value;
+ };
+ vector<Alias> aliases_;
+
+ bool immutable_api_;
+
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+
+ bool CanUseEnumValues();
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumLiteGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__
diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc
index 3f0fa11f..c5434767 100644
--- a/src/google/protobuf/compiler/java/java_field.cc
+++ b/src/google/protobuf/compiler/java/java_field.cc
@@ -39,6 +39,7 @@
#include <google/protobuf/stubs/shared_ptr.h>
#endif
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_enum_field.h>
diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h
index 00f3c601..0e24da24 100644
--- a/src/google/protobuf/compiler/java/java_field.h
+++ b/src/google/protobuf/compiler/java/java_field.h
@@ -44,6 +44,7 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/stubs/logging.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h
index 96d2545f..99ba6a18 100644
--- a/src/google/protobuf/compiler/java/java_helpers.h
+++ b/src/google/protobuf/compiler/java/java_helpers.h
@@ -332,6 +332,10 @@ inline bool PreserveUnknownFields(const Descriptor* descriptor) {
return descriptor->file()->syntax() != FileDescriptor::SYNTAX_PROTO3;
}
+inline bool IsAnyMessage(const Descriptor* descriptor) {
+ return descriptor->full_name() == "google.protobuf.Any";
+}
+
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_map_field.cc b/src/google/protobuf/compiler/java/java_map_field.cc
index 44b86cd7..3e035c89 100644
--- a/src/google/protobuf/compiler/java/java_map_field.cc
+++ b/src/google/protobuf/compiler/java/java_map_field.cc
@@ -314,6 +314,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
" internalGetMutable$capitalized_name$().getMutableMap(),\n"
" $name$ValueConverter);\n"
"}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder putAll$capitalized_name$(\n"
+ " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
+ " getMutable$capitalized_name$().putAll(values);\n"
+ " return this;\n"
+ "}\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
WriteFieldDocComment(printer, descriptor_);
printer->Print(
@@ -331,6 +339,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
"getMutable$capitalized_name$Value() {\n"
" return internalGetMutable$capitalized_name$().getMutableMap();\n"
"}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder putAll$capitalized_name$Value(\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
+ " getMutable$capitalized_name$Value().putAll(values);\n"
+ " return this;\n"
+ "}\n");
}
} else {
WriteFieldDocComment(printer, descriptor_);
@@ -346,6 +362,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
"getMutable$capitalized_name$() {\n"
" return internalGetMutable$capitalized_name$().getMutableMap();\n"
"}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder putAll$capitalized_name$(\n"
+ " java.util.Map<$type_parameters$> values) {\n"
+ " getMutable$capitalized_name$().putAll(values);\n"
+ " return this;\n"
+ "}\n");
}
}
diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.cc b/src/google/protobuf/compiler/java/java_map_field_lite.cc
index cd1698f0..4fe656d3 100644
--- a/src/google/protobuf/compiler/java/java_map_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc
@@ -303,6 +303,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
" copyOnWrite();\n"
" return instance.getMutable$capitalized_name$();\n"
"}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder putAll$capitalized_name$(\n"
+ " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
+ " getMutable$capitalized_name$().putAll(values);\n"
+ " return this;\n"
+ "}\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
WriteFieldDocComment(printer, descriptor_);
printer->Print(
@@ -321,6 +329,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
" copyOnWrite();\n"
" return instance.getMutable$capitalized_name$Value();\n"
"}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder putAll$capitalized_name$Value(\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
+ " getMutable$capitalized_name$Value().putAll(values);\n"
+ " return this;\n"
+ "}\n");
}
} else {
WriteFieldDocComment(printer, descriptor_);
@@ -337,6 +353,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
" copyOnWrite();\n"
" return instance.getMutable$capitalized_name$();\n"
"}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "public Builder putAll$capitalized_name$(\n"
+ " java.util.Map<$type_parameters$> values) {\n"
+ " getMutable$capitalized_name$().putAll(values);\n"
+ " return this;\n"
+ "}\n");
}
}
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index 09b0fd94..80d6e9ad 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -255,6 +255,18 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
field_generators_.get(descriptor_->field(i))
.GenerateInterfaceMembers(printer);
}
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "\n"
+ "public $classname$.$oneof_capitalized_name$Case "
+ "get$oneof_capitalized_name$Case();\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->capitalized_name,
+ "classname",
+ context_->GetNameResolver()->GetImmutableClassName(
+ descriptor_));
+ }
printer->Outdent();
printer->Print("}\n");
@@ -292,8 +304,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
" com.google.protobuf.GeneratedMessage implements\n"
" $extra_interfaces$\n"
" $classname$OrBuilder {\n");
-
- builder_type = "com.google.protobuf.GeneratedMessage.Builder";
+ builder_type = "com.google.protobuf.GeneratedMessage.Builder<?>";
}
printer->Indent();
// Using builder_type, instead of Builder, prevents the Builder class from
@@ -435,6 +446,10 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
"\n");
}
+ if (IsAnyMessage(descriptor_)) {
+ GenerateAnyMethods(printer);
+ }
+
// Fields
for (int i = 0; i < descriptor_->field_count(); i++) {
printer->Print("public static final int $constant_name$ = $number$;\n",
@@ -578,9 +593,8 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
printer->Print(
"}\n"
"\n"
- "private int memoizedSerializedSize = -1;\n"
"public int getSerializedSize() {\n"
- " int size = memoizedSerializedSize;\n"
+ " int size = memoizedSize;\n"
" if (size != -1) return size;\n"
"\n"
" size = 0;\n");
@@ -612,7 +626,7 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
printer->Outdent();
printer->Print(
- " memoizedSerializedSize = size;\n"
+ " memoizedSize = size;\n"
" return size;\n"
"}\n"
"\n");
@@ -948,22 +962,58 @@ GenerateEqualsAndHashCode(io::Printer* printer) {
printer->Print("boolean result = true;\n");
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
- const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
- bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
- if (check_has_bits) {
+ if (field->containing_oneof() == NULL) {
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
+ if (check_has_bits) {
+ printer->Print(
+ "result = result && (has$name$() == other.has$name$());\n"
+ "if (has$name$()) {\n",
+ "name", info->capitalized_name);
+ printer->Indent();
+ }
+ field_generators_.get(field).GenerateEqualsCode(printer);
+ if (check_has_bits) {
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+ }
+ }
+
+ // Compare oneofs.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "result = result && get$oneof_capitalized_name$Case().equals(\n"
+ " other.get$oneof_capitalized_name$Case());\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->capitalized_name);
+ printer->Print(
+ "if (!result) return false;\n"
+ "switch ($oneof_name$Case_) {\n",
+ "oneof_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->name);
+ printer->Indent();
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
printer->Print(
- "result = result && (has$name$() == other.has$name$());\n"
- "if (has$name$()) {\n",
- "name", info->capitalized_name);
+ "case $field_number$:\n",
+ "field_number",
+ SimpleItoa(field->number()));
printer->Indent();
- }
- field_generators_.get(field).GenerateEqualsCode(printer);
- if (check_has_bits) {
+ field_generators_.get(field).GenerateEqualsCode(printer);
+ printer->Print("break;\n");
printer->Outdent();
- printer->Print(
- "}\n");
}
+ printer->Print(
+ "case 0:\n"
+ "default:\n");
+ printer->Outdent();
+ printer->Print("}\n");
}
+
if (PreserveUnknownFields(descriptor_)) {
// Always consider unknown fields for equality. This will sometimes return
// false for non-canonical ordering when running in LITE_RUNTIME but it's
@@ -1198,7 +1248,7 @@ GenerateParsingConstructor(io::Printer* printer) {
// ===================================================================
void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
printer->Print(
- "public static final com.google.protobuf.Parser<$classname$> PARSER =\n"
+ "private static final com.google.protobuf.Parser<$classname$> PARSER =\n"
" new com.google.protobuf.AbstractParser<$classname$>() {\n",
"classname", descriptor_->name());
printer->Indent();
@@ -1250,6 +1300,10 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
"\n");
printer->Print(
+ "public static com.google.protobuf.Parser<$classname$> parser() {\n"
+ " return PARSER;\n"
+ "}\n"
+ "\n"
"@java.lang.Override\n"
"public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
" return PARSER;\n"
@@ -1269,6 +1323,50 @@ void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) {
}
+void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
+ printer->Print(
+ "private static String getTypeUrl(\n"
+ " com.google.protobuf.Descriptors.Descriptor descriptor) {\n"
+ " return \"type.googleapis.com/\" + descriptor.getFullName();\n"
+ "}\n"
+ "\n"
+ "public static <T extends com.google.protobuf.Message> Any pack(\n"
+ " T message) {\n"
+ " return Any.newBuilder()\n"
+ " .setTypeUrl(getTypeUrl(message.getDescriptorForType()))\n"
+ " .setValue(message.toByteString())\n"
+ " .build();\n"
+ "}\n"
+ "\n"
+ "public <T extends com.google.protobuf.Message> boolean is(\n"
+ " java.lang.Class<T> clazz) {\n"
+ " T defaultInstance =\n"
+ " com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
+ " return getTypeUrl().equals(\n"
+ " getTypeUrl(defaultInstance.getDescriptorForType()));\n"
+ "}\n"
+ "\n"
+ "private volatile com.google.protobuf.Message cachedUnpackValue;\n"
+ "\n"
+ "public <T extends com.google.protobuf.Message> T unpack(\n"
+ " java.lang.Class<T> clazz)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " if (!is(clazz)) {\n"
+ " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
+ " \"Type of the Any messsage does not match the given class.\");\n"
+ " }\n"
+ " if (cachedUnpackValue != null) {\n"
+ " return (T) cachedUnpackValue;\n"
+ " }\n"
+ " T defaultInstance =\n"
+ " com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
+ " T result = (T) defaultInstance.getParserForType()\n"
+ " .parseFrom(getValue());\n"
+ " cachedUnpackValue = result;\n"
+ " return result;\n"
+ "}\n");
+}
+
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h
index c3c37765..be5bfb07 100644
--- a/src/google/protobuf/compiler/java/java_message.h
+++ b/src/google/protobuf/compiler/java/java_message.h
@@ -122,6 +122,7 @@ class ImmutableMessageGenerator : public MessageGenerator {
void GenerateEqualsAndHashCode(io::Printer* printer);
void GenerateParser(io::Printer* printer);
void GenerateParsingConstructor(io::Printer* printer);
+ void GenerateAnyMethods(io::Printer* printer);
Context* context_;
ClassNameResolver* name_resolver_;
diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc
index b180b4a7..b5f8e626 100644
--- a/src/google/protobuf/compiler/java/java_message_field.cc
+++ b/src/google/protobuf/compiler/java/java_message_field.cc
@@ -452,11 +452,11 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$name$_ = input.readGroup($number$, $type$.PARSER,\n"
+ "$name$_ = input.readGroup($number$, $type$.parser(),\n"
" extensionRegistry);\n");
} else {
printer->Print(variables_,
- "$name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
+ "$name$_ = input.readMessage($type$.parser(), extensionRegistry);\n");
}
printer->Print(variables_,
@@ -736,11 +736,12 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$oneof_name$_ = input.readGroup($number$, $type$.PARSER,\n"
+ "$oneof_name$_ = input.readGroup($number$, $type$.parser(),\n"
" extensionRegistry);\n");
} else {
printer->Print(variables_,
- "$oneof_name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
+ "$oneof_name$_ =\n"
+ " input.readMessage($type$.parser(), extensionRegistry);\n");
}
printer->Print(variables_,
@@ -1232,11 +1233,11 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$name$_.add(input.readGroup($number$, $type$.PARSER,\n"
+ "$name$_.add(input.readGroup($number$, $type$.parser(),\n"
" extensionRegistry));\n");
} else {
printer->Print(variables_,
- "$name$_.add(input.readMessage($type$.PARSER, extensionRegistry));\n");
+ "$name$_.add(input.readMessage($type$.parser(), extensionRegistry));\n");
}
}
diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.cc b/src/google/protobuf/compiler/java/java_message_field_lite.cc
index 8332202c..356520ec 100644
--- a/src/google/protobuf/compiler/java/java_message_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc
@@ -310,11 +310,11 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$name$_ = input.readGroup($number$, $type$.PARSER,\n"
+ "$name$_ = input.readGroup($number$, $type$.parser(),\n"
" extensionRegistry);\n");
} else {
printer->Print(variables_,
- "$name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
+ "$name$_ = input.readMessage($type$.parser(), extensionRegistry);\n");
}
printer->Print(variables_,
@@ -521,11 +521,12 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$oneof_name$_ = input.readGroup($number$, $type$.PARSER,\n"
+ "$oneof_name$_ = input.readGroup($number$, $type$.parser(),\n"
" extensionRegistry);\n");
} else {
printer->Print(variables_,
- "$oneof_name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
+ "$oneof_name$_ =\n"
+ " input.readMessage($type$.parser(), extensionRegistry);\n");
}
printer->Print(variables_,
@@ -885,11 +886,12 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$name$_.add(input.readGroup($number$, $type$.PARSER,\n"
+ "$name$_.add(input.readGroup($number$, $type$.parser(),\n"
" extensionRegistry));\n");
} else {
printer->Print(variables_,
- "$name$_.add(input.readMessage($type$.PARSER, extensionRegistry));\n");
+ "$name$_.add(\n"
+ " input.readMessage($type$.parser(), extensionRegistry));\n");
}
}
diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc
index 3accee92..8b6c75b8 100644
--- a/src/google/protobuf/compiler/java/java_message_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_lite.cc
@@ -45,7 +45,7 @@
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
-#include <google/protobuf/compiler/java/java_enum.h>
+#include <google/protobuf/compiler/java/java_enum_lite.h>
#include <google/protobuf/compiler/java/java_extension.h>
#include <google/protobuf/compiler/java/java_generator_factory.h>
#include <google/protobuf/compiler/java/java_helpers.h>
@@ -143,6 +143,17 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) {
field_generators_.get(descriptor_->field(i))
.GenerateInterfaceMembers(printer);
}
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "\n"
+ "public $classname$.$oneof_capitalized_name$Case "
+ "get$oneof_capitalized_name$Case();\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->capitalized_name,
+ "classname",
+ context_->GetNameResolver()->GetImmutableClassName(descriptor_));
+ }
printer->Outdent();
printer->Print("}\n");
@@ -190,7 +201,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
// Nested types
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
- EnumGenerator(descriptor_->enum_type(i), true, context_)
+ EnumLiteGenerator(descriptor_->enum_type(i), true, context_)
.Generate(printer);
}
@@ -321,12 +332,12 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
printer->Print(
"protected final Object dynamicMethod(\n"
" com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n"
- " Object... args) {\n"
+ " Object arg0, Object arg1) {\n"
" switch (method) {\n"
" case PARSE_PARTIAL_FROM: {\n"
" return new $classname$("
- " (com.google.protobuf.CodedInputStream) args[0],\n"
- " (com.google.protobuf.ExtensionRegistryLite) args[1]);\n"
+ " (com.google.protobuf.CodedInputStream) arg0,\n"
+ " (com.google.protobuf.ExtensionRegistryLite) arg1);\n"
" }\n"
" case NEW_INSTANCE: {\n"
" return new $classname$(\n"
@@ -370,7 +381,25 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
printer->Outdent();
printer->Print(
- "}\n");
+ "}\n"
+ "case GET_DEFAULT_INSTANCE: {\n"
+ " return DEFAULT_INSTANCE;\n"
+ "}\n"
+ "case GET_PARSER: {\n"
+ // Generally one would use the lazy initialization holder pattern for
+ // manipulating static fields but that has exceptional cost on Android as
+ // it will generate an extra class for every message. Instead, use the
+ // double-check locking pattern which works just as well.
+ " if (PARSER == null) {"
+ " synchronized ($classname$.class) {\n"
+ " if (PARSER == null) {\n"
+ " PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " return PARSER;\n"
+ "}\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
printer->Outdent();
printer->Outdent();
@@ -413,18 +442,6 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
GenerateParser(printer);
- // LITE_RUNTIME uses this to implement the *ForType methods at the
- // GeneratedMessageLite level.
- printer->Print(
- "static {\n"
- " com.google.protobuf.GeneratedMessageLite.onLoad(\n"
- " $classname$.class, new com.google.protobuf.GeneratedMessageLite\n"
- " .PrototypeHolder<$classname$, Builder>(\n"
- " DEFAULT_INSTANCE, PARSER));"
- "}\n"
- "\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
-
// Extensions must be declared after the DEFAULT_INSTANCE is initialized
// because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
// the outer class's FileDescriptor.
@@ -554,54 +571,54 @@ GenerateParseFromMethods(io::Printer* printer) {
"public static $classname$ parseFrom(\n"
" com.google.protobuf.ByteString data)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return PARSER.parseFrom(data);\n"
+ " return parser().parseFrom(data);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.ByteString data,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return PARSER.parseFrom(data, extensionRegistry);\n"
+ " return parser().parseFrom(data, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(byte[] data)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return PARSER.parseFrom(data);\n"
+ " return parser().parseFrom(data);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" byte[] data,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return PARSER.parseFrom(data, extensionRegistry);\n"
+ " return parser().parseFrom(data, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseFrom(input);\n"
+ " return parser().parseFrom(input);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" java.io.InputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseFrom(input, extensionRegistry);\n"
+ " return parser().parseFrom(input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseDelimitedFrom(input);\n"
+ " return parser().parseDelimitedFrom(input);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(\n"
" java.io.InputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseDelimitedFrom(input, extensionRegistry);\n"
+ " return parser().parseDelimitedFrom(input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseFrom(input);\n"
+ " return parser().parseFrom(input);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseFrom(input, extensionRegistry);\n"
+ " return parser().parseFrom(input, extensionRegistry);\n"
"}\n"
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
@@ -652,7 +669,7 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized(
"if (isInitialized == 1) return DEFAULT_INSTANCE;\n"
"if (isInitialized == 0) return null;\n"
"\n"
- "boolean shouldMemoize = ((Boolean) args[0]).booleanValue();\n");
+ "boolean shouldMemoize = ((Boolean) arg0).booleanValue();\n");
// Check that all required fields in this message are set.
// TODO(kenton): We can optimize this when we switch to putting all the
@@ -778,7 +795,7 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMakeImmutable(
.GenerateDynamicMethodMakeImmutableCode(printer);
}
printer->Print(
- "return null;");
+ "return null;\n");
}
// ===================================================================
@@ -786,7 +803,7 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMakeImmutable(
void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder(
io::Printer* printer) {
printer->Print(
- "return new Builder();");
+ "return new Builder();\n");
}
// ===================================================================
@@ -796,9 +813,8 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFrom(
printer->Print(
// Optimization: If other is the default instance, we know none of its
// fields are set so we can skip the merge.
- "Object arg = args[0];\n"
- "if (arg == $classname$.getDefaultInstance()) return this;\n"
- "$classname$ other = ($classname$) arg;\n",
+ "if (arg0 == $classname$.getDefaultInstance()) return this;\n"
+ "$classname$ other = ($classname$) arg0;\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -1151,9 +1167,11 @@ GenerateParsingConstructor(io::Printer* printer) {
// ===================================================================
void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) {
printer->Print(
- "public static final com.google.protobuf.Parser<$classname$> PARSER =\n"
- " new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n"
- "\n",
+ "private static volatile com.google.protobuf.Parser<$classname$> PARSER;\n"
+ "\n"
+ "public static com.google.protobuf.Parser<$classname$> parser() {\n"
+ " return DEFAULT_INSTANCE.getParserForType();\n"
+ "}\n",
"classname", descriptor_->name());
}
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
index 7bebe12a..178bbe19 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -35,6 +35,7 @@
#include <map>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
index 217ff9b6..392333b8 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
@@ -35,6 +35,7 @@
#include <map>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
diff --git a/src/google/protobuf/compiler/java/java_service.cc b/src/google/protobuf/compiler/java/java_service.cc
index 7baead15..11bfc12d 100644
--- a/src/google/protobuf/compiler/java/java_service.cc
+++ b/src/google/protobuf/compiler/java/java_service.cc
@@ -39,7 +39,6 @@
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/compiler/java/java_name_resolver.h>
#include <google/protobuf/io/printer.h>
-#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc
index 68e863cc..47e04659 100644
--- a/src/google/protobuf/compiler/java/java_string_field.cc
+++ b/src/google/protobuf/compiler/java/java_string_field.cc
@@ -36,6 +36,7 @@
#include <map>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
@@ -77,6 +78,10 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
" if (value == null) {\n"
" throw new NullPointerException();\n"
" }\n";
+ (*variables)["writeString"] =
+ "com.google.protobuf.GeneratedMessage.writeString";
+ (*variables)["computeStringSize"] =
+ "com.google.protobuf.GeneratedMessage.computeStringSize";
// TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
// by the proto compiler
@@ -433,7 +438,7 @@ void ImmutableStringFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($is_field_present_message$) {\n"
- " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+ " $writeString$(output, $number$, $name$_);\n"
"}\n");
}
@@ -441,8 +446,7 @@ void ImmutableStringFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($is_field_present_message$) {\n"
- " size += com.google.protobuf.CodedOutputStream\n"
- " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+ " size += $computeStringSize$($number$, $name$_);\n"
"}\n");
}
@@ -689,7 +693,7 @@ void ImmutableStringOneofFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($has_oneof_case_message$) {\n"
- " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+ " $writeString$(output, $number$, $oneof_name$_);\n"
"}\n");
}
@@ -697,8 +701,7 @@ void ImmutableStringOneofFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($has_oneof_case_message$) {\n"
- " size += com.google.protobuf.CodedOutputStream\n"
- " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+ " size += $computeStringSize$($number$, $oneof_name$_);\n"
"}\n");
}
@@ -1007,12 +1010,12 @@ GenerateSerializationCode(io::Printer* printer) const {
" output.writeRawVarint32($name$MemoizedSerializedSize);\n"
"}\n"
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.write$capitalized_type$NoTag($name$_.get(i));\n"
+ " writeStringNoTag(output, $name$_.getRaw(i));\n"
"}\n");
} else {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.writeBytes($number$, $name$_.getByteString(i));\n"
+ " $writeString$(output, $number$, $name$_.getRaw(i));\n"
"}\n");
}
}
@@ -1026,8 +1029,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " dataSize += com.google.protobuf.CodedOutputStream\n"
- " .computeBytesSizeNoTag($name$_.getByteString(i));\n"
+ " dataSize += computeStringSizeNoTag($name$_.getRaw(i));\n"
"}\n");
printer->Print(
diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.cc b/src/google/protobuf/compiler/java/java_string_field_lite.cc
index 51bb245c..032715b7 100644
--- a/src/google/protobuf/compiler/java/java_string_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc
@@ -36,6 +36,7 @@
#include <map>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
@@ -64,7 +65,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
SetCommonFieldVariables(descriptor, info, variables);
- (*variables)["empty_list"] = "emptyLazyStringArrayList()";
+ (*variables)["empty_list"] =
+ "com.google.protobuf.GeneratedMessageLite.emptyProtobufList()";
(*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
(*variables)["default_init"] =
@@ -101,7 +103,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
(*variables)["clear_has_field_bit_message"] = "";
(*variables)["is_field_present_message"] =
- "!get" + (*variables)["capitalized_name"] + "Bytes().isEmpty()";
+ "!get" + (*variables)["capitalized_name"] + ".isEmpty()";
}
// For repeated builders, the underlying list tracks mutability state.
@@ -144,8 +146,9 @@ int ImmutableStringFieldLiteGenerator::GetNumBitsForBuilder() const {
return 0;
}
-// A note about how strings are handled. This code used to just store a String
-// in the Message. This had two issues:
+// A note about how strings are handled. In the SPEED and CODE_SIZE runtimes,
+// strings are not stored as java.lang.String in the Message because of two
+// issues:
//
// 1. It wouldn't roundtrip byte arrays that were not vaid UTF-8 encoded
// strings, but rather fields that were raw bytes incorrectly marked
@@ -160,22 +163,14 @@ int ImmutableStringFieldLiteGenerator::GetNumBitsForBuilder() const {
// it many cases, the field is never even read by the application code. This
// avoids unnecessary conversions in the common use cases.
//
-// So now, the field for String is maintained as an Object reference which can
-// either store a String or a ByteString. The code uses an instanceof check
-// to see which one it has and converts to the other one if needed. It remembers
-// the last value requested (in a thread safe manner) as this is most likely
-// the one needed next. The thread safety is such that if two threads both
-// convert the field because the changes made by each thread were not visible to
-// the other, they may cause a conversion to happen more times than would
-// otherwise be necessary. This was deemed better than adding synchronization
-// overhead. It will not cause any corruption issues or affect the behavior of
-// the API. The instanceof check is also highly optimized in the JVM and we
-// decided it was better to reduce the memory overhead by not having two
-// separate fields but rather use dynamic type checking.
-//
-// For single fields, the logic for this is done inside the generated code. For
-// repeated fields, the logic is done in LazyStringArrayList and
-// UnmodifiableLazyStringList.
+// In the LITE_RUNTIME, we store strings as java.lang.String because we assume
+// that the users of this runtime are not subject to proto1 constraints and are
+// running code on devices that are user facing. That is, the developers are
+// properly incentivized to only fetch the data they need to read and wish to
+// reduce the number of allocations incurred when running on a user's device.
+
+// TODO(dweis): Consider dropping all of the *Bytes() methods. They really
+// shouldn't be necessary or used on devices.
void ImmutableStringFieldLiteGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
if (SupportFieldPresence(descriptor_->file())) {
@@ -195,7 +190,7 @@ GenerateInterfaceMembers(io::Printer* printer) const {
void ImmutableStringFieldLiteGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private java.lang.Object $name$_;\n");
+ "private java.lang.String $name$_;\n");
PrintExtraFieldInfo(variables_, printer);
if (SupportFieldPresence(descriptor_->file())) {
@@ -209,40 +204,13 @@ GenerateMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.lang.String get$capitalized_name$() {\n"
- " java.lang.Object ref = $name$_;\n"
- " if (ref instanceof java.lang.String) {\n"
- " return (java.lang.String) ref;\n"
- " } else {\n"
- " com.google.protobuf.ByteString bs = \n"
- " (com.google.protobuf.ByteString) ref;\n"
- " java.lang.String s = bs.toStringUtf8();\n");
- if (CheckUtf8(descriptor_)) {
- printer->Print(variables_,
- " $name$_ = s;\n");
- } else {
- printer->Print(variables_,
- " if (bs.isValidUtf8()) {\n"
- " $name$_ = s;\n"
- " }\n");
- }
- printer->Print(variables_,
- " return s;\n"
- " }\n"
+ " return $name$_;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public com.google.protobuf.ByteString\n"
" get$capitalized_name$Bytes() {\n"
- " java.lang.Object ref = $name$_;\n"
- " if (ref instanceof java.lang.String) {\n"
- " com.google.protobuf.ByteString b = \n"
- " com.google.protobuf.ByteString.copyFromUtf8(\n"
- " (java.lang.String) ref);\n"
- " $name$_ = b;\n"
- " return b;\n"
- " } else {\n"
- " return (com.google.protobuf.ByteString) ref;\n"
- " }\n"
+ " return com.google.protobuf.ByteString.copyFromUtf8($name$_);\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
@@ -273,7 +241,7 @@ GenerateMembers(io::Printer* printer) const {
}
printer->Print(variables_,
" $set_has_field_bit_message$\n"
- " $name$_ = value;\n"
+ " $name$_ = value.toStringUtf8();\n"
"}\n");
}
@@ -368,7 +336,7 @@ GenerateParsingCode(io::Printer* printer) const {
"String s = input.readStringRequireUtf8();\n"
"$set_has_field_bit_message$\n"
"$name$_ = s;\n");
- } else if (!HasDescriptorMethods(descriptor_->file())) {
+ } else {
// Lite runtime should attempt to reduce allocations by attempting to
// construct the string directly from the input stream buffer. This avoids
// spurious intermediary ByteString allocations, cutting overall allocations
@@ -377,11 +345,6 @@ GenerateParsingCode(io::Printer* printer) const {
"String s = input.readString();\n"
"$set_has_field_bit_message$\n"
"$name$_ = s;\n");
- } else {
- printer->Print(variables_,
- "com.google.protobuf.ByteString bs = input.readBytes();\n"
- "$set_has_field_bit_message$\n"
- "$name$_ = bs;\n");
}
}
@@ -392,18 +355,24 @@ GenerateParsingDoneCode(io::Printer* printer) const {
void ImmutableStringFieldLiteGenerator::
GenerateSerializationCode(io::Printer* printer) const {
+ // Lite runtime should reduce allocations by serializing the string directly.
+ // This avoids spurious intermediary ByteString allocations, cutting overall
+ // allocations in half.
printer->Print(variables_,
"if ($is_field_present_message$) {\n"
- " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+ " output.writeString($number$, get$capitalized_name$());\n"
"}\n");
}
void ImmutableStringFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
+ // Lite runtime should reduce allocations by computing on the string directly.
+ // This avoids spurious intermediary ByteString allocations, cutting overall
+ // allocations in half.
printer->Print(variables_,
"if ($is_field_present_message$) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+ " .computeStringSize($number$, get$capitalized_name$());\n"
"}\n");
}
@@ -458,51 +427,22 @@ GenerateMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.lang.String get$capitalized_name$() {\n"
- " java.lang.Object ref $default_init$;\n"
+ " java.lang.String ref $default_init$;\n"
" if ($has_oneof_case_message$) {\n"
- " ref = $oneof_name$_;\n"
- " }\n"
- " if (ref instanceof java.lang.String) {\n"
- " return (java.lang.String) ref;\n"
- " } else {\n"
- " com.google.protobuf.ByteString bs = \n"
- " (com.google.protobuf.ByteString) ref;\n"
- " java.lang.String s = bs.toStringUtf8();\n");
- if (CheckUtf8(descriptor_)) {
- printer->Print(variables_,
- " if ($has_oneof_case_message$) {\n"
- " $oneof_name$_ = s;\n"
- " }\n");
- } else {
- printer->Print(variables_,
- " if (bs.isValidUtf8() && ($has_oneof_case_message$)) {\n"
- " $oneof_name$_ = s;\n"
- " }\n");
- }
- printer->Print(variables_,
- " return s;\n"
+ " ref = (java.lang.String) $oneof_name$_;\n"
" }\n"
+ " return ref;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public com.google.protobuf.ByteString\n"
" get$capitalized_name$Bytes() {\n"
- " java.lang.Object ref $default_init$;\n"
+ " java.lang.String ref $default_init$;\n"
" if ($has_oneof_case_message$) {\n"
- " ref = $oneof_name$_;\n"
- " }\n"
- " if (ref instanceof java.lang.String) {\n"
- " com.google.protobuf.ByteString b = \n"
- " com.google.protobuf.ByteString.copyFromUtf8(\n"
- " (java.lang.String) ref);\n"
- " if ($has_oneof_case_message$) {\n"
- " $oneof_name$_ = b;\n"
- " }\n"
- " return b;\n"
- " } else {\n"
- " return (com.google.protobuf.ByteString) ref;\n"
+ " ref = (java.lang.String) $oneof_name$_;\n"
" }\n"
+ " return com.google.protobuf.ByteString.copyFromUtf8(ref);\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
@@ -533,7 +473,7 @@ GenerateMembers(io::Printer* printer) const {
}
printer->Print(variables_,
" $set_oneof_case_message$;\n"
- " $oneof_name$_ = value;\n"
+ " $oneof_name$_ = value.toStringUtf8();\n"
"}\n");
}
@@ -603,7 +543,7 @@ GenerateParsingCode(io::Printer* printer) const {
"String s = input.readStringRequireUtf8();\n"
"$set_oneof_case_message$;\n"
"$oneof_name$_ = s;\n");
- } else if (!HasDescriptorMethods(descriptor_->file())) {
+ } else {
// Lite runtime should attempt to reduce allocations by attempting to
// construct the string directly from the input stream buffer. This avoids
// spurious intermediary ByteString allocations, cutting overall allocations
@@ -612,28 +552,29 @@ GenerateParsingCode(io::Printer* printer) const {
"String s = input.readString();\n"
"$set_oneof_case_message$;\n"
"$oneof_name$_ = s;\n");
- } else {
- printer->Print(variables_,
- "com.google.protobuf.ByteString bs = input.readBytes();\n"
- "$set_oneof_case_message$;\n"
- "$oneof_name$_ = bs;\n");
}
}
void ImmutableStringOneofFieldLiteGenerator::
GenerateSerializationCode(io::Printer* printer) const {
+ // Lite runtime should reduce allocations by serializing the string directly.
+ // This avoids spurious intermediary ByteString allocations, cutting overall
+ // allocations in half.
printer->Print(variables_,
"if ($has_oneof_case_message$) {\n"
- " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+ " output.writeString($number$, get$capitalized_name$());\n"
"}\n");
}
void ImmutableStringOneofFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
+ // Lite runtime should reduce allocations by computing on the string directly.
+ // This avoids spurious intermediary ByteString allocations, cutting overall
+ // allocations in half.
printer->Print(variables_,
"if ($has_oneof_case_message$) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+ " .computeStringSize($number$, get$capitalized_name$());\n"
"}\n");
}
@@ -667,7 +608,7 @@ void RepeatedImmutableStringFieldLiteGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
- "$deprecation$com.google.protobuf.ProtocolStringList\n"
+ "$deprecation$java.util.List<String>\n"
" get$capitalized_name$List();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
@@ -685,12 +626,11 @@ GenerateInterfaceMembers(io::Printer* printer) const {
void RepeatedImmutableStringFieldLiteGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private com.google.protobuf.LazyStringArrayList $name$_;\n");
+ "private com.google.protobuf.Internal.ProtobufList<String> $name$_;\n");
PrintExtraFieldInfo(variables_, printer);
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
- "$deprecation$public com.google.protobuf.ProtocolStringList\n"
- " get$capitalized_name$List() {\n"
+ "$deprecation$public java.util.List<String> get$capitalized_name$List() {\n"
" return $name$_;\n" // note: unmodifiable list
"}\n");
WriteFieldDocComment(printer, descriptor_);
@@ -707,7 +647,8 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"$deprecation$public com.google.protobuf.ByteString\n"
" get$capitalized_name$Bytes(int index) {\n"
- " return $name$_.getByteString(index);\n"
+ " return com.google.protobuf.ByteString.copyFromUtf8(\n"
+ " $name$_.get(index));\n"
"}\n");
if (descriptor_->options().packed() &&
@@ -719,7 +660,8 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private void ensure$capitalized_name$IsMutable() {\n"
" if (!$is_mutable$) {\n"
- " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n"
+ " $name$_ = com.google.protobuf.GeneratedMessageLite.newProtobufList(\n"
+ " $name$_);\n"
" }\n"
"}\n");
@@ -764,7 +706,7 @@ GenerateMembers(io::Printer* printer) const {
}
printer->Print(variables_,
" ensure$capitalized_name$IsMutable();\n"
- " $name$_.add(value);\n"
+ " $name$_.add(value.toStringUtf8());\n"
"}\n");
}
@@ -772,10 +714,10 @@ void RepeatedImmutableStringFieldLiteGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
- "$deprecation$public com.google.protobuf.ProtocolStringList\n"
+ "$deprecation$public java.util.List<String>\n"
" get$capitalized_name$List() {\n"
- " return ((com.google.protobuf.LazyStringList)\n"
- " instance.get$capitalized_name$List()).getUnmodifiableView();\n"
+ " return java.util.Collections.unmodifiableList(\n"
+ " instance.get$capitalized_name$List());\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
@@ -875,20 +817,17 @@ GenerateParsingCode(io::Printer* printer) const {
if (CheckUtf8(descriptor_)) {
printer->Print(variables_,
"String s = input.readStringRequireUtf8();\n");
- } else if (!HasDescriptorMethods(descriptor_->file())) {
+ } else {
// Lite runtime should attempt to reduce allocations by attempting to
// construct the string directly from the input stream buffer. This avoids
// spurious intermediary ByteString allocations, cutting overall allocations
// in half.
printer->Print(variables_,
"String s = input.readString();\n");
- } else {
- printer->Print(variables_,
- "com.google.protobuf.ByteString bs = input.readBytes();\n");
}
printer->Print(variables_,
"if (!$is_mutable$) {\n"
- " $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
+ " $name$_ = com.google.protobuf.GeneratedMessageLite.newProtobufList();\n"
"}\n");
if (CheckUtf8(descriptor_) || !HasDescriptorMethods(descriptor_->file())) {
printer->Print(variables_,
@@ -905,7 +844,7 @@ GenerateParsingCodeFromPacked(io::Printer* printer) const {
"int length = input.readRawVarint32();\n"
"int limit = input.pushLimit(length);\n"
"if (!$is_mutable$ && input.getBytesUntilLimit() > 0) {\n"
- " $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
+ " $name$_ = com.google.protobuf.GeneratedMessageLite.newProtobufList();\n"
"}\n"
"while (input.getBytesUntilLimit() > 0) {\n");
if (CheckUtf8(descriptor_)) {
@@ -932,6 +871,9 @@ GenerateParsingDoneCode(io::Printer* printer) const {
void RepeatedImmutableStringFieldLiteGenerator::
GenerateSerializationCode(io::Printer* printer) const {
+ // Lite runtime should reduce allocations by serializing the string directly.
+ // This avoids spurious intermediary ByteString allocations, cutting overall
+ // allocations in half.
if (descriptor_->options().packed()) {
printer->Print(variables_,
"if (get$capitalized_name$List().size() > 0) {\n"
@@ -939,18 +881,21 @@ GenerateSerializationCode(io::Printer* printer) const {
" output.writeRawVarint32($name$MemoizedSerializedSize);\n"
"}\n"
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.write$capitalized_type$NoTag($name$_.get(i));\n"
+ " output.writeStringNoTag($name$_.get(i));\n"
"}\n");
} else {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.writeBytes($number$, $name$_.getByteString(i));\n"
+ " output.writeString($number$, $name$_.get(i));\n"
"}\n");
}
}
void RepeatedImmutableStringFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
+ // Lite runtime should reduce allocations by computing on the string directly.
+ // This avoids spurious intermediary ByteString allocations, cutting overall
+ // allocations in half.
printer->Print(variables_,
"{\n"
" int dataSize = 0;\n");
@@ -959,7 +904,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
" dataSize += com.google.protobuf.CodedOutputStream\n"
- " .computeBytesSizeNoTag($name$_.getByteString(i));\n"
+ " .computeStringSizeNoTag($name$_.get(i));\n"
"}\n");
printer->Print(
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index a2eeee2d..895ff34a 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -44,6 +44,7 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/map_util.h>
diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h
index 16012e96..007b001c 100644
--- a/src/google/protobuf/compiler/parser.h
+++ b/src/google/protobuf/compiler/parser.h
@@ -323,7 +323,7 @@ class LIBPROTOBUF_EXPORT Parser {
const LocationRecorder& service_location,
const FileDescriptorProto* containing_file);
- // Parse one statement within a message, enum, or service block, inclunding
+ // Parse one statement within a message, enum, or service block, including
// final semicolon.
bool ParseMessageStatement(DescriptorProto* message,
const LocationRecorder& message_location,
@@ -364,7 +364,7 @@ class LIBPROTOBUF_EXPORT Parser {
const LocationRecorder& extensions_location,
const FileDescriptorProto* containing_file);
- // Parse an "reserved" declaration.
+ // Parse a "reserved" declaration.
bool ParseReserved(DescriptorProto* message,
const LocationRecorder& message_location);
bool ParseReservedNames(DescriptorProto* message,
@@ -415,7 +415,7 @@ class LIBPROTOBUF_EXPORT Parser {
Message* mutable_options);
// Parse "required", "optional", or "repeated" and fill in "label"
- // with the value. Returns true if shuch a label is consumed.
+ // with the value. Returns true if such a label is consumed.
bool ParseLabel(FieldDescriptorProto::Label* label,
const FileDescriptorProto* containing_file);
diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc
index cdcaffde..2bebf1f3 100644
--- a/src/google/protobuf/compiler/plugin.cc
+++ b/src/google/protobuf/compiler/plugin.cc
@@ -48,6 +48,7 @@
#include <unistd.h>
#endif
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/plugin.pb.h>
#include <google/protobuf/compiler/code_generator.h>
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index e7890fae..994bc392 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -629,28 +629,28 @@ int CodeGeneratorRequest::proto_file_size() const {
void CodeGeneratorRequest::clear_proto_file() {
proto_file_.Clear();
}
- const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const {
+const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return proto_file_.Get(index);
}
- ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) {
+::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return proto_file_.Mutable(index);
}
- ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() {
+::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() {
// @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return proto_file_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
-CodeGeneratorRequest::proto_file() const {
- // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
- return proto_file_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
CodeGeneratorRequest::mutable_proto_file() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return &proto_file_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+CodeGeneratorRequest::proto_file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+ return proto_file_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1535,28 +1535,28 @@ int CodeGeneratorResponse::file_size() const {
void CodeGeneratorResponse::clear_file() {
file_.Clear();
}
- const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const {
+const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.file)
return file_.Get(index);
}
- ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) {
+::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.file)
return file_.Mutable(index);
}
- ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() {
+::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() {
// @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file)
return file_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
-CodeGeneratorResponse::file() const {
- // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
- return file_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
CodeGeneratorResponse::mutable_file() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file)
return &file_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
+CodeGeneratorResponse::file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
+ return file_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index 6fcaea2e..ab79bdae 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -144,10 +144,10 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
const ::google::protobuf::FileDescriptorProto& proto_file(int index) const;
::google::protobuf::FileDescriptorProto* mutable_proto_file(int index);
::google::protobuf::FileDescriptorProto* add_proto_file();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
- proto_file() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
mutable_proto_file();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+ proto_file() const;
// @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
private:
@@ -378,10 +378,10 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const;
::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index);
::google::protobuf::compiler::CodeGeneratorResponse_File* add_file();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
- file() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
mutable_file();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
+ file() const;
// @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
private:
@@ -534,16 +534,16 @@ inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_
// @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return proto_file_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
-CodeGeneratorRequest::proto_file() const {
- // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
- return proto_file_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
CodeGeneratorRequest::mutable_proto_file() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return &proto_file_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+CodeGeneratorRequest::proto_file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+ return proto_file_;
+}
// -------------------------------------------------------------------
@@ -784,16 +784,16 @@ inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorRe
// @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file)
return file_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
-CodeGeneratorResponse::file() const {
- // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
- return file_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
CodeGeneratorResponse::mutable_file() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file)
return &file_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
+CodeGeneratorResponse::file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
+ return file_;
+}
#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
// -------------------------------------------------------------------
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
index 7b3b5fa3..4d500f90 100644
--- a/src/google/protobuf/compiler/python/python_generator.cc
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -58,6 +58,7 @@
#include <google/protobuf/compiler/python/python_generator.h>
#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/io/printer.h>
diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h
index 2ddac601..aa0f5fce 100644
--- a/src/google/protobuf/compiler/python/python_generator.h
+++ b/src/google/protobuf/compiler/python/python_generator.h
@@ -38,6 +38,7 @@
#include <string>
#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/common.h>
namespace google {
diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc
index a3cff1f8..85429924 100644
--- a/src/google/protobuf/compiler/subprocess.cc
+++ b/src/google/protobuf/compiler/subprocess.cc
@@ -42,6 +42,7 @@
#include <signal.h>
#endif
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message.h>
#include <google/protobuf/stubs/substitute.h>