aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler
diff options
context:
space:
mode:
authorGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-07-29 01:13:20 +0000
committerGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-07-29 01:13:20 +0000
commit80b1d62bfcea65c59e2160da71dad84b1bd19cef (patch)
tree5423b830c53174fec83a7ea01ff0877e11c1ddb6 /src/google/protobuf/compiler
parentd2fd0638c309113ccae3731a58e30419f522269a (diff)
Submit recent changes from internal branch, including "lite mode" for
C++ and Java. See CHANGES.txt for more details.
Diffstat (limited to 'src/google/protobuf/compiler')
-rw-r--r--src/google/protobuf/compiler/code_generator.cc22
-rw-r--r--src/google/protobuf/compiler/code_generator.h11
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum.cc79
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum.h4
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum_field.cc107
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_extension.cc1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_field.cc19
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_field.h10
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.cc315
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_generator.cc29
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.cc13
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.h29
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.cc523
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.h9
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.cc67
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_primitive_field.cc111
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_service.cc2
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.cc129
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc64
-rw-r--r--src/google/protobuf/compiler/java/java_enum.cc148
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field.cc43
-rw-r--r--src/google/protobuf/compiler/java/java_extension.cc99
-rw-r--r--src/google/protobuf/compiler/java/java_file.cc43
-rw-r--r--src/google/protobuf/compiler/java/java_file.h2
-rw-r--r--src/google/protobuf/compiler/java/java_generator.cc28
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.cc67
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.h30
-rw-r--r--src/google/protobuf/compiler/java/java_message.cc478
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field.cc103
-rw-r--r--src/google/protobuf/compiler/parser.cc2
30 files changed, 1604 insertions, 983 deletions
diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc
index 149d34af..0def84d8 100644
--- a/src/google/protobuf/compiler/code_generator.cc
+++ b/src/google/protobuf/compiler/code_generator.cc
@@ -34,6 +34,8 @@
#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/stubs/strutil.h>
+
namespace google {
namespace protobuf {
namespace compiler {
@@ -41,6 +43,26 @@ namespace compiler {
CodeGenerator::~CodeGenerator() {}
OutputDirectory::~OutputDirectory() {}
+// Parses a set of comma-delimited name/value pairs.
+void ParseGeneratorParameter(const string& text,
+ vector<pair<string, string> >* output) {
+ vector<string> parts;
+ SplitStringUsing(text, ",", &parts);
+
+ for (int i = 0; i < parts.size(); i++) {
+ string::size_type equals_pos = parts[i].find_first_of('=');
+ pair<string, string> value;
+ if (equals_pos == string::npos) {
+ value.first = parts[i];
+ value.second = "";
+ } else {
+ value.first = parts[i].substr(0, equals_pos);
+ value.second = parts[i].substr(equals_pos + 1);
+ }
+ output->push_back(value);
+ }
+}
+
} // namespace compiler
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h
index d22974e9..8a7081f7 100644
--- a/src/google/protobuf/compiler/code_generator.h
+++ b/src/google/protobuf/compiler/code_generator.h
@@ -40,6 +40,8 @@
#include <google/protobuf/stubs/common.h>
#include <string>
+#include <vector>
+#include <utility>
namespace google {
namespace protobuf {
@@ -105,6 +107,15 @@ class LIBPROTOC_EXPORT OutputDirectory {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OutputDirectory);
};
+// Several code generators treat the parameter argument as holding a
+// list of options separated by commas. This helper function parses
+// a set of comma-delimited name/value pairs: e.g.,
+// "foo=bar,baz,qux=corge"
+// parses to the pairs:
+// ("foo", "bar"), ("baz", ""), ("qux", "corge")
+extern void ParseGeneratorParameter(const string&,
+ vector<pair<string, string> >*);
+
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc
index 875cbef8..90e9172a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -95,24 +95,39 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
}
printer->Print(vars,
- "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n"
"$dllexport$bool $classname$_IsValid(int value);\n"
"const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n"
"const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"
"\n");
- // The _Name and _Parse methods
- printer->Print(vars,
- "inline const ::std::string& $classname$_Name($classname$ value) {\n"
- " return ::google::protobuf::internal::NameOfEnum(\n"
- " $classname$_descriptor(), value);\n"
- "}\n");
- printer->Print(vars,
- "inline bool $classname$_Parse(\n"
- " const ::std::string& name, $classname$* value) {\n"
- " return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n"
- " $classname$_descriptor(), name, value);\n"
- "}\n");
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(vars,
+ "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n");
+ // The _Name and _Parse methods
+ printer->Print(vars,
+ "inline const ::std::string& $classname$_Name($classname$ value) {\n"
+ " return ::google::protobuf::internal::NameOfEnum(\n"
+ " $classname$_descriptor(), value);\n"
+ "}\n");
+ printer->Print(vars,
+ "inline bool $classname$_Parse(\n"
+ " const ::std::string& name, $classname$* value) {\n"
+ " return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n"
+ " $classname$_descriptor(), name, value);\n"
+ "}\n");
+ }
+}
+
+void EnumGenerator::
+GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "template <>\n"
+ "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n"
+ " return $classname$_descriptor();\n"
+ "}\n",
+ "classname", ClassName(descriptor_, true));
+ }
}
void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
@@ -128,24 +143,28 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
}
printer->Print(vars,
- "static inline const ::google::protobuf::EnumDescriptor*\n"
- "$nested_name$_descriptor() {\n"
- " return $classname$_descriptor();\n"
- "}\n"
"static inline bool $nested_name$_IsValid(int value) {\n"
" return $classname$_IsValid(value);\n"
"}\n"
- "static inline const ::std::string& $nested_name$_Name($nested_name$ value) {\n"
- " return $classname$_Name(value);\n"
- "}\n"
- "static inline bool $nested_name$_Parse(const ::std::string& name,\n"
- " $nested_name$* value) {\n"
- " return $classname$_Parse(name, value);\n"
- "}\n"
"static const $nested_name$ $nested_name$_MIN =\n"
" $classname$_$nested_name$_MIN;\n"
"static const $nested_name$ $nested_name$_MAX =\n"
" $classname$_$nested_name$_MAX;\n");
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(vars,
+ "static inline const ::google::protobuf::EnumDescriptor*\n"
+ "$nested_name$_descriptor() {\n"
+ " return $classname$_descriptor();\n"
+ "}\n"
+ "static inline const ::std::string& $nested_name$_Name($nested_name$ value) {\n"
+ " return $classname$_Name(value);\n"
+ "}\n"
+ "static inline bool $nested_name$_Parse(const ::std::string& name,\n"
+ " $nested_name$* value) {\n"
+ " return $classname$_Parse(name, value);\n"
+ "}\n");
+ }
}
void EnumGenerator::GenerateDescriptorInitializer(
@@ -168,11 +187,15 @@ void EnumGenerator::GenerateMethods(io::Printer* printer) {
map<string, string> vars;
vars["classname"] = classname_;
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(vars,
+ "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
+ " protobuf_AssignDescriptorsOnce();\n"
+ " return $classname$_descriptor_;\n"
+ "}\n");
+ }
+
printer->Print(vars,
- "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
- " protobuf_AssignDescriptorsOnce();\n"
- " return $classname$_descriptor_;\n"
- "}\n"
"bool $classname$_IsValid(int value) {\n"
" switch(value) {\n");
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/google/protobuf/compiler/cpp/cpp_enum.h
index 9f2e5fee..58f7721e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.h
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.h
@@ -63,6 +63,10 @@ class EnumGenerator {
// nested enums.
void GenerateDefinition(io::Printer* printer);
+ // Generate specialization of GetEnumDescriptor<MyEnum>().
+ // Precondition: in ::google::protobuf namespace.
+ void GenerateGetEnumDescriptorSpecializations(io::Printer* printer);
+
// For enums nested within a message, generate code to import all the enum's
// symbols (e.g. the enum type name, all its values, etc.) into the class's
// namespace. This should be placed inside the class definition in the
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index b90eb372..7ca11c8c 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -35,7 +35,7 @@
#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/wire_format_inl.h>
+#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
@@ -43,24 +43,14 @@ namespace protobuf {
namespace compiler {
namespace cpp {
-using internal::WireFormat;
-
namespace {
-// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
-// repeat code between this and the other field types.
void SetEnumVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
+ SetCommonFieldVariables(descriptor, variables);
const EnumValueDescriptor* default_value = descriptor->default_value_enum();
-
- (*variables)["name"] = FieldName(descriptor);
(*variables)["type"] = ClassName(descriptor->enum_type(), true);
(*variables)["default"] = SimpleItoa(default_value->number());
- (*variables)["index"] = SimpleItoa(descriptor->index());
- (*variables)["number"] = SimpleItoa(descriptor->number());
- (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
- (*variables)["tag_size"] = SimpleItoa(
- WireFormat::TagSize(descriptor->number(), descriptor->type()));
}
} // namespace
@@ -83,8 +73,8 @@ GeneratePrivateMembers(io::Printer* printer) const {
void EnumFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "inline $type$ $name$() const;\n"
- "inline void set_$name$($type$ value);\n");
+ "inline $type$ $name$() const$deprecation$;\n"
+ "inline void set_$name$($type$ value)$deprecation$;\n");
}
void EnumFieldGenerator::
@@ -124,33 +114,37 @@ void EnumFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
printer->Print(variables_,
"int value;\n"
- "DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));\n"
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value));\n"
"if ($type$_IsValid(value)) {\n"
- " set_$name$(static_cast< $type$ >(value));\n"
- "} else {\n"
- " mutable_unknown_fields()->AddVarint($number$, value);\n"
+ " set_$name$(static_cast< $type$ >(value));\n");
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(variables_,
+ "} else {\n"
+ " mutable_unknown_fields()->AddVarint($number$, value);\n");
+ }
+ printer->Print(variables_,
"}\n");
}
void EnumFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::WriteEnum("
- "$number$, this->$name$(), output);\n");
+ "::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
+ " $number$, this->$name$(), output);\n");
}
void EnumFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
printer->Print(variables_,
- "target = ::google::protobuf::internal::WireFormat::WriteEnumToArray("
- "$number$, this->$name$(), target);\n");
+ "target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
+ " $number$, this->$name$(), target);\n");
}
void EnumFieldGenerator::
GenerateByteSize(io::Printer* printer) const {
printer->Print(variables_,
"total_size += $tag_size$ +\n"
- " ::google::protobuf::internal::WireFormat::EnumSize(this->$name$());\n");
+ " ::google::protobuf::internal::WireFormatLite::EnumSize(this->$name$());\n");
}
// ===================================================================
@@ -167,8 +161,7 @@ void RepeatedEnumFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
printer->Print(variables_,
"::google::protobuf::RepeatedField<int> $name$_;\n");
- if (descriptor_->options().packed() &&
- descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->file())) {
printer->Print(variables_,
"mutable int _$name$_cached_byte_size_;\n");
}
@@ -177,11 +170,11 @@ GeneratePrivateMembers(io::Printer* printer) const {
void RepeatedEnumFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "inline const ::google::protobuf::RepeatedField<int>& $name$() const;\n"
- "inline ::google::protobuf::RepeatedField<int>* mutable_$name$();\n"
- "inline $type$ $name$(int index) const;\n"
- "inline void set_$name$(int index, $type$ value);\n"
- "inline void add_$name$($type$ value);\n");
+ "inline const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n"
+ "inline ::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n"
+ "inline $type$ $name$(int index) const$deprecation$;\n"
+ "inline void set_$name$(int index, $type$ value)$deprecation$;\n"
+ "inline void add_$name$($type$ value)$deprecation$;\n");
}
void RepeatedEnumFieldGenerator::
@@ -238,7 +231,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
"input->PushLimit(length);\n"
"while (input->BytesUntilLimit() > 0) {\n"
" int value;\n"
- " DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));\n"
+ " DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value));\n"
" if ($type$_IsValid(value)) {\n"
" add_$name$(static_cast< $type$ >(value));\n"
" }\n"
@@ -247,11 +240,15 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
} else {
printer->Print(variables_,
"int value;\n"
- "DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));\n"
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value));\n"
"if ($type$_IsValid(value)) {\n"
- " add_$name$(static_cast< $type$ >(value));\n"
- "} else {\n"
- " mutable_unknown_fields()->AddVarint($number$, value);\n"
+ " add_$name$(static_cast< $type$ >(value));\n");
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(variables_,
+ "} else {\n"
+ " mutable_unknown_fields()->AddVarint($number$, value);\n");
+ }
+ printer->Print(variables_,
"}\n");
}
}
@@ -262,10 +259,10 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const {
// Write the tag and the size.
printer->Print(variables_,
"if (this->$name$_size() > 0) {\n"
- " ::google::protobuf::internal::WireFormat::WriteTag("
- "$number$, "
- "::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED, "
- "output);\n"
+ " ::google::protobuf::internal::WireFormatLite::WriteTag(\n"
+ " $number$,\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+ " output);\n"
" output->WriteVarint32(_$name$_cached_byte_size_);\n"
"}\n");
}
@@ -273,12 +270,12 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const {
"for (int i = 0; i < this->$name$_size(); i++) {\n");
if (descriptor_->options().packed()) {
printer->Print(variables_,
- " ::google::protobuf::internal::WireFormat::WriteEnumNoTag("
- "this->$name$(i), output);\n");
+ " ::google::protobuf::internal::WireFormatLite::WriteEnumNoTag(\n"
+ " this->$name$(i), output);\n");
} else {
printer->Print(variables_,
- " ::google::protobuf::internal::WireFormat::WriteEnum("
- "$number$, this->$name$(i), output);\n");
+ " ::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
+ " $number$, this->$name$(i), output);\n");
}
printer->Print("}\n");
}
@@ -289,24 +286,24 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
// Write the tag and the size.
printer->Print(variables_,
"if (this->$name$_size() > 0) {\n"
- " target = ::google::protobuf::internal::WireFormat::WriteTagToArray("
- "$number$, "
- "::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED, "
- "target);\n"
+ " target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
+ " $number$,\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+ " target);\n"
" target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray("
- "_$name$_cached_byte_size_, target);\n"
+ " _$name$_cached_byte_size_, target);\n"
"}\n");
}
printer->Print(variables_,
"for (int i = 0; i < this->$name$_size(); i++) {\n");
if (descriptor_->options().packed()) {
printer->Print(variables_,
- " target = ::google::protobuf::internal::WireFormat::WriteEnumNoTagToArray("
- "this->$name$(i), target);\n");
+ " target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n"
+ " this->$name$(i), target);\n");
} else {
printer->Print(variables_,
- " target = ::google::protobuf::internal::WireFormat::WriteEnumToArray("
- "$number$, this->$name$(i), target);\n");
+ " target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
+ " $number$, this->$name$(i), target);\n");
}
printer->Print("}\n");
}
@@ -319,15 +316,15 @@ GenerateByteSize(io::Printer* printer) const {
printer->Indent();
printer->Print(variables_,
"for (int i = 0; i < this->$name$_size(); i++) {\n"
- " data_size += ::google::protobuf::internal::WireFormat::EnumSize(\n"
+ " data_size += ::google::protobuf::internal::WireFormatLite::EnumSize(\n"
" this->$name$(i));\n"
"}\n");
if (descriptor_->options().packed()) {
printer->Print(variables_,
"if (data_size > 0) {\n"
- " total_size += $tag_size$ + "
- "::google::protobuf::internal::WireFormat::Int32Size(data_size);\n"
+ " total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
"}\n"
"_$name$_cached_byte_size_ = data_size;\n"
"total_size += data_size;\n");
diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc
index cd4806ba..7208ed3a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_extension.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc
@@ -133,6 +133,7 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
vars["global_name"] = global_name;
printer->Print(vars,
"const ::std::string $global_name$_default($default$);\n");
+
// Update the default to refer to the string global.
vars["default"] = global_name + "_default";
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc
index 47daac7a..c546e964 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_field.cc
@@ -33,18 +33,37 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
#include <google/protobuf/compiler/cpp/cpp_string_field.h>
#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
#include <google/protobuf/compiler/cpp/cpp_message_field.h>
#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace cpp {
+using internal::WireFormat;
+
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables) {
+ (*variables)["name"] = FieldName(descriptor);
+ (*variables)["index"] = SimpleItoa(descriptor->index());
+ (*variables)["number"] = SimpleItoa(descriptor->number());
+ (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
+ (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
+
+ (*variables)["tag_size"] = SimpleItoa(
+ WireFormat::TagSize(descriptor->number(), descriptor->type()));
+ (*variables)["deprecation"] = descriptor->options().deprecated()
+ ? " DEPRECATED_PROTOBUF_FIELD" : "";
+}
+
FieldGenerator::~FieldGenerator() {}
FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h
index 7e7c7f83..00ec2c7c 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_field.h
@@ -35,6 +35,9 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
+#include <map>
+#include <string>
+
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
@@ -49,6 +52,13 @@ namespace protobuf {
namespace compiler {
namespace cpp {
+// Helper function: set variables in the map that are the same for all
+// field code generators.
+// ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size',
+// 'deprecation'].
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables);
+
class FieldGenerator {
public:
FieldGenerator() {}
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index f056ed57..51859bb3 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -125,13 +125,18 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
// OK, it's now safe to #include other files.
printer->Print(
- "#include <google/protobuf/generated_message_reflection.h>\n"
+ "#include <google/protobuf/generated_message_util.h>\n"
"#include <google/protobuf/repeated_field.h>\n"
"#include <google/protobuf/extension_set.h>\n");
- if (file_->service_count() > 0) {
+ if (HasDescriptorMethods(file_)) {
printer->Print(
- "#include <google/protobuf/service.h>\n");
+ "#include <google/protobuf/generated_message_reflection.h>\n");
+
+ if (file_->service_count() > 0) {
+ printer->Print(
+ "#include <google/protobuf/service.h>\n");
+ }
}
for (int i = 0; i < file_->dependency_count(); i++) {
@@ -193,19 +198,21 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
printer->Print(kThickSeparator);
printer->Print("\n");
- // Generate service definitions.
- for (int i = 0; i < file_->service_count(); i++) {
- if (i > 0) {
- printer->Print("\n");
- printer->Print(kThinSeparator);
- printer->Print("\n");
+ if (HasDescriptorMethods(file_)) {
+ // Generate service definitions.
+ for (int i = 0; i < file_->service_count(); i++) {
+ if (i > 0) {
+ printer->Print("\n");
+ printer->Print(kThinSeparator);
+ printer->Print("\n");
+ }
+ service_generators_[i]->GenerateDeclarations(printer);
}
- service_generators_[i]->GenerateDeclarations(printer);
- }
- printer->Print("\n");
- printer->Print(kThickSeparator);
- printer->Print("\n");
+ printer->Print("\n");
+ printer->Print(kThickSeparator);
+ printer->Print("\n");
+ }
// Declare extension identifiers.
for (int i = 0; i < file_->extension_count(); i++) {
@@ -228,6 +235,30 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
// Close up namespace.
GenerateNamespaceClosers(printer);
+ // Emit GetEnumDescriptor specializations into google::protobuf namespace:
+ if (HasDescriptorMethods(file_)) {
+ // The SWIG conditional is to avoid a null-pointer dereference
+ // (bug 1984964) in swig-1.3.21 resulting from the following syntax:
+ // namespace X { void Y<Z::W>(); }
+ // which appears in GetEnumDescriptor() specializations.
+ printer->Print(
+ "\n"
+ "#ifndef SWIG\n"
+ "namespace google {\nnamespace protobuf {\n"
+ "\n");
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+ }
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+ }
+ printer->Print(
+ "\n"
+ "} // namespace google\n} // namespace protobuf\n"
+ "#endif // SWIG\n"
+ "\n");
+ }
+
printer->Print(
"#endif // PROTOBUF_$filename_identifier$__INCLUDED\n",
"filename_identifier", filename_identifier);
@@ -237,40 +268,52 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
printer->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
"\n"
+ // The generated code calls accessors that might be deprecated. We don't
+ // want the compiler to warn in generated code.
+ "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n"
"#include \"$basename$.pb.h\"\n"
+
"#include <google/protobuf/stubs/once.h>\n"
- "#include <google/protobuf/descriptor.h>\n"
"#include <google/protobuf/io/coded_stream.h>\n"
- "#include <google/protobuf/reflection_ops.h>\n"
- "#include <google/protobuf/wire_format_inl.h>\n",
+ "#include <google/protobuf/wire_format_lite_inl.h>\n",
"basename", StripProto(file_->name()));
+ if (HasDescriptorMethods(file_)) {
+ printer->Print(
+ "#include <google/protobuf/descriptor.h>\n"
+ "#include <google/protobuf/reflection_ops.h>\n"
+ "#include <google/protobuf/wire_format.h>\n");
+ }
+
GenerateNamespaceOpeners(printer);
- printer->Print(
- "\n"
- "namespace {\n"
- "\n");
- for (int i = 0; i < file_->message_type_count(); i++) {
- message_generators_[i]->GenerateDescriptorDeclarations(printer);
- }
- for (int i = 0; i < file_->enum_type_count(); i++) {
+ if (HasDescriptorMethods(file_)) {
printer->Print(
- "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
- "name", ClassName(file_->enum_type(i), false));
- }
- for (int i = 0; i < file_->service_count(); i++) {
+ "\n"
+ "namespace {\n"
+ "\n");
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateDescriptorDeclarations(printer);
+ }
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ printer->Print(
+ "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
+ "name", ClassName(file_->enum_type(i), false));
+ }
+ for (int i = 0; i < file_->service_count(); i++) {
+ printer->Print(
+ "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n",
+ "name", file_->service(i)->name());
+ }
+
printer->Print(
- "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n",
- "name", file_->service(i)->name());
+ "\n"
+ "} // namespace\n"
+ "\n");
}
- printer->Print(
- "\n"
- "} // namespace\n"
- "\n");
-
- // Define our externally-visible BuildDescriptors() function.
+ // Define our externally-visible BuildDescriptors() function. (For the lite
+ // library, all this does is initialize default instances.)
GenerateBuildDescriptors(printer);
// Generate enums.
@@ -286,12 +329,14 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
message_generators_[i]->GenerateClassMethods(printer);
}
- // Generate services.
- for (int i = 0; i < file_->service_count(); i++) {
- if (i == 0) printer->Print("\n");
- printer->Print(kThickSeparator);
- printer->Print("\n");
- service_generators_[i]->GenerateImplementation(printer);
+ if (HasDescriptorMethods(file_)) {
+ // Generate services.
+ for (int i = 0; i < file_->service_count(); i++) {
+ if (i == 0) printer->Print("\n");
+ printer->Print(kThickSeparator);
+ printer->Print("\n");
+ service_generators_[i]->GenerateImplementation(printer);
+ }
}
// Define extensions.
@@ -317,80 +362,84 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// anyone calls descriptor() or GetReflection() on one of the types defined
// in the file.
- printer->Print(
- "\n"
- "void $assigndescriptorsname$() {\n",
- "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
- printer->Indent();
-
- // Make sure the file has found its way into the pool. If a descriptor
- // is requested *during* static init then AddDescriptors() may not have
- // been called yet, so we call it manually. Note that it's fine if
- // AddDescriptors() is called multiple times.
- printer->Print(
- "$adddescriptorsname$();\n",
- "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
+ // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
+ // and we only use AddDescriptors() to allocate default instances.
+ if (HasDescriptorMethods(file_)) {
+ printer->Print(
+ "\n"
+ "void $assigndescriptorsname$() {\n",
+ "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
+ printer->Indent();
+
+ // Make sure the file has found its way into the pool. If a descriptor
+ // is requested *during* static init then AddDescriptors() may not have
+ // been called yet, so we call it manually. Note that it's fine if
+ // AddDescriptors() is called multiple times.
+ printer->Print(
+ "$adddescriptorsname$();\n",
+ "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
- // Get the file's descriptor from the pool.
- printer->Print(
- "const ::google::protobuf::FileDescriptor* file =\n"
- " ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n"
- " \"$filename$\");\n"
- // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file"
- // being unused when compiling an empty .proto file.
- "GOOGLE_CHECK(file != NULL);\n",
- "filename", file_->name());
-
- // Go through all the stuff defined in this file and generated code to
- // assign the global descriptor pointers based on the file descriptor.
- for (int i = 0; i < file_->message_type_count(); i++) {
- message_generators_[i]->GenerateDescriptorInitializer(printer, i);
- }
- for (int i = 0; i < file_->enum_type_count(); i++) {
- enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
- }
- for (int i = 0; i < file_->service_count(); i++) {
- service_generators_[i]->GenerateDescriptorInitializer(printer, i);
- }
+ // Get the file's descriptor from the pool.
+ printer->Print(
+ "const ::google::protobuf::FileDescriptor* file =\n"
+ " ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n"
+ " \"$filename$\");\n"
+ // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file"
+ // being unused when compiling an empty .proto file.
+ "GOOGLE_CHECK(file != NULL);\n",
+ "filename", file_->name());
+
+ // Go through all the stuff defined in this file and generated code to
+ // assign the global descriptor pointers based on the file descriptor.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
+ for (int i = 0; i < file_->service_count(); i++) {
+ service_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
- printer->Outdent();
- printer->Print(
- "}\n"
- "\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------
- // protobuf_AssignDescriptorsOnce(): The first time it is called, calls
- // AssignDescriptors(). All later times, waits for the first call to
- // complete and then returns.
- printer->Print(
- "namespace {\n"
- "\n"
- "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n"
- "inline void protobuf_AssignDescriptorsOnce() {\n"
- " ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n"
- " &$assigndescriptorsname$);\n"
- "}\n"
- "\n",
- "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
+ // protobuf_AssignDescriptorsOnce(): The first time it is called, calls
+ // AssignDescriptors(). All later times, waits for the first call to
+ // complete and then returns.
+ printer->Print(
+ "namespace {\n"
+ "\n"
+ "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n"
+ "inline void protobuf_AssignDescriptorsOnce() {\n"
+ " ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n"
+ " &$assigndescriptorsname$);\n"
+ "}\n"
+ "\n",
+ "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
+
+ // protobuf_RegisterTypes(): Calls
+ // MessageFactory::InternalRegisterGeneratedType() for each message type.
+ printer->Print(
+ "void protobuf_RegisterTypes(const ::std::string&) {\n"
+ " protobuf_AssignDescriptorsOnce();\n");
+ printer->Indent();
- // protobuf_RegisterTypes(): Calls
- // MessageFactory::InternalRegisterGeneratedType() for each message type.
- printer->Print(
- "void protobuf_RegisterTypes() {\n"
- " protobuf_AssignDescriptorsOnce();\n");
- printer->Indent();
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateTypeRegistrations(printer);
+ }
- for (int i = 0; i < file_->message_type_count(); i++) {
- message_generators_[i]->GenerateTypeRegistrations(printer);
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n"
+ "} // namespace\n");
}
- printer->Outdent();
- printer->Print(
- "}\n"
- "\n"
- "} // namespace\n");
-
// -----------------------------------------------------------------
// ShutdownFile(): Deletes descriptors, default instances, etc. on shutdown.
@@ -442,32 +491,34 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
"name", GlobalAddDescriptorsName(dependency->name()));
}
- // Embed the descriptor. We simply serialize the entire FileDescriptorProto
- // and embed it as a string literal, which is parsed and built into real
- // descriptors at initialization time.
- FileDescriptorProto file_proto;
- file_->CopyTo(&file_proto);
- string file_data;
- file_proto.SerializeToString(&file_data);
+ if (HasDescriptorMethods(file_)) {
+ // Embed the descriptor. We simply serialize the entire FileDescriptorProto
+ // and embed it as a string literal, which is parsed and built into real
+ // descriptors at initialization time.
+ FileDescriptorProto file_proto;
+ file_->CopyTo(&file_proto);
+ string file_data;
+ file_proto.SerializeToString(&file_data);
- printer->Print(
- "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
+ printer->Print(
+ "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
- // Only write 40 bytes per line.
- static const int kBytesPerLine = 40;
- for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
- printer->Print("\n \"$data$\"",
- "data", CEscape(file_data.substr(i, kBytesPerLine)));
- }
- printer->Print(
- ", $size$);\n",
- "size", SimpleItoa(file_data.size()));
+ // Only write 40 bytes per line.
+ static const int kBytesPerLine = 40;
+ for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+ printer->Print("\n \"$data$\"",
+ "data", CEscape(file_data.substr(i, kBytesPerLine)));
+ }
+ printer->Print(
+ ", $size$);\n",
+ "size", SimpleItoa(file_data.size()));
- // Call MessageFactory::InternalRegisterGeneratedFile().
- printer->Print(
- "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
- " \"$filename$\", &protobuf_RegisterTypes);\n",
- "filename", file_->name());
+ // Call MessageFactory::InternalRegisterGeneratedFile().
+ printer->Print(
+ "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
+ " \"$filename$\", &protobuf_RegisterTypes);\n",
+ "filename", file_->name());
+ }
// Allocate and initialize default instances. This can't be done lazily
// since default instances are returned by simple accessors and are used with
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc
index f3515255..d67d3504 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -42,39 +42,12 @@
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/stubs/strutil.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace cpp {
-namespace {
-
-// Parses a set of comma-delimited name/value pairs, e.g.:
-// "foo=bar,baz,qux=corge"
-// parses to the pairs:
-// ("foo", "bar"), ("baz", ""), ("qux", "corge")
-void ParseOptions(const string& text, vector<pair<string, string> >* output) {
- vector<string> parts;
- SplitStringUsing(text, ",", &parts);
-
- for (int i = 0; i < parts.size(); i++) {
- string::size_type equals_pos = parts[i].find_first_of('=');
- pair<string, string> value;
- if (equals_pos == string::npos) {
- value.first = parts[i];
- value.second = "";
- } else {
- value.first = parts[i].substr(0, equals_pos);
- value.second = parts[i].substr(equals_pos + 1);
- }
- output->push_back(value);
- }
-}
-
-} // namespace
-
CppGenerator::CppGenerator() {}
CppGenerator::~CppGenerator() {}
@@ -83,7 +56,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
OutputDirectory* output_directory,
string* error) const {
vector<pair<string, string> > options;
- ParseOptions(parameter, &options);
+ ParseGeneratorParameter(parameter, &options);
// -----------------------------------------------------------------
// parse generator options
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index 595aeaeb..723a8b45 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -152,7 +152,18 @@ string FieldName(const FieldDescriptor* field) {
string FieldConstantName(const FieldDescriptor *field) {
string field_name = UnderscoresToCamelCase(field->name(), true);
- return "k" + field_name + "FieldNumber";
+ string result = "k" + field_name + "FieldNumber";
+
+ if (!field->is_extension() &&
+ field->containing_type()->FindFieldByCamelcaseName(
+ field->camelcase_name()) != field) {
+ // This field's camelcase name is not unique. As a hack, add the field
+ // number to the constant name. This makes the constant rather useless,
+ // but what can we do?
+ result += "_" + SimpleItoa(field->number());
+ }
+
+ return result;
}
string StripProto(const string& filename) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index 55fd7e29..83e12501 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -37,6 +37,7 @@
#include <string>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
namespace google {
namespace protobuf {
@@ -105,6 +106,34 @@ string GlobalAssignDescriptorsName(const string& filename);
// Return the name of the ShutdownFile() function for a given file.
string GlobalShutdownFileName(const string& filename);
+// Do message classes in this file keep track of unknown fields?
+inline const bool HasUnknownFields(const FileDescriptor *file) {
+ return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
+}
+
+// Does this file have generated parsing, serialization, and other
+// standard methods for which reflection-based fallback implementations exist?
+inline const bool HasGeneratedMethods(const FileDescriptor *file) {
+ return file->options().optimize_for() != FileOptions::CODE_SIZE;
+}
+
+// Do message classes in this file have descriptor and refelction methods?
+inline const bool HasDescriptorMethods(const FileDescriptor *file) {
+ return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
+}
+
+// Should string fields in this file verify that their contents are UTF-8?
+inline const bool HasUtf8Verification(const FileDescriptor* file) {
+ return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
+}
+
+// Should we generate a separate, super-optimized code path for serializing to
+// flat arrays? We don't do this in Lite mode because we'd rather reduce code
+// size.
+inline const bool HasFastArraySerialization(const FileDescriptor* file) {
+ return file->options().optimize_for() == FileOptions::SPEED;
+}
+
} // namespace cpp
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 9852ee91..ae243dd9 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -34,14 +34,17 @@
#include <algorithm>
#include <google/protobuf/stubs/hash.h>
+#include <map>
+#include <vector>
#include <google/protobuf/compiler/cpp/cpp_message.h>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
#include <google/protobuf/compiler/cpp/cpp_enum.h>
#include <google/protobuf/compiler/cpp/cpp_extension.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/wire_format_inl.h>
+#include <google/protobuf/wire_format.h>
#include <google/protobuf/descriptor.pb.h>
namespace google {
@@ -50,6 +53,7 @@ namespace compiler {
namespace cpp {
using internal::WireFormat;
+using internal::WireFormatLite;
namespace {
@@ -196,6 +200,16 @@ GenerateEnumDefinitions(io::Printer* printer) {
}
void MessageGenerator::
+GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+ }
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+ }
+}
+
+void MessageGenerator::
GenerateFieldAccessorDeclarations(io::Printer* printer) {
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
@@ -203,17 +217,16 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) {
PrintFieldComment(printer, field);
map<string, string> vars;
- vars["name"] = FieldName(field);
+ SetCommonFieldVariables(field, &vars);
vars["constant_name"] = FieldConstantName(field);
- vars["number"] = SimpleItoa(field->number());
if (field->is_repeated()) {
- printer->Print(vars, "inline int $name$_size() const;\n");
+ printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
} else {
- printer->Print(vars, "inline bool has_$name$() const;\n");
+ printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
}
- printer->Print(vars, "inline void clear_$name$();\n");
+ printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
printer->Print(vars, "static const int $constant_name$ = $number$;\n");
// Generate type-specific accessor declarations.
@@ -241,9 +254,7 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) {
PrintFieldComment(printer, field);
map<string, string> vars;
- vars["name"] = FieldName(field);
- vars["index"] = SimpleItoa(field->index());
- vars["classname"] = classname_;
+ SetCommonFieldVariables(field, &vars);
// Generate has_$name$() or $name$_size().
if (field->is_repeated()) {
@@ -297,9 +308,11 @@ GenerateClassDefinition(io::Printer* printer) {
} else {
vars["dllexport"] = dllexport_decl_ + " ";
}
+ vars["superclass"] = HasDescriptorMethods(descriptor_->file()) ?
+ "Message" : "MessageLite";
printer->Print(vars,
- "class $dllexport$$classname$ : public ::google::protobuf::Message {\n"
+ "class $dllexport$$classname$ : public ::google::protobuf::$superclass$ {\n"
" public:\n");
printer->Indent();
@@ -313,16 +326,28 @@ GenerateClassDefinition(io::Printer* printer) {
" CopyFrom(from);\n"
" return *this;\n"
"}\n"
- "\n"
- "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
- " return _unknown_fields_;\n"
- "}\n"
- "\n"
- "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
- " return &_unknown_fields_;\n"
- "}\n"
- "\n"
- "static const ::google::protobuf::Descriptor* descriptor();\n"
+ "\n");
+
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
+ " return _unknown_fields_;\n"
+ "}\n"
+ "\n"
+ "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
+ " return &_unknown_fields_;\n"
+ "}\n"
+ "\n");
+ }
+
+ // Only generate this member if it's not disabled.
+ if (HasDescriptorMethods(descriptor_->file()) &&
+ !descriptor_->options().no_standard_descriptor_accessor()) {
+ printer->Print(vars,
+ "static const ::google::protobuf::Descriptor* descriptor();\n");
+ }
+
+ printer->Print(vars,
"static const $classname$& default_instance();\n"
"void Swap($classname$* other);\n"
"\n"
@@ -330,28 +355,29 @@ GenerateClassDefinition(io::Printer* printer) {
"\n"
"$classname$* New() const;\n");
- if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ if (HasGeneratedMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(vars,
+ "void CopyFrom(const ::google::protobuf::Message& from);\n"
+ "void MergeFrom(const ::google::protobuf::Message& from);\n");
+ } else {
+ printer->Print(vars,
+ "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
+ }
+
printer->Print(vars,
- "void CopyFrom(const ::google::protobuf::Message& from);\n"
- "void MergeFrom(const ::google::protobuf::Message& from);\n"
"void CopyFrom(const $classname$& from);\n"
"void MergeFrom(const $classname$& from);\n"
"void Clear();\n"
- "bool IsInitialized() const;\n");
-
- if (!descriptor_->options().message_set_wire_format()) {
- // For message_set_wire_format, we don't generate parsing or
- // serialization code even if optimize_for = SPEED, since MessageSet
- // encoding is somewhat more complicated than normal extension encoding
- // and we'd like to avoid having to implement it in multiple places.
- // WireFormat's implementation is probably good enough.
- printer->Print(vars,
- "\n"
- "int ByteSize() const;\n"
- "bool MergePartialFromCodedStream(\n"
- " ::google::protobuf::io::CodedInputStream* input);\n"
- "void SerializeWithCachedSizes(\n"
- " ::google::protobuf::io::CodedOutputStream* output) const;\n"
+ "bool IsInitialized() const;\n"
+ "\n"
+ "int ByteSize() const;\n"
+ "bool MergePartialFromCodedStream(\n"
+ " ::google::protobuf::io::CodedInputStream* input);\n"
+ "void SerializeWithCachedSizes(\n"
+ " ::google::protobuf::io::CodedOutputStream* output) const;\n");
+ if (HasFastArraySerialization(descriptor_->file())) {
+ printer->Print(
"::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
}
}
@@ -363,10 +389,19 @@ GenerateClassDefinition(io::Printer* printer) {
"void SharedDtor();\n"
"void SetCachedSize(int size) const { _cached_size_ = size; }\n"
"public:\n"
- "\n"
- "const ::google::protobuf::Descriptor* GetDescriptor() const;\n"
- "const ::google::protobuf::Reflection* GetReflection() const;\n"
- "\n"
+ "\n");
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "::google::protobuf::Metadata GetMetadata() const;\n"
+ "\n");
+ } else {
+ printer->Print(
+ "::std::string GetTypeName() const;\n"
+ "\n");
+ }
+
+ printer->Print(
"// nested types ----------------------------------------------------\n"
"\n");
@@ -411,9 +446,13 @@ GenerateClassDefinition(io::Printer* printer) {
"::google::protobuf::internal::ExtensionSet _extensions_;\n");
}
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ "::google::protobuf::UnknownFieldSet _unknown_fields_;\n");
+ }
+
// TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it.
printer->Print(
- "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
"mutable int _cached_size_;\n"
"\n");
for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -431,7 +470,8 @@ GenerateClassDefinition(io::Printer* printer) {
GlobalAddDescriptorsName(descriptor_->file()->name()));
printer->Print(
"friend void $assigndescriptorsname$();\n"
- "friend void $shutdownfilename$();\n",
+ "friend void $shutdownfilename$();\n"
+ "\n",
"assigndescriptorsname",
GlobalAssignDescriptorsName(descriptor_->file()->name()),
"shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
@@ -605,10 +645,15 @@ GenerateDefaultInstanceInitializer(io::Printer* printer) {
void MessageGenerator::
GenerateShutdownCode(io::Printer* printer) {
printer->Print(
- "delete $classname$::default_instance_;\n"
- "delete $classname$_reflection_;\n",
+ "delete $classname$::default_instance_;\n",
"classname", classname_);
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "delete $classname$_reflection_;\n",
+ "classname", classname_);
+ }
+
// Handle nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateShutdownCode(printer);
@@ -655,29 +700,24 @@ GenerateClassMethods(io::Printer* printer) {
GenerateStructors(printer);
printer->Print("\n");
- if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ if (HasGeneratedMethods(descriptor_->file())) {
GenerateClear(printer);
printer->Print("\n");
- if (!descriptor_->options().message_set_wire_format()) {
- // For message_set_wire_format, we don't generate parsing or
- // serialization code even if optimize_for = SPEED, since MessageSet
- // encoding is somewhat more complicated than normal extension encoding
- // and we'd like to avoid having to implement it in multiple places.
- // WireFormat's implementation is probably good enough.
- GenerateMergeFromCodedStream(printer);
- printer->Print("\n");
+ GenerateMergeFromCodedStream(printer);
+ printer->Print("\n");
- GenerateSerializeWithCachedSizes(printer);
- printer->Print("\n");
+ GenerateSerializeWithCachedSizes(printer);
+ printer->Print("\n");
+ if (HasFastArraySerialization(descriptor_->file())) {
GenerateSerializeWithCachedSizesToArray(printer);
printer->Print("\n");
-
- GenerateByteSize(printer);
- printer->Print("\n");
}
+ GenerateByteSize(printer);
+ printer->Print("\n");
+
GenerateMergeFrom(printer);
printer->Print("\n");
@@ -691,16 +731,26 @@ GenerateClassMethods(io::Printer* printer) {
GenerateSwap(printer);
printer->Print("\n");
- printer->Print(
- "const ::google::protobuf::Descriptor* $classname$::GetDescriptor() const {\n"
- " return descriptor();\n"
- "}\n"
- "\n"
- "const ::google::protobuf::Reflection* $classname$::GetReflection() const {\n"
- " protobuf_AssignDescriptorsOnce();\n"
- " return $classname$_reflection_;\n"
- "}\n",
- "classname", classname_);
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
+ " protobuf_AssignDescriptorsOnce();\n"
+ " ::google::protobuf::Metadata metadata;\n"
+ " metadata.descriptor = $classname$_descriptor_;\n"
+ " metadata.reflection = $classname$_reflection_;\n"
+ " return metadata;\n"
+ "}\n"
+ "\n",
+ "classname", classname_);
+ } else {
+ printer->Print(
+ "::std::string $classname$::GetTypeName() const {\n"
+ " return \"$type_name$\";\n"
+ "}\n"
+ "\n",
+ "classname", classname_,
+ "type_name", descriptor_->full_name());
+ }
}
void MessageGenerator::
@@ -724,18 +774,6 @@ GenerateOffsets(io::Printer* printer) {
}
void MessageGenerator::
-GenerateInitializerList(io::Printer* printer) {
- printer->Indent();
- printer->Indent();
-
- printer->Print(
- "::google::protobuf::Message()");
-
- printer->Outdent();
- printer->Outdent();
-}
-
-void MessageGenerator::
GenerateSharedConstructorCode(io::Printer* printer) {
printer->Print(
"void $classname$::SharedCtor() {\n",
@@ -797,17 +835,14 @@ void MessageGenerator::
GenerateStructors(io::Printer* printer) {
// Generate the default constructor.
printer->Print(
- "$classname$::$classname$()\n"
- " : ",
- "classname", classname_);
- GenerateInitializerList(printer);
- printer->Print(" {\n"
+ "$classname$::$classname$() {\n"
" SharedCtor();\n"
- "}\n");
+ "}\n",
+ "classname", classname_);
printer->Print(
"\n"
- "void $classname$::InitAsDefaultInstance() {",
+ "void $classname$::InitAsDefaultInstance() {\n",
"classname", classname_);
// The default instance needs all of its embedded message pointers
@@ -833,15 +868,12 @@ GenerateStructors(io::Printer* printer) {
// Generate the copy constructor.
printer->Print(
- "$classname$::$classname$(const $classname$& from)\n"
- " : ",
- "classname", classname_);
- GenerateInitializerList(printer);
- printer->Print(" {\n"
+ "$classname$::$classname$(const $classname$& from) {\n"
" SharedCtor();\n"
" MergeFrom(from);\n"
"}\n"
- "\n");
+ "\n",
+ "classname", classname_);
// Generate the shared constructor code.
GenerateSharedConstructorCode(printer);
@@ -857,12 +889,21 @@ GenerateStructors(io::Printer* printer) {
// Generate the shared destructor code.
GenerateSharedDestructorCode(printer);
+ // Only generate this member if it's not disabled.
+ if (HasDescriptorMethods(descriptor_->file()) &&
+ !descriptor_->options().no_standard_descriptor_accessor()) {
+ printer->Print(
+ "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
+ " protobuf_AssignDescriptorsOnce();\n"
+ " return $classname$_descriptor_;\n"
+ "}\n"
+ "\n",
+ "classname", classname_,
+ "adddescriptorsname",
+ GlobalAddDescriptorsName(descriptor_->file()->name()));
+ }
+
printer->Print(
- "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
- " protobuf_AssignDescriptorsOnce();\n"
- " return $classname$_descriptor_;\n"
- "}\n"
- "\n"
"const $classname$& $classname$::default_instance() {\n"
" if (default_instance_ == NULL) $adddescriptorsname$();"
" return *default_instance_;\n"
@@ -951,8 +992,12 @@ GenerateClear(io::Printer* printer) {
}
printer->Print(
- "::memset(_has_bits_, 0, sizeof(_has_bits_));\n"
- "mutable_unknown_fields()->Clear();\n");
+ "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
+
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ "mutable_unknown_fields()->Clear();\n");
+ }
printer->Outdent();
printer->Print("}\n");
@@ -967,7 +1012,7 @@ GenerateSwap(io::Printer* printer) {
printer->Print("if (other != this) {\n");
printer->Indent();
- if ( descriptor_->file()->options().optimize_for() == FileOptions::SPEED ) {
+ if (HasGeneratedMethods(descriptor_->file())) {
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
field_generators_.get(field).GenerateSwappingCode(printer);
@@ -978,7 +1023,9 @@ GenerateSwap(io::Printer* printer) {
"i", SimpleItoa(i));
}
- printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
+ }
printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
if (descriptor_->extension_range_count() > 0) {
printer->Print("_extensions_.Swap(&other->_extensions_);\n");
@@ -987,7 +1034,6 @@ GenerateSwap(io::Printer* printer) {
printer->Print("GetReflection()->Swap(this, other);");
}
-
printer->Outdent();
printer->Print("}\n");
printer->Outdent();
@@ -996,31 +1042,42 @@ GenerateSwap(io::Printer* printer) {
void MessageGenerator::
GenerateMergeFrom(io::Printer* printer) {
- // Generate the generalized MergeFrom (aka that which takes in the Message
- // base class as a parameter).
- printer->Print(
- "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
- " GOOGLE_CHECK_NE(&from, this);\n",
- "classname", classname_);
- printer->Indent();
+ if (HasDescriptorMethods(descriptor_->file())) {
+ // Generate the generalized MergeFrom (aka that which takes in the Message
+ // base class as a parameter).
+ printer->Print(
+ "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
+ " GOOGLE_CHECK_NE(&from, this);\n",
+ "classname", classname_);
+ printer->Indent();
- // Cast the message to the proper type. If we find that the message is
- // *not* of the proper type, we can still call Merge via the reflection
- // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
- // for each message.
- printer->Print(
- "const $classname$* source =\n"
- " ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
- " &from);\n"
- "if (source == NULL) {\n"
- " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
- "} else {\n"
- " MergeFrom(*source);\n"
- "}\n",
- "classname", classname_);
+ // Cast the message to the proper type. If we find that the message is
+ // *not* of the proper type, we can still call Merge via the reflection
+ // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
+ // for each message.
+ printer->Print(
+ "const $classname$* source =\n"
+ " ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
+ " &from);\n"
+ "if (source == NULL) {\n"
+ " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
+ "} else {\n"
+ " MergeFrom(*source);\n"
+ "}\n",
+ "classname", classname_);
- printer->Outdent();
- printer->Print("}\n\n");
+ printer->Outdent();
+ printer->Print("}\n\n");
+ } else {
+ // Generate CheckTypeAndMergeFrom().
+ printer->Print(
+ "void $classname$::CheckTypeAndMergeFrom(\n"
+ " const ::google::protobuf::MessageLite& from) {\n"
+ " MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
+ "}\n"
+ "\n",
+ "classname", classname_);
+ }
// Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
printer->Print(
@@ -1082,8 +1139,10 @@ GenerateMergeFrom(io::Printer* printer) {
printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
}
- printer->Print(
- "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
+ }
printer->Outdent();
printer->Print("}\n");
@@ -1091,20 +1150,22 @@ GenerateMergeFrom(io::Printer* printer) {
void MessageGenerator::
GenerateCopyFrom(io::Printer* printer) {
- // Generate the generalized CopyFrom (aka that which takes in the Message
- // base class as a parameter).
- printer->Print(
- "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
- "classname", classname_);
- printer->Indent();
+ if (HasDescriptorMethods(descriptor_->file())) {
+ // Generate the generalized CopyFrom (aka that which takes in the Message
+ // base class as a parameter).
+ printer->Print(
+ "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
+ "classname", classname_);
+ printer->Indent();
- printer->Print(
- "if (&from == this) return;\n"
- "Clear();\n"
- "MergeFrom(from);\n");
+ printer->Print(
+ "if (&from == this) return;\n"
+ "Clear();\n"
+ "MergeFrom(from);\n");
- printer->Outdent();
- printer->Print("}\n\n");
+ printer->Outdent();
+ printer->Print("}\n\n");
+ }
// Generate the class-specific CopyFrom.
printer->Print(
@@ -1123,6 +1184,18 @@ GenerateCopyFrom(io::Printer* printer) {
void MessageGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) {
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ printer->Print(
+ "bool $classname$::MergePartialFromCodedStream(\n"
+ " ::google::protobuf::io::CodedInputStream* input) {\n"
+ " return _extensions_.ParseMessageSet(input, default_instance_,\n"
+ " mutable_unknown_fields());\n"
+ "}\n",
+ "classname", classname_);
+ return;
+ }
+
printer->Print(
"bool $classname$::MergePartialFromCodedStream(\n"
" ::google::protobuf::io::CodedInputStream* input) {\n"
@@ -1144,7 +1217,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
// creates a jump table that is 8x larger and sparser, and meanwhile the
// if()s are highly predictable.
printer->Print(
- "switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) {\n");
+ "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n");
printer->Indent();
@@ -1158,8 +1231,8 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
printer->Print(
"case $number$: {\n"
- " if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=\n"
- " ::google::protobuf::internal::WireFormat::WIRETYPE_$wiretype$) {\n"
+ " if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) !=\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n"
" goto handle_uninterpreted;\n"
" }\n",
"number", SimpleItoa(field->number()),
@@ -1214,8 +1287,8 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
// Is this an end-group tag? If so, this must be the end of the message.
printer->Print(
- "if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) ==\n"
- " ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) {\n"
+ "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
" return true;\n"
"}\n");
@@ -1228,10 +1301,10 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
descriptor_->extension_range(i);
if (i > 0) printer->Print(" ||\n ");
- uint32 start_tag = WireFormat::MakeTag(
- range->start, static_cast<WireFormat::WireType>(0));
- uint32 end_tag = WireFormat::MakeTag(
- range->end, static_cast<WireFormat::WireType>(0));
+ uint32 start_tag = WireFormatLite::MakeTag(
+ range->start, static_cast<WireFormatLite::WireType>(0));
+ uint32 end_tag = WireFormatLite::MakeTag(
+ range->end, static_cast<WireFormatLite::WireType>(0));
if (range->end > FieldDescriptor::kMaxNumber) {
printer->Print(
@@ -1244,17 +1317,29 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
"end", SimpleItoa(end_tag));
}
}
- printer->Print(") {\n"
- " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
- " mutable_unknown_fields()));\n"
+ printer->Print(") {\n");
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
+ " mutable_unknown_fields()));\n");
+ } else {
+ printer->Print(
+ " DO_(_extensions_.ParseField(tag, input, default_instance_));\n");
+ }
+ printer->Print(
" continue;\n"
"}\n");
}
// We really don't recognize this tag. Skip it.
- printer->Print(
- "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
- " input, tag, mutable_unknown_fields()));\n");
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
+ " input, tag, mutable_unknown_fields()));\n");
+ } else {
+ printer->Print(
+ "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n");
+ }
if (descriptor_->field_count() > 0) {
printer->Print("break;\n");
@@ -1319,21 +1404,41 @@ void MessageGenerator::GenerateSerializeOneExtensionRange(
void MessageGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) {
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ printer->Print(
+ "void $classname$::SerializeWithCachedSizes(\n"
+ " ::google::protobuf::io::CodedOutputStream* output) const {\n"
+ " _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
+ "classname", classname_);
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
+ " unknown_fields(), output);\n");
+ }
+ printer->Print(
+ "}\n");
+ return;
+ }
+
printer->Print(
"void $classname$::SerializeWithCachedSizes(\n"
" ::google::protobuf::io::CodedOutputStream* output) const {\n",
"classname", classname_);
printer->Indent();
- printer->Print(
- "::google::protobuf::uint8* raw_buffer = "
- "output->GetDirectBufferForNBytesAndAdvance(_cached_size_);\n"
- "if (raw_buffer != NULL) {\n"
- " $classname$::SerializeWithCachedSizesToArray(raw_buffer);\n"
- " return;\n"
- "}\n"
- "\n",
- "classname", classname_);
+ if (HasFastArraySerialization(descriptor_->file())) {
+ printer->Print(
+ "::google::protobuf::uint8* raw_buffer = "
+ "output->GetDirectBufferForNBytesAndAdvance(_cached_size_);\n"
+ "if (raw_buffer != NULL) {\n"
+ " $classname$::SerializeWithCachedSizesToArray(raw_buffer);\n"
+ " return;\n"
+ "}\n"
+ "\n",
+ "classname", classname_);
+ }
+
GenerateSerializeWithCachedSizesBody(printer, false);
printer->Outdent();
@@ -1343,6 +1448,26 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) {
void MessageGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ printer->Print(
+ "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
+ " ::google::protobuf::uint8* target) const {\n"
+ " target =\n"
+ " _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
+ "classname", classname_);
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ " target = ::google::protobuf::internal::WireFormat::\n"
+ " SerializeUnknownMessageSetItemsToArray(\n"
+ " unknown_fields(), target);\n");
+ }
+ printer->Print(
+ " return target;\n"
+ "}\n");
+ return;
+ }
+
printer->Print(
"::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
" ::google::protobuf::uint8* target) const {\n",
@@ -1389,26 +1514,46 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
}
}
- printer->Print("if (!unknown_fields().empty()) {\n");
- printer->Indent();
- if (to_array) {
- printer->Print(
- "target = "
- "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
- " unknown_fields(), target);\n");
- } else {
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print("if (!unknown_fields().empty()) {\n");
+ printer->Indent();
+ if (to_array) {
+ printer->Print(
+ "target = "
+ "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
+ " unknown_fields(), target);\n");
+ } else {
+ printer->Print(
+ "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
+ " unknown_fields(), output);\n");
+ }
+ printer->Outdent();
+
printer->Print(
- "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
- " unknown_fields(), output);\n");
+ "}\n");
}
- printer->Outdent();
-
- printer->Print(
- "}\n");
}
void MessageGenerator::
GenerateByteSize(io::Printer* printer) {
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ printer->Print(
+ "int $classname$::ByteSize() const {\n"
+ " int total_size = _extensions_.MessageSetByteSize();\n",
+ "classname", classname_);
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ " total_size += ::google::protobuf::internal::WireFormat::\n"
+ " ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
+ }
+ printer->Print(
+ " _cached_size_ = total_size;\n"
+ " return total_size;\n"
+ "}\n");
+ return;
+ }
+
printer->Print(
"int $classname$::ByteSize() const {\n",
"classname", classname_);
@@ -1478,14 +1623,16 @@ GenerateByteSize(io::Printer* printer) {
"\n");
}
- printer->Print("if (!unknown_fields().empty()) {\n");
- printer->Indent();
- printer->Print(
- "total_size +=\n"
- " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
- " unknown_fields());\n");
- printer->Outdent();
- printer->Print("}\n");
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print("if (!unknown_fields().empty()) {\n");
+ printer->Indent();
+ printer->Print(
+ "total_size +=\n"
+ " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
+ " unknown_fields());\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ }
// We update _cached_size_ even though this is a const method. In theory,
// this is not thread-compatible, because concurrent writes have undefined
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h
index 105574a7..f1c57141 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -69,6 +69,10 @@ class MessageGenerator {
// definitions because those classes use the enums definitions).
void GenerateEnumDefinitions(io::Printer* printer);
+ // Generate specializations of GetEnumDescriptor<MyEnum>().
+ // Precondition: in ::google::protobuf namespace.
+ void GenerateGetEnumDescriptorSpecializations(io::Printer* printer);
+
// Generate definitions for this class and all its nested types.
void GenerateClassDefinition(io::Printer* printer);
@@ -125,11 +129,6 @@ class MessageGenerator {
// Generate the shared destructor code.
void GenerateSharedDestructorCode(io::Printer* printer);
- // Generate the member initializer list for the constructors. The member
- // initializer list is shared between the default constructor and the copy
- // constructor.
- void GenerateInitializerList(io::Printer* printer);
-
// Generate standard Message methods.
void GenerateClear(io::Printer* printer);
void GenerateMergeFromCodedStream(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index 2a7eb3f8..059fba6e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -35,7 +35,6 @@
#include <google/protobuf/compiler/cpp/cpp_message_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
-#include <google/protobuf/wire_format_inl.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
@@ -43,22 +42,12 @@ namespace protobuf {
namespace compiler {
namespace cpp {
-using internal::WireFormat;
-
namespace {
-// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
-// repeat code between this and the other field types.
void SetMessageVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
- (*variables)["name"] = FieldName(descriptor);
+ SetCommonFieldVariables(descriptor, variables);
(*variables)["type"] = ClassName(descriptor->message_type(), true);
- (*variables)["index"] = SimpleItoa(descriptor->index());
- (*variables)["number"] = SimpleItoa(descriptor->number());
- (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
- (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
- (*variables)["tag_size"] = SimpleItoa(
- WireFormat::TagSize(descriptor->number(), descriptor->type()));
}
} // namespace
@@ -81,8 +70,8 @@ GeneratePrivateMembers(io::Printer* printer) const {
void MessageFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "inline const $type$& $name$() const;\n"
- "inline $type$* mutable_$name$();\n");
+ "inline const $type$& $name$() const$deprecation$;\n"
+ "inline $type$* mutable_$name$()$deprecation$;\n");
}
void MessageFieldGenerator::
@@ -124,35 +113,35 @@ void MessageFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
printer->Print(variables_,
- "DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(\n"
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
" input, mutable_$name$()));\n");
} else {
printer->Print(variables_,
- "DO_(::google::protobuf::internal::WireFormat::ReadGroupNoVirtual("
- "$number$, input, mutable_$name$()));\n");
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n"
+ " $number$, input, mutable_$name$()));\n");
}
}
void MessageFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::Write$declared_type$NoVirtual("
- "$number$, this->$name$(), output);\n");
+ "::google::protobuf::internal::WireFormatLite::Write$declared_type$NoVirtual(\n"
+ " $number$, this->$name$(), output);\n");
}
void MessageFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
printer->Print(variables_,
- "target = ::google::protobuf::internal::WireFormat::"
- "Write$declared_type$NoVirtualToArray("
- "$number$, this->$name$(), target);\n");
+ "target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$NoVirtualToArray(\n"
+ " $number$, this->$name$(), target);\n");
}
void MessageFieldGenerator::
GenerateByteSize(io::Printer* printer) const {
printer->Print(variables_,
"total_size += $tag_size$ +\n"
- " ::google::protobuf::internal::WireFormat::$declared_type$SizeNoVirtual(\n"
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
" this->$name$());\n");
}
@@ -175,11 +164,13 @@ GeneratePrivateMembers(io::Printer* printer) const {
void RepeatedMessageFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "inline const ::google::protobuf::RepeatedPtrField< $type$ >& $name$() const;\n"
- "inline ::google::protobuf::RepeatedPtrField< $type$ >* mutable_$name$();\n"
- "inline const $type$& $name$(int index) const;\n"
- "inline $type$* mutable_$name$(int index);\n"
- "inline $type$* add_$name$();\n");
+ "inline const ::google::protobuf::RepeatedPtrField< $type$ >& $name$() const"
+ "$deprecation$;\n"
+ "inline ::google::protobuf::RepeatedPtrField< $type$ >* mutable_$name$()"
+ "$deprecation$;\n"
+ "inline const $type$& $name$(int index) const$deprecation$;\n"
+ "inline $type$* mutable_$name$(int index)$deprecation$;\n"
+ "inline $type$* add_$name$()$deprecation$;\n");
}
void RepeatedMessageFieldGenerator::
@@ -228,12 +219,12 @@ void RepeatedMessageFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
printer->Print(variables_,
- "DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(\n"
- " input, add_$name$()));\n");
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
+ " input, add_$name$()));\n");
} else {
printer->Print(variables_,
- "DO_(::google::protobuf::internal::WireFormat::ReadGroupNoVirtual("
- "$number$, input, add_$name$()));\n");
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n"
+ " $number$, input, add_$name$()));\n");
}
}
@@ -241,8 +232,8 @@ void RepeatedMessageFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < this->$name$_size(); i++) {\n"
- " ::google::protobuf::internal::WireFormat::Write$declared_type$NoVirtual("
- "$number$, this->$name$(i), output);\n"
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$NoVirtual(\n"
+ " $number$, this->$name$(i), output);\n"
"}\n");
}
@@ -250,9 +241,9 @@ void RepeatedMessageFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < this->$name$_size(); i++) {\n"
- " target = ::google::protobuf::internal::WireFormat::"
- "Write$declared_type$NoVirtualToArray("
- "$number$, this->$name$(i), target);\n"
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$NoVirtualToArray(\n"
+ " $number$, this->$name$(i), target);\n"
"}\n");
}
@@ -262,7 +253,7 @@ GenerateByteSize(io::Printer* printer) const {
"total_size += $tag_size$ * this->$name$_size();\n"
"for (int i = 0; i < this->$name$_size(); i++) {\n"
" total_size +=\n"
- " ::google::protobuf::internal::WireFormat::$declared_type$SizeNoVirtual(\n"
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
" this->$name$(i));\n"
"}\n");
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
index 44d0b97c..81f5ce07 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -35,7 +35,7 @@
#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
-#include <google/protobuf/wire_format_inl.h>
+#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
@@ -43,7 +43,7 @@ namespace protobuf {
namespace compiler {
namespace cpp {
-using internal::WireFormat;
+using internal::WireFormatLite;
namespace {
@@ -57,14 +57,14 @@ int FixedSize(FieldDescriptor::Type type) {
case FieldDescriptor::TYPE_UINT64 : return -1;
case FieldDescriptor::TYPE_SINT32 : return -1;
case FieldDescriptor::TYPE_SINT64 : return -1;
- case FieldDescriptor::TYPE_FIXED32 : return WireFormat::kFixed32Size;
- case FieldDescriptor::TYPE_FIXED64 : return WireFormat::kFixed64Size;
- case FieldDescriptor::TYPE_SFIXED32: return WireFormat::kSFixed32Size;
- case FieldDescriptor::TYPE_SFIXED64: return WireFormat::kSFixed64Size;
- case FieldDescriptor::TYPE_FLOAT : return WireFormat::kFloatSize;
- case FieldDescriptor::TYPE_DOUBLE : return WireFormat::kDoubleSize;
-
- case FieldDescriptor::TYPE_BOOL : return WireFormat::kBoolSize;
+ case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
+ case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
+ case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
+ case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
+ case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize;
+ case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize;
+
+ case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize;
case FieldDescriptor::TYPE_ENUM : return -1;
case FieldDescriptor::TYPE_STRING : return -1;
@@ -79,20 +79,11 @@ int FixedSize(FieldDescriptor::Type type) {
return -1;
}
-// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
-// repeat code between this and the other field types.
void SetPrimitiveVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
- (*variables)["name"] = FieldName(descriptor);
+ SetCommonFieldVariables(descriptor, variables);
(*variables)["type"] = PrimitiveTypeName(descriptor->cpp_type());
(*variables)["default"] = DefaultValue(descriptor);
- (*variables)["index"] = SimpleItoa(descriptor->index());
- (*variables)["number"] = SimpleItoa(descriptor->number());
- (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
- (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
- (*variables)["tag_size"] = SimpleItoa(
- WireFormat::TagSize(descriptor->number(), descriptor->type()));
-
int fixed_size = FixedSize(descriptor->type());
if (fixed_size != -1) {
(*variables)["fixed_size"] = SimpleItoa(fixed_size);
@@ -119,8 +110,8 @@ GeneratePrivateMembers(io::Printer* printer) const {
void PrimitiveFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "inline $type$ $name$() const;\n"
- "inline void set_$name$($type$ value);\n");
+ "inline $type$ $name$() const$deprecation$;\n"
+ "inline void set_$name$($type$ value)$deprecation$;\n");
}
void PrimitiveFieldGenerator::
@@ -158,7 +149,7 @@ GenerateConstructorCode(io::Printer* printer) const {
void PrimitiveFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
printer->Print(variables_,
- "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$(\n"
+ "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
" input, &$name$_));\n"
"_set_bit($index$);\n");
}
@@ -166,14 +157,14 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
void PrimitiveFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::Write$declared_type$("
+ "::google::protobuf::internal::WireFormatLite::Write$declared_type$("
"$number$, this->$name$(), output);\n");
}
void PrimitiveFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
printer->Print(variables_,
- "target = ::google::protobuf::internal::WireFormat::Write$declared_type$ToArray("
+ "target = ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray("
"$number$, this->$name$(), target);\n");
}
@@ -183,7 +174,7 @@ GenerateByteSize(io::Printer* printer) const {
if (fixed_size == -1) {
printer->Print(variables_,
"total_size += $tag_size$ +\n"
- " ::google::protobuf::internal::WireFormat::$declared_type$Size(\n"
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
" this->$name$());\n");
} else {
printer->Print(variables_,
@@ -205,8 +196,7 @@ void RepeatedPrimitiveFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
printer->Print(variables_,
"::google::protobuf::RepeatedField< $type$ > $name$_;\n");
- if (descriptor_->options().packed() &&
- descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->file())) {
printer->Print(variables_,
"mutable int _$name$_cached_byte_size_;\n");
}
@@ -215,11 +205,12 @@ GeneratePrivateMembers(io::Printer* printer) const {
void RepeatedPrimitiveFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "inline const ::google::protobuf::RepeatedField< $type$ >& $name$() const;\n"
- "inline ::google::protobuf::RepeatedField< $type$ >* mutable_$name$();\n"
- "inline $type$ $name$(int index) const;\n"
- "inline void set_$name$(int index, $type$ value);\n"
- "inline void add_$name$($type$ value);\n");
+ "inline const ::google::protobuf::RepeatedField< $type$ >& $name$() const\n"
+ " $deprecation$;\n"
+ "inline ::google::protobuf::RepeatedField< $type$ >* mutable_$name$()$deprecation$;\n"
+ "inline $type$ $name$(int index) const$deprecation$;\n"
+ "inline void set_$name$(int index, $type$ value)$deprecation$;\n"
+ "inline void add_$name$($type$ value)$deprecation$;\n");
}
void RepeatedPrimitiveFieldGenerator::
@@ -272,12 +263,12 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
printer->Print(variables_,
"::google::protobuf::uint32 length;\n"
"DO_(input->ReadVarint32(&length));\n"
- "::google::protobuf::io::CodedInputStream::Limit limit = "
- "input->PushLimit(length);\n"
+ "::google::protobuf::io::CodedInputStream::Limit limit =\n"
+ " input->PushLimit(length);\n"
"while (input->BytesUntilLimit() > 0) {\n"
" $type$ value;\n"
- " DO_(::google::protobuf::internal::WireFormat::Read$declared_type$("
- "input, &value));\n"
+ " DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
+ " input, &value));\n"
" add_$name$(value);\n"
"}\n"
"input->PopLimit(limit);\n");
@@ -286,8 +277,8 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
} else {
printer->Print(variables_,
"$type$ value;\n"
- "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$("
- "input, &value));\n"
+ "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
+ " input, &value));\n"
"add_$name$(value);\n");
}
}
@@ -298,9 +289,9 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const {
// Write the tag and the size.
printer->Print(variables_,
"if (this->$name$_size() > 0) {\n"
- " ::google::protobuf::internal::WireFormat::WriteTag("
+ " ::google::protobuf::internal::WireFormatLite::WriteTag("
"$number$, "
- "::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED, "
+ "::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, "
"output);\n"
" output->WriteVarint32(_$name$_cached_byte_size_);\n"
"}\n");
@@ -309,12 +300,12 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const {
"for (int i = 0; i < this->$name$_size(); i++) {\n");
if (descriptor_->options().packed()) {
printer->Print(variables_,
- " ::google::protobuf::internal::WireFormat::Write$declared_type$NoTag("
- "this->$name$(i), output);\n");
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$NoTag(\n"
+ " this->$name$(i), output);\n");
} else {
printer->Print(variables_,
- " ::google::protobuf::internal::WireFormat::Write$declared_type$("
- "$number$, this->$name$(i), output);\n");
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
+ " $number$, this->$name$(i), output);\n");
}
printer->Print("}\n");
}
@@ -325,26 +316,24 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
// Write the tag and the size.
printer->Print(variables_,
"if (this->$name$_size() > 0) {\n"
- " target = ::google::protobuf::internal::WireFormat::WriteTagToArray("
- "$number$, "
- "::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED, "
- "target);\n"
- " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray("
- "_$name$_cached_byte_size_, target);\n"
+ " target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
+ " $number$,\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+ " target);\n"
+ " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(\n"
+ " _$name$_cached_byte_size_, target);\n"
"}\n");
}
printer->Print(variables_,
"for (int i = 0; i < this->$name$_size(); i++) {\n");
if (descriptor_->options().packed()) {
printer->Print(variables_,
- " target = ::google::protobuf::internal::WireFormat::"
- "Write$declared_type$NoTagToArray("
- "this->$name$(i), target);\n");
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$NoTagToArray(this->$name$(i), target);\n");
} else {
printer->Print(variables_,
- " target = ::google::protobuf::internal::WireFormat::"
- "Write$declared_type$ToArray("
- "$number$, this->$name$(i), target);\n");
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$ToArray($number$, this->$name$(i), target);\n");
}
printer->Print("}\n");
}
@@ -359,8 +348,8 @@ GenerateByteSize(io::Printer* printer) const {
if (fixed_size == -1) {
printer->Print(variables_,
"for (int i = 0; i < this->$name$_size(); i++) {\n"
- " data_size += ::google::protobuf::internal::WireFormat::$declared_type$Size(\n"
- " this->$name$(i));\n"
+ " data_size += ::google::protobuf::internal::WireFormatLite::\n"
+ " $declared_type$Size(this->$name$(i));\n"
"}\n");
} else {
printer->Print(variables_,
@@ -370,8 +359,8 @@ GenerateByteSize(io::Printer* printer) const {
if (descriptor_->options().packed()) {
printer->Print(variables_,
"if (data_size > 0) {\n"
- " total_size += $tag_size$ + "
- "::google::protobuf::internal::WireFormat::Int32Size(data_size);\n"
+ " total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
"}\n"
"_$name$_cached_byte_size_ = data_size;\n"
"total_size += data_size;\n");
diff --git a/src/google/protobuf/compiler/cpp/cpp_service.cc b/src/google/protobuf/compiler/cpp/cpp_service.cc
index 7689fa13..c2825683 100644
--- a/src/google/protobuf/compiler/cpp/cpp_service.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_service.cc
@@ -249,7 +249,7 @@ void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
sub_vars["input_type"] = ClassName(method->input_type(), true);
sub_vars["output_type"] = ClassName(method->output_type(), true);
- // Note: ::google::protobuf::down_cast does not work here because it only works on pointers,
+ // Note: down_cast does not work here because it only works on pointers,
// not references.
printer->Print(sub_vars,
" case $index$:\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index 05858da4..72258e89 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -35,7 +35,6 @@
#include <google/protobuf/compiler/cpp/cpp_string_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
-#include <google/protobuf/wire_format_inl.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/strutil.h>
@@ -44,23 +43,13 @@ namespace protobuf {
namespace compiler {
namespace cpp {
-using internal::WireFormat;
-
namespace {
-// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
-// repeat code between this and the other field types.
void SetStringVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
- (*variables)["name"] = FieldName(descriptor);
+ SetCommonFieldVariables(descriptor, variables);
(*variables)["default"] =
"\"" + CEscape(descriptor->default_value_string()) + "\"";
- (*variables)["index"] = SimpleItoa(descriptor->index());
- (*variables)["number"] = SimpleItoa(descriptor->number());
- (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
- (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
- (*variables)["tag_size"] = SimpleItoa(
- WireFormat::TagSize(descriptor->number(), descriptor->type()));
(*variables)["pointer_type"] =
descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
}
@@ -111,11 +100,12 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
}
printer->Print(variables_,
- "inline const ::std::string& $name$() const;\n"
- "inline void set_$name$(const ::std::string& value);\n"
- "inline void set_$name$(const char* value);\n"
- "inline void set_$name$(const $pointer_type$* value, size_t size);\n"
- "inline ::std::string* mutable_$name$();\n");
+ "inline const ::std::string& $name$() const$deprecation$;\n"
+ "inline void set_$name$(const ::std::string& value)$deprecation$;\n"
+ "inline void set_$name$(const char* value)$deprecation$;\n"
+ "inline void set_$name$(const $pointer_type$* value, size_t size)"
+ "$deprecation$;\n"
+ "inline ::std::string* mutable_$name$()$deprecation$;\n");
if (descriptor_->options().has_ctype()) {
printer->Outdent();
@@ -221,29 +211,52 @@ GenerateDestructorCode(io::Printer* printer) const {
void StringFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
printer->Print(variables_,
- "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$("
- "input, mutable_$name$()));\n");
+ "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
+ " input, this->mutable_$name$()));\n");
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " this->$name$().data(), this->$name$().length(),\n"
+ " ::google::protobuf::internal::WireFormat::PARSE);\n");
+ }
}
void StringFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " this->$name$().data(), this->$name$().length(),\n"
+ " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
+ }
printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::Write$declared_type$("
- "$number$, this->$name$(), output);\n");
+ "::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
+ " $number$, this->$name$(), output);\n");
}
void StringFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " this->$name$().data(), this->$name$().length(),\n"
+ " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
+ }
printer->Print(variables_,
- "target = ::google::protobuf::internal::WireFormat::Write$declared_type$ToArray("
- "$number$, this->$name$(), target);\n");
+ "target =\n"
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray(\n"
+ " $number$, this->$name$(), target);\n");
}
void StringFieldGenerator::
GenerateByteSize(io::Printer* printer) const {
printer->Print(variables_,
"total_size += $tag_size$ +\n"
- " ::google::protobuf::internal::WireFormat::$declared_type$Size(this->$name$());\n");
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
+ " this->$name$());\n");
}
// ===================================================================
@@ -274,18 +287,22 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
}
printer->Print(variables_,
- "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const;\n"
- "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$();\n"
- "inline const ::std::string& $name$(int index) const;\n"
- "inline ::std::string* mutable_$name$(int index);\n"
- "inline void set_$name$(int index, const ::std::string& value);\n"
- "inline void set_$name$(int index, const char* value);\n"
+ "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const"
+ "$deprecation$;\n"
+ "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()"
+ "$deprecation$;\n"
+ "inline const ::std::string& $name$(int index) const$deprecation$;\n"
+ "inline ::std::string* mutable_$name$(int index)$deprecation$;\n"
+ "inline void set_$name$(int index, const ::std::string& value)$deprecation$;\n"
+ "inline void set_$name$(int index, const char* value)$deprecation$;\n"
"inline "
- "void set_$name$(int index, const $pointer_type$* value, size_t size);\n"
- "inline ::std::string* add_$name$();\n"
- "inline void add_$name$(const ::std::string& value);\n"
- "inline void add_$name$(const char* value);\n"
- "inline void add_$name$(const $pointer_type$* value, size_t size);\n");
+ "void set_$name$(int index, const $pointer_type$* value, size_t size)"
+ "$deprecation$;\n"
+ "inline ::std::string* add_$name$()$deprecation$;\n"
+ "inline void add_$name$(const ::std::string& value)$deprecation$;\n"
+ "inline void add_$name$(const char* value)$deprecation$;\n"
+ "inline void add_$name$(const $pointer_type$* value, size_t size)"
+ "$deprecation$;\n");
if (descriptor_->options().has_ctype()) {
printer->Outdent();
@@ -361,26 +378,48 @@ GenerateConstructorCode(io::Printer* printer) const {
void RepeatedStringFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
printer->Print(variables_,
- "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$(\n"
- " input, add_$name$()));\n");
+ "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
+ " input, this->add_$name$()));\n");
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " this->$name$(0).data(), this->$name$(0).length(),\n"
+ " ::google::protobuf::internal::WireFormat::PARSE);\n");
+ }
}
void RepeatedStringFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
printer->Print(variables_,
- "for (int i = 0; i < this->$name$_size(); i++) {\n"
- " ::google::protobuf::internal::WireFormat::Write$declared_type$("
- "$number$, this->$name$(i), output);\n"
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " this->$name$(i).data(), this->$name$(i).length(),\n"
+ " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
+ }
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
+ " $number$, this->$name$(i), output);\n"
"}\n");
}
void RepeatedStringFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
printer->Print(variables_,
- "for (int i = 0; i < this->$name$_size(); i++) {\n"
- " target = ::google::protobuf::internal::WireFormat::"
- "Write$declared_type$ToArray("
- "$number$, this->$name$(i), target);\n"
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " this->$name$(i).data(), this->$name$(i).length(),\n"
+ " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
+ }
+ printer->Print(variables_,
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$ToArray($number$, this->$name$(i), target);\n"
"}\n");
}
@@ -389,7 +428,7 @@ GenerateByteSize(io::Printer* printer) const {
printer->Print(variables_,
"total_size += $tag_size$ * this->$name$_size();\n"
"for (int i = 0; i < this->$name$_size(); i++) {\n"
- " total_size += ::google::protobuf::internal::WireFormat::$declared_type$Size(\n"
+ " total_size += ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
" this->$name$(i));\n"
"}\n");
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index cabf08fd..2b16e85d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -50,11 +50,9 @@
#include <google/protobuf/unittest_optimize_for.pb.h>
#include <google/protobuf/unittest_embed_optimize_for.pb.h>
#include <google/protobuf/test_util.h>
-#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h>
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
@@ -75,18 +73,6 @@ namespace cpp {
// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
namespace cpp_unittest {
-TEST(ExtremeDefaultValues, FloatingPoint) {
- const unittest::TestExtremeDefaultValues& extreme_default =
- unittest::TestExtremeDefaultValues::default_instance();
-
- EXPECT_EQ(0.0f, extreme_default.zero_float());
- EXPECT_EQ(1.0f, extreme_default.one_float());
- EXPECT_EQ(1.5f, extreme_default.small_float());
- EXPECT_EQ(-1.0f, extreme_default.negative_one_float());
- EXPECT_EQ(-1.5f, extreme_default.negative_float());
- EXPECT_EQ(2.0e8f, extreme_default.large_float());
- EXPECT_EQ(-8e-28f, extreme_default.small_negative_float());
-}
class MockErrorCollector : public MultiFileErrorCollector {
public:
@@ -157,6 +143,19 @@ TEST(GeneratedMessageTest, Defaults) {
&message.optional_import_message());
}
+TEST(GeneratedMessageTest, FloatingPointDefaults) {
+ const unittest::TestExtremeDefaultValues& extreme_default =
+ unittest::TestExtremeDefaultValues::default_instance();
+
+ EXPECT_EQ(0.0f, extreme_default.zero_float());
+ EXPECT_EQ(1.0f, extreme_default.one_float());
+ EXPECT_EQ(1.5f, extreme_default.small_float());
+ EXPECT_EQ(-1.0f, extreme_default.negative_one_float());
+ EXPECT_EQ(-1.5f, extreme_default.negative_float());
+ EXPECT_EQ(2.0e8f, extreme_default.large_float());
+ EXPECT_EQ(-8e-28f, extreme_default.small_negative_float());
+}
+
TEST(GeneratedMessageTest, Accessors) {
// Set every field to a unique value then go back and check all those
// values.
@@ -710,6 +709,32 @@ TEST(GeneratedMessageTest, TestSpaceUsed) {
#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+TEST(GeneratedMessageTest, FieldConstantValues) {
+ unittest::TestRequired message;
+ EXPECT_EQ(unittest::TestAllTypes_NestedMessage::kBbFieldNumber, 1);
+ EXPECT_EQ(unittest::TestAllTypes::kOptionalInt32FieldNumber, 1);
+ EXPECT_EQ(unittest::TestAllTypes::kOptionalgroupFieldNumber, 16);
+ EXPECT_EQ(unittest::TestAllTypes::kOptionalNestedMessageFieldNumber, 18);
+ EXPECT_EQ(unittest::TestAllTypes::kOptionalNestedEnumFieldNumber, 21);
+ EXPECT_EQ(unittest::TestAllTypes::kRepeatedInt32FieldNumber, 31);
+ EXPECT_EQ(unittest::TestAllTypes::kRepeatedgroupFieldNumber, 46);
+ EXPECT_EQ(unittest::TestAllTypes::kRepeatedNestedMessageFieldNumber, 48);
+ EXPECT_EQ(unittest::TestAllTypes::kRepeatedNestedEnumFieldNumber, 51);
+}
+
+TEST(GeneratedMessageTest, ExtensionConstantValues) {
+ EXPECT_EQ(unittest::TestRequired::kSingleFieldNumber, 1000);
+ EXPECT_EQ(unittest::TestRequired::kMultiFieldNumber, 1001);
+ EXPECT_EQ(unittest::kOptionalInt32ExtensionFieldNumber, 1);
+ EXPECT_EQ(unittest::kOptionalgroupExtensionFieldNumber, 16);
+ EXPECT_EQ(unittest::kOptionalNestedMessageExtensionFieldNumber, 18);
+ EXPECT_EQ(unittest::kOptionalNestedEnumExtensionFieldNumber, 21);
+ EXPECT_EQ(unittest::kRepeatedInt32ExtensionFieldNumber, 31);
+ EXPECT_EQ(unittest::kRepeatedgroupExtensionFieldNumber, 46);
+ EXPECT_EQ(unittest::kRepeatedNestedMessageExtensionFieldNumber, 48);
+ EXPECT_EQ(unittest::kRepeatedNestedEnumExtensionFieldNumber, 51);
+}
+
// ===================================================================
TEST(GeneratedEnumTest, EnumValuesAsSwitchCases) {
@@ -803,6 +828,17 @@ TEST(GeneratedEnumTest, Parse) {
EXPECT_FALSE(unittest::TestEnumWithDupValue_Parse("FOO", &dup_value));
}
+TEST(GeneratedEnumTest, GetEnumDescriptor) {
+ EXPECT_EQ(unittest::TestAllTypes::NestedEnum_descriptor(),
+ GetEnumDescriptor<unittest::TestAllTypes::NestedEnum>());
+ EXPECT_EQ(unittest::ForeignEnum_descriptor(),
+ GetEnumDescriptor<unittest::ForeignEnum>());
+ EXPECT_EQ(unittest::TestEnumWithDupValue_descriptor(),
+ GetEnumDescriptor<unittest::TestEnumWithDupValue>());
+ EXPECT_EQ(unittest::TestSparseEnum_descriptor(),
+ GetEnumDescriptor<unittest::TestSparseEnum>());
+}
+
#endif // PROTOBUF_TEST_NO_DESCRIPTORS
// ===================================================================
diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc
index 4aac6493..8ade50c9 100644
--- a/src/google/protobuf/compiler/java/java_enum.cc
+++ b/src/google/protobuf/compiler/java/java_enum.cc
@@ -67,14 +67,17 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
EnumGenerator::~EnumGenerator() {}
void EnumGenerator::Generate(io::Printer* printer) {
- bool is_own_file =
- descriptor_->containing_type() == NULL &&
- descriptor_->file()->options().java_multiple_files();
- printer->Print(
- "public $static$ enum $classname$\n"
- " implements com.google.protobuf.ProtocolMessageEnum {\n",
- "static", is_own_file ? "" : "static",
- "classname", descriptor_->name());
+ 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++) {
@@ -126,63 +129,78 @@ void EnumGenerator::Generate(io::Printer* printer) {
" default: return null;\n"
" }\n"
"}\n"
- "\n");
+ "\n"
+ "public static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
+ " internalGetValueMap() {\n"
+ " return internalValueMap;\n"
+ "}\n"
+ "private static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
+ " 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());
// -----------------------------------------------------------------
// Reflection
- printer->Print(
- "public final com.google.protobuf.Descriptors.EnumValueDescriptor\n"
- " getValueDescriptor() {\n"
- " return getDescriptor().getValues().get(index);\n"
- "}\n"
- "public final com.google.protobuf.Descriptors.EnumDescriptor\n"
- " getDescriptorForType() {\n"
- " return getDescriptor();\n"
- "}\n"
- "public static final com.google.protobuf.Descriptors.EnumDescriptor\n"
- " getDescriptor() {\n");
-
- // TODO(kenton): Cache statically? Note that we can't access descriptors
- // at module init time because it wouldn't work with descriptor.proto, but
- // we can cache the value the first time getDescriptor() is called.
- if (descriptor_->containing_type() == NULL) {
+ if (HasDescriptorMethods(descriptor_)) {
printer->Print(
- " return $file$.getDescriptor().getEnumTypes().get($index$);\n",
- "file", ClassName(descriptor_->file()),
- "index", SimpleItoa(descriptor_->index()));
- } else {
- printer->Print(
- " return $parent$.getDescriptor().getEnumTypes().get($index$);\n",
- "parent", ClassName(descriptor_->containing_type()),
- "index", SimpleItoa(descriptor_->index()));
- }
+ "public final com.google.protobuf.Descriptors.EnumValueDescriptor\n"
+ " getValueDescriptor() {\n"
+ " return getDescriptor().getValues().get(index);\n"
+ "}\n"
+ "public final com.google.protobuf.Descriptors.EnumDescriptor\n"
+ " getDescriptorForType() {\n"
+ " return getDescriptor();\n"
+ "}\n"
+ "public static final com.google.protobuf.Descriptors.EnumDescriptor\n"
+ " getDescriptor() {\n");
+
+ // TODO(kenton): Cache statically? Note that we can't access descriptors
+ // at module init time because it wouldn't work with descriptor.proto, but
+ // we can cache the value the first time getDescriptor() is called.
+ if (descriptor_->containing_type() == NULL) {
+ printer->Print(
+ " return $file$.getDescriptor().getEnumTypes().get($index$);\n",
+ "file", ClassName(descriptor_->file()),
+ "index", SimpleItoa(descriptor_->index()));
+ } else {
+ printer->Print(
+ " return $parent$.getDescriptor().getEnumTypes().get($index$);\n",
+ "parent", ClassName(descriptor_->containing_type()),
+ "index", SimpleItoa(descriptor_->index()));
+ }
- printer->Print(
- "}\n"
- "\n"
- "private static final $classname$[] VALUES = {\n"
- " ",
- "classname", descriptor_->name());
+ printer->Print(
+ "}\n"
+ "\n"
+ "private static final $classname$[] VALUES = {\n"
+ " ",
+ "classname", descriptor_->name());
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ printer->Print("$name$, ",
+ "name", descriptor_->value(i)->name());
+ }
- for (int i = 0; i < descriptor_->value_count(); i++) {
- printer->Print("$name$, ",
- "name", descriptor_->value(i)->name());
+ printer->Print(
+ "\n"
+ "};\n"
+ "public static $classname$ valueOf(\n"
+ " com.google.protobuf.Descriptors.EnumValueDescriptor desc) {\n"
+ " if (desc.getType() != getDescriptor()) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"EnumValueDescriptor is not for this type.\");\n"
+ " }\n"
+ " return VALUES[desc.getIndex()];\n"
+ "}\n",
+ "classname", descriptor_->name());
}
- printer->Print(
- "\n"
- "};\n"
- "public static $classname$ valueOf(\n"
- " com.google.protobuf.Descriptors.EnumValueDescriptor desc) {\n"
- " if (desc.getType() != getDescriptor()) {\n"
- " throw new java.lang.IllegalArgumentException(\n"
- " \"EnumValueDescriptor is not for this type.\");\n"
- " }\n"
- " return VALUES[desc.getIndex()];\n"
- "}\n",
- "classname", descriptor_->name());
-
// -----------------------------------------------------------------
printer->Print(
@@ -194,14 +212,16 @@ void EnumGenerator::Generate(io::Printer* printer) {
"}\n",
"classname", descriptor_->name());
- // Force the static initialization code for the file to run, since it may
- // initialize static variables declared in this class.
- printer->Print(
- "\n"
- "static {\n"
- " $file$.getDescriptor();\n"
- "}\n",
- "file", ClassName(descriptor_->file()));
+ if (HasDescriptorMethods(descriptor_)) {
+ // Force the static initialization code for the file to run, since it may
+ // initialize static variables declared in this class.
+ printer->Print(
+ "\n"
+ "static {\n"
+ " $file$.getDescriptor();\n"
+ "}\n",
+ "file", ClassName(descriptor_->file()));
+ }
printer->Outdent();
printer->Print("}\n\n");
diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc
index 2153042d..dc36e06e 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -39,7 +39,7 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/io/printer.h>
-#include <google/protobuf/wire_format_inl.h>
+#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
@@ -53,18 +53,13 @@ namespace {
// repeat code between this and the other field types.
void SetEnumVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
- const EnumValueDescriptor* default_value;
- default_value = descriptor->default_value_enum();
-
- string type = ClassName(descriptor->enum_type());
-
(*variables)["name"] =
UnderscoresToCamelCase(descriptor);
(*variables)["capitalized_name"] =
UnderscoresToCapitalizedCamelCase(descriptor);
(*variables)["number"] = SimpleItoa(descriptor->number());
- (*variables)["type"] = type;
- (*variables)["default"] = type + "." + default_value->name();
+ (*variables)["type"] = ClassName(descriptor->enum_type());
+ (*variables)["default"] = DefaultValue(descriptor);
(*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
(*variables)["tag_size"] = SimpleItoa(
internal::WireFormat::TagSize(descriptor->number(), descriptor->type()));
@@ -132,10 +127,17 @@ void EnumFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
"int rawValue = input.readEnum();\n"
- "$type$ value = $type$.valueOf(rawValue);\n"
- "if (value == null) {\n"
- " unknownFields.mergeVarintField($number$, rawValue);\n"
- "} else {\n"
+ "$type$ value = $type$.valueOf(rawValue);\n");
+ if (HasUnknownFields(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "if (value == null) {\n"
+ " unknownFields.mergeVarintField($number$, rawValue);\n"
+ "} else {\n");
+ } else {
+ printer->Print(variables_,
+ "if (value != null) {\n");
+ }
+ printer->Print(variables_,
" set$capitalized_name$(value);\n"
"}\n");
}
@@ -185,7 +187,7 @@ GenerateMembers(io::Printer* printer) const {
"}\n");
if (descriptor_->options().packed() &&
- descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ HasGeneratedMethods(descriptor_->containing_type())) {
printer->Print(variables_,
"private int $name$MemoizedSerializedSize;\n");
}
@@ -272,10 +274,17 @@ GenerateParsingCode(io::Printer* printer) const {
// Read and store the enum
printer->Print(variables_,
"int rawValue = input.readEnum();\n"
- "$type$ value = $type$.valueOf(rawValue);\n"
- "if (value == null) {\n"
- " unknownFields.mergeVarintField($number$, rawValue);\n"
- "} else {\n"
+ "$type$ value = $type$.valueOf(rawValue);\n");
+ if (HasUnknownFields(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "if (value == null) {\n"
+ " unknownFields.mergeVarintField($number$, rawValue);\n"
+ "} else {\n");
+ } else {
+ printer->Print(variables_,
+ "if (value != null) {\n");
+ }
+ printer->Print(variables_,
" add$capitalized_name$(value);\n"
"}\n");
diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc
index 302dcea4..4403220b 100644
--- a/src/google/protobuf/compiler/java/java_extension.cc
+++ b/src/google/protobuf/compiler/java/java_extension.cc
@@ -42,6 +42,39 @@ namespace protobuf {
namespace compiler {
namespace java {
+namespace {
+
+const char* TypeName(FieldDescriptor::Type field_type) {
+ switch (field_type) {
+ case FieldDescriptor::TYPE_INT32 : return "INT32";
+ case FieldDescriptor::TYPE_UINT32 : return "UINT32";
+ case FieldDescriptor::TYPE_SINT32 : return "SINT32";
+ case FieldDescriptor::TYPE_FIXED32 : return "FIXED32";
+ case FieldDescriptor::TYPE_SFIXED32: return "SFIXED32";
+ case FieldDescriptor::TYPE_INT64 : return "INT64";
+ case FieldDescriptor::TYPE_UINT64 : return "UINT64";
+ case FieldDescriptor::TYPE_SINT64 : return "SINT64";
+ case FieldDescriptor::TYPE_FIXED64 : return "FIXED64";
+ case FieldDescriptor::TYPE_SFIXED64: return "SFIXED64";
+ case FieldDescriptor::TYPE_FLOAT : return "FLOAT";
+ case FieldDescriptor::TYPE_DOUBLE : return "DOUBLE";
+ case FieldDescriptor::TYPE_BOOL : return "BOOL";
+ case FieldDescriptor::TYPE_STRING : return "STRING";
+ case FieldDescriptor::TYPE_BYTES : return "BYTES";
+ case FieldDescriptor::TYPE_ENUM : return "ENUM";
+ case FieldDescriptor::TYPE_GROUP : return "GROUP";
+ case FieldDescriptor::TYPE_MESSAGE : return "MESSAGE";
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+}
+
ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor)
: descriptor_(descriptor) {
if (descriptor_->extension_scope() != NULL) {
@@ -59,6 +92,7 @@ void ExtensionGenerator::Generate(io::Printer* printer) {
vars["containing_type"] = ClassName(descriptor_->containing_type());
vars["number"] = SimpleItoa(descriptor_->number());
vars["constant_name"] = FieldConstantName(descriptor_);
+ vars["lite"] = HasDescriptorMethods(descriptor_->file()) ? "" : "Lite";
JavaType java_type = GetJavaType(descriptor_);
string singular_type;
@@ -79,13 +113,13 @@ void ExtensionGenerator::Generate(io::Printer* printer) {
if (descriptor_->is_repeated()) {
printer->Print(vars,
"public static\n"
- " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " com.google.protobuf.GeneratedMessage$lite$.GeneratedExtension<\n"
" $containing_type$,\n"
" java.util.List<$type$>> $name$;\n");
} else {
printer->Print(vars,
"public static\n"
- " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " com.google.protobuf.GeneratedMessage$lite$.GeneratedExtension<\n"
" $containing_type$,\n"
" $type$> $name$;\n");
}
@@ -96,34 +130,71 @@ void ExtensionGenerator::GenerateInitializationCode(io::Printer* printer) {
vars["name"] = UnderscoresToCamelCase(descriptor_);
vars["scope"] = scope_;
vars["index"] = SimpleItoa(descriptor_->index());
+ vars["extendee"] = ClassName(descriptor_->containing_type());
+ vars["default"] = descriptor_->is_repeated() ? "" : DefaultValue(descriptor_);
+ vars["number"] = SimpleItoa(descriptor_->number());
+ vars["type_constant"] = TypeName(descriptor_->type());
+ vars["packed"] = descriptor_->options().packed() ? "true" : "false";
+ vars["enum_map"] = "null";
+ vars["prototype"] = "null";
JavaType java_type = GetJavaType(descriptor_);
string singular_type;
switch (java_type) {
case JAVATYPE_MESSAGE:
vars["type"] = ClassName(descriptor_->message_type());
+ vars["prototype"] = ClassName(descriptor_->message_type()) +
+ ".getDefaultInstance()";
break;
case JAVATYPE_ENUM:
vars["type"] = ClassName(descriptor_->enum_type());
+ vars["enum_map"] = ClassName(descriptor_->enum_type()) +
+ ".internalGetValueMap()";
break;
default:
vars["type"] = BoxedPrimitiveTypeName(java_type);
break;
}
- if (descriptor_->is_repeated()) {
- printer->Print(vars,
- "$scope$.$name$ =\n"
- " com.google.protobuf.GeneratedMessage\n"
- " .newRepeatedGeneratedExtension(\n"
- " $scope$.getDescriptor().getExtensions().get($index$),\n"
- " $type$.class);\n");
+ if (HasDescriptorMethods(descriptor_->file())) {
+ if (descriptor_->is_repeated()) {
+ printer->Print(vars,
+ "$scope$.$name$ =\n"
+ " com.google.protobuf.GeneratedMessage\n"
+ " .newRepeatedGeneratedExtension(\n"
+ " $scope$.getDescriptor().getExtensions().get($index$),\n"
+ " $type$.class);\n");
+ } else {
+ printer->Print(vars,
+ "$scope$.$name$ =\n"
+ " com.google.protobuf.GeneratedMessage.newGeneratedExtension(\n"
+ " $scope$.getDescriptor().getExtensions().get($index$),\n"
+ " $type$.class);\n");
+ }
} else {
- printer->Print(vars,
- "$scope$.$name$ =\n"
- " com.google.protobuf.GeneratedMessage.newGeneratedExtension(\n"
- " $scope$.getDescriptor().getExtensions().get($index$),\n"
- " $type$.class);\n");
+ if (descriptor_->is_repeated()) {
+ printer->Print(vars,
+ "$scope$.$name$ =\n"
+ " com.google.protobuf.GeneratedMessageLite\n"
+ " .newRepeatedGeneratedExtension(\n"
+ " $extendee$.getDefaultInstance(),\n"
+ " $prototype$,\n"
+ " $enum_map$,\n"
+ " $number$,\n"
+ " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
+ " $packed$);\n");
+ } else {
+ printer->Print(vars,
+ "$scope$.$name$ =\n"
+ " com.google.protobuf.GeneratedMessageLite\n"
+ " .newGeneratedExtension(\n"
+ " $extendee$.getDefaultInstance(),\n"
+ " $default$,\n"
+ " $prototype$,\n"
+ " $enum_map$,\n"
+ " $number$,\n"
+ " com.google.protobuf.WireFormat.FieldType.$type_constant$);\n");
+ }
}
}
diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc
index 31d75be6..0e170b38 100644
--- a/src/google/protobuf/compiler/java/java_file.cc
+++ b/src/google/protobuf/compiler/java/java_file.cc
@@ -151,7 +151,9 @@ void FileGenerator::Generate(io::Printer* printer) {
printer->Print(
"public static void registerAllExtensions(\n"
- " com.google.protobuf.ExtensionRegistry registry) {\n");
+ " com.google.protobuf.ExtensionRegistry$lite$ registry) {\n",
+ "lite", HasDescriptorMethods(file_) ? "" : "Lite");
+
printer->Indent();
for (int i = 0; i < file_->extension_count(); i++) {
@@ -195,8 +197,42 @@ void FileGenerator::Generate(io::Printer* printer) {
printer->Print("\n");
- // -----------------------------------------------------------------
+ if (HasDescriptorMethods(file_)) {
+ GenerateEmbeddedDescriptor(printer);
+ } else {
+ printer->Print(
+ "static {\n");
+ printer->Indent();
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ // TODO(kenton): Reuse MessageGenerator objects?
+ MessageGenerator(file_->message_type(i))
+ .GenerateStaticVariableInitializers(printer);
+ }
+
+ for (int i = 0; i < file_->extension_count(); i++) {
+ // TODO(kenton): Reuse ExtensionGenerator objects?
+ ExtensionGenerator(file_->extension(i))
+ .GenerateInitializationCode(printer);
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+
+ // Dummy function we can use to force the static initialization block to
+ // run. Needed by inner classes. Cannot be private due to
+ // java_multiple_files option.
+ printer->Print(
+ "\n"
+ "public static void internalForceInit() {}\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) {
// Embed the descriptor. We simply serialize the entire FileDescriptorProto
// and embed it as a string literal, which is parsed and built into real
// descriptors at initialization time. We unfortunately have to put it in
@@ -310,9 +346,6 @@ void FileGenerator::Generate(io::Printer* printer) {
printer->Outdent();
printer->Print(
"}\n");
-
- printer->Outdent();
- printer->Print("}\n");
}
template<typename GeneratorClass, typename DescriptorClass>
diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h
index f1efd011..cb82cea2 100644
--- a/src/google/protobuf/compiler/java/java_file.h
+++ b/src/google/protobuf/compiler/java/java_file.h
@@ -81,6 +81,8 @@ class FileGenerator {
string java_package_;
string classname_;
+ void GenerateEmbeddedDescriptor(io::Printer* printer);
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
};
diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc
index 51af5f0d..8ed3affb 100644
--- a/src/google/protobuf/compiler/java/java_generator.cc
+++ b/src/google/protobuf/compiler/java/java_generator.cc
@@ -45,32 +45,6 @@ namespace protobuf {
namespace compiler {
namespace java {
-namespace {
-
-// Parses a set of comma-delimited name/value pairs, e.g.:
-// "foo=bar,baz,qux=corge"
-// parses to the pairs:
-// ("foo", "bar"), ("baz", ""), ("qux", "corge")
-void ParseOptions(const string& text, vector<pair<string, string> >* output) {
- vector<string> parts;
- SplitStringUsing(text, ",", &parts);
-
- for (int i = 0; i < parts.size(); i++) {
- string::size_type equals_pos = parts[i].find_first_of('=');
- pair<string, string> value;
- if (equals_pos == string::npos) {
- value.first = parts[i];
- value.second = "";
- } else {
- value.first = parts[i].substr(0, equals_pos);
- value.second = parts[i].substr(equals_pos + 1);
- }
- output->push_back(value);
- }
-}
-
-} // namespace
-
JavaGenerator::JavaGenerator() {}
JavaGenerator::~JavaGenerator() {}
@@ -79,7 +53,7 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
OutputDirectory* output_directory,
string* error) const {
vector<pair<string, string> > options;
- ParseOptions(parameter, &options);
+ ParseGeneratorParameter(parameter, &options);
// -----------------------------------------------------------------
// parse generator options
diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc
index 6a107650..dc6748e3 100644
--- a/src/google/protobuf/compiler/java/java_helpers.cc
+++ b/src/google/protobuf/compiler/java/java_helpers.cc
@@ -37,6 +37,7 @@
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
namespace google {
namespace protobuf {
@@ -243,6 +244,72 @@ const char* BoxedPrimitiveTypeName(JavaType type) {
return NULL;
}
+bool AllAscii(const string& text) {
+ for (int i = 0; i < text.size(); i++) {
+ if ((text[i] & 0x80) != 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+string DefaultValue(const FieldDescriptor* field) {
+ // Switch on cpp_type since we need to know which default_value_* method
+ // of FieldDescriptor to call.
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return SimpleItoa(field->default_value_int32());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ // Need to print as a signed int since Java has no unsigned.
+ return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
+ case FieldDescriptor::CPPTYPE_INT64:
+ return SimpleItoa(field->default_value_int64()) + "L";
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
+ "L";
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return SimpleDtoa(field->default_value_double()) + "D";
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return SimpleFtoa(field->default_value_float()) + "F";
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() ? "true" : "false";
+ case FieldDescriptor::CPPTYPE_STRING:
+ if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ if (field->has_default_value()) {
+ // See comments in Internal.java for gory details.
+ return strings::Substitute(
+ "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")",
+ CEscape(field->default_value_string()));
+ } else {
+ return "com.google.protobuf.ByteString.EMPTY";
+ }
+ } else {
+ if (AllAscii(field->default_value_string())) {
+ // All chars are ASCII. In this case CEscape() works fine.
+ return "\"" + CEscape(field->default_value_string()) + "\"";
+ } else {
+ // See comments in Internal.java for gory details.
+ return strings::Substitute(
+ "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
+ CEscape(field->default_value_string()));
+ }
+ }
+
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return ClassName(field->enum_type()) + "." +
+ field->default_value_enum()->name();
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return ClassName(field->message_type()) + ".getDefaultInstance()";
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return "";
+}
+
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h
index de3f883b..f1b643c3 100644
--- a/src/google/protobuf/compiler/java/java_helpers.h
+++ b/src/google/protobuf/compiler/java/java_helpers.h
@@ -36,6 +36,7 @@
#define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
#include <string>
+#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
namespace google {
@@ -115,6 +116,35 @@ inline JavaType GetJavaType(const FieldDescriptor* field) {
// types.
const char* BoxedPrimitiveTypeName(JavaType type);
+string DefaultValue(const FieldDescriptor* field);
+
+// Does this message class keep track of unknown fields?
+inline bool HasUnknownFields(const Descriptor* descriptor) {
+ return descriptor->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME;
+}
+
+// Does this message class have generated parsing, serialization, and other
+// standard methods for which reflection-based fallback implementations exist?
+inline bool HasGeneratedMethods(const Descriptor* descriptor) {
+ return descriptor->file()->options().optimize_for() !=
+ FileOptions::CODE_SIZE;
+}
+
+// Does this message class have descriptor and reflection methods?
+inline bool HasDescriptorMethods(const Descriptor* descriptor) {
+ return descriptor->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME;
+}
+inline bool HasDescriptorMethods(const EnumDescriptor* descriptor) {
+ return descriptor->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME;
+}
+inline bool HasDescriptorMethods(const FileDescriptor* descriptor) {
+ return descriptor->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME;
+}
+
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index c9cbd13f..f79546d6 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -41,7 +41,7 @@
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/wire_format_inl.h>
+#include <google/protobuf/wire_format.h>
#include <google/protobuf/descriptor.pb.h>
namespace google {
@@ -50,6 +50,7 @@ namespace compiler {
namespace java {
using internal::WireFormat;
+using internal::WireFormatLite;
namespace {
@@ -153,38 +154,41 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor)
MessageGenerator::~MessageGenerator() {}
void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
- // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
- // used in the construction of descriptors, we have a tricky bootstrapping
- // problem. To help control static initialization order, we make sure all
- // descriptors and other static data that depends on them are members of
- // the outermost class in the file. This way, they will be initialized in
- // a deterministic order.
-
- map<string, string> vars;
- vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
- vars["index"] = SimpleItoa(descriptor_->index());
- vars["classname"] = ClassName(descriptor_);
- if (descriptor_->containing_type() != NULL) {
- vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type());
- }
- if (descriptor_->file()->options().java_multiple_files()) {
- // We can only make these package-private since the classes that use them
- // are in separate files.
- vars["private"] = "";
- } else {
- vars["private"] = "private ";
- }
+ if (HasDescriptorMethods(descriptor_)) {
+ // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
+ // used in the construction of descriptors, we have a tricky bootstrapping
+ // problem. To help control static initialization order, we make sure all
+ // descriptors and other static data that depends on them are members of
+ // the outermost class in the file. This way, they will be initialized in
+ // a deterministic order.
+
+ map<string, string> vars;
+ vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
+ vars["index"] = SimpleItoa(descriptor_->index());
+ vars["classname"] = ClassName(descriptor_);
+ if (descriptor_->containing_type() != NULL) {
+ vars["parent"] = UniqueFileScopeIdentifier(
+ descriptor_->containing_type());
+ }
+ if (descriptor_->file()->options().java_multiple_files()) {
+ // We can only make these package-private since the classes that use them
+ // are in separate files.
+ vars["private"] = "";
+ } else {
+ vars["private"] = "private ";
+ }
- // The descriptor for this type.
- printer->Print(vars,
- "$private$static com.google.protobuf.Descriptors.Descriptor\n"
- " internal_$identifier$_descriptor;\n");
+ // The descriptor for this type.
+ printer->Print(vars,
+ "$private$static com.google.protobuf.Descriptors.Descriptor\n"
+ " internal_$identifier$_descriptor;\n");
- // And the FieldAccessorTable.
- printer->Print(vars,
- "$private$static\n"
- " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
- " internal_$identifier$_fieldAccessorTable;\n");
+ // And the FieldAccessorTable.
+ printer->Print(vars,
+ "$private$static\n"
+ " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ " internal_$identifier$_fieldAccessorTable;\n");
+ }
// Generate static members for all nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
@@ -196,41 +200,44 @@ void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
void MessageGenerator::GenerateStaticVariableInitializers(
io::Printer* printer) {
- map<string, string> vars;
- vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
- vars["index"] = SimpleItoa(descriptor_->index());
- vars["classname"] = ClassName(descriptor_);
- if (descriptor_->containing_type() != NULL) {
- vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type());
- }
+ if (HasDescriptorMethods(descriptor_)) {
+ map<string, string> vars;
+ vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
+ vars["index"] = SimpleItoa(descriptor_->index());
+ vars["classname"] = ClassName(descriptor_);
+ if (descriptor_->containing_type() != NULL) {
+ vars["parent"] = UniqueFileScopeIdentifier(
+ descriptor_->containing_type());
+ }
- // The descriptor for this type.
- if (descriptor_->containing_type() == NULL) {
- printer->Print(vars,
- "internal_$identifier$_descriptor =\n"
- " getDescriptor().getMessageTypes().get($index$);\n");
- } else {
- printer->Print(vars,
- "internal_$identifier$_descriptor =\n"
- " internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
- }
+ // The descriptor for this type.
+ if (descriptor_->containing_type() == NULL) {
+ printer->Print(vars,
+ "internal_$identifier$_descriptor =\n"
+ " getDescriptor().getMessageTypes().get($index$);\n");
+ } else {
+ printer->Print(vars,
+ "internal_$identifier$_descriptor =\n"
+ " internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
+ }
- // And the FieldAccessorTable.
- printer->Print(vars,
- "internal_$identifier$_fieldAccessorTable = new\n"
- " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n"
- " internal_$identifier$_descriptor,\n"
- " new java.lang.String[] { ");
- for (int i = 0; i < descriptor_->field_count(); i++) {
- printer->Print(
- "\"$field_name$\", ",
- "field_name",
- UnderscoresToCapitalizedCamelCase(descriptor_->field(i)));
+ // And the FieldAccessorTable.
+ printer->Print(vars,
+ "internal_$identifier$_fieldAccessorTable = new\n"
+ " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n"
+ " internal_$identifier$_descriptor,\n"
+ " new java.lang.String[] { ");
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print(
+ "\"$field_name$\", ",
+ "field_name",
+ UnderscoresToCapitalizedCamelCase(descriptor_->field(i)));
+ }
+ printer->Print("},\n"
+ " $classname$.class,\n"
+ " $classname$.Builder.class);\n",
+ "classname", ClassName(descriptor_));
}
- printer->Print("},\n"
- " $classname$.class,\n"
- " $classname$.Builder.class);\n",
- "classname", ClassName(descriptor_));
// Generate static member initializers for all nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
@@ -252,18 +259,35 @@ void MessageGenerator::Generate(io::Printer* printer) {
descriptor_->file()->options().java_multiple_files();
if (descriptor_->extension_range_count() > 0) {
- printer->Print(
- "public $static$ final class $classname$ extends\n"
- " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
- " $classname$> {\n",
- "static", is_own_file ? "" : "static",
- "classname", descriptor_->name());
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public $static$ final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
+ " $classname$> {\n",
+ "static", is_own_file ? "" : "static",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "public $static$ final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
+ " $classname$> {\n",
+ "static", is_own_file ? "" : "static",
+ "classname", descriptor_->name());
+ }
} else {
- printer->Print(
- "public $static$ final class $classname$ extends\n"
- " com.google.protobuf.GeneratedMessage {\n",
- "static", is_own_file ? "" : "static",
- "classname", descriptor_->name());
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public $static$ final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessage {\n",
+ "static", is_own_file ? "" : "static",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "public $static$ final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessageLite {\n",
+ "static", is_own_file ? "" : "static",
+ "classname", descriptor_->name());
+ }
}
printer->Indent();
printer->Print(
@@ -280,20 +304,23 @@ void MessageGenerator::Generate(io::Printer* printer) {
"}\n"
"\n",
"classname", descriptor_->name());
- printer->Print(
- "public static final com.google.protobuf.Descriptors.Descriptor\n"
- " getDescriptor() {\n"
- " return $fileclass$.internal_$identifier$_descriptor;\n"
- "}\n"
- "\n"
- "@Override\n"
- "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
- " internalGetFieldAccessorTable() {\n"
- " return $fileclass$.internal_$identifier$_fieldAccessorTable;\n"
- "}\n"
- "\n",
- "fileclass", ClassName(descriptor_->file()),
- "identifier", UniqueFileScopeIdentifier(descriptor_));
+
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public static final com.google.protobuf.Descriptors.Descriptor\n"
+ " getDescriptor() {\n"
+ " return $fileclass$.internal_$identifier$_descriptor;\n"
+ "}\n"
+ "\n"
+ "@Override\n"
+ "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ " internalGetFieldAccessorTable() {\n"
+ " return $fileclass$.internal_$identifier$_fieldAccessorTable;\n"
+ "}\n"
+ "\n",
+ "fileclass", ClassName(descriptor_->file()),
+ "identifier", UniqueFileScopeIdentifier(descriptor_));
+ }
// Nested types and extensions
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
@@ -318,7 +345,7 @@ void MessageGenerator::Generate(io::Printer* printer) {
printer->Print("\n");
}
- if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ if (HasGeneratedMethods(descriptor_)) {
GenerateIsInitialized(printer);
GenerateMessageSerializationMethods(printer);
}
@@ -326,12 +353,23 @@ void MessageGenerator::Generate(io::Printer* printer) {
GenerateParseFromMethods(printer);
GenerateBuilder(printer);
- // Force the static initialization code for the file to run, since it may
- // initialize static variables declared in this class.
+ if (HasDescriptorMethods(descriptor_)) {
+ // Force the static initialization code for the file to run, since it may
+ // initialize static variables declared in this class.
+ printer->Print(
+ "\n"
+ "static {\n"
+ " $file$.getDescriptor();\n"
+ "}\n",
+ "file", ClassName(descriptor_->file()));
+ }
+
+ // Force initialization of outer class. Otherwise, nested extensions may
+ // not be initialized.
printer->Print(
"\n"
"static {\n"
- " $file$.getDescriptor();\n"
+ " $file$.internalForceInit();\n"
"}\n",
"file", ClassName(descriptor_->file()));
@@ -360,9 +398,18 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
printer->Indent();
if (descriptor_->extension_range_count() > 0) {
- printer->Print(
- "com.google.protobuf.GeneratedMessage.ExtendableMessage\n"
- " .ExtensionWriter extensionWriter = newExtensionWriter();\n");
+ if (descriptor_->options().message_set_wire_format()) {
+ printer->Print(
+ "com.google.protobuf.GeneratedMessage$lite$.ExtendableMessage\n"
+ " .ExtensionWriter extensionWriter =\n"
+ " newMessageSetExtensionWriter();\n",
+ "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite");
+ } else {
+ printer->Print(
+ "com.google.protobuf.GeneratedMessage$lite$.ExtendableMessage\n"
+ " .ExtensionWriter extensionWriter = newExtensionWriter();\n",
+ "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite");
+ }
}
// Merge the fields and the extension ranges, both sorted by field number.
@@ -380,12 +427,14 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
}
}
- if (descriptor_->options().message_set_wire_format()) {
- printer->Print(
- "getUnknownFields().writeAsMessageSetTo(output);\n");
- } else {
- printer->Print(
- "getUnknownFields().writeTo(output);\n");
+ if (HasUnknownFields(descriptor_)) {
+ if (descriptor_->options().message_set_wire_format()) {
+ printer->Print(
+ "getUnknownFields().writeAsMessageSetTo(output);\n");
+ } else {
+ printer->Print(
+ "getUnknownFields().writeTo(output);\n");
+ }
}
printer->Outdent();
@@ -406,16 +455,23 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
}
if (descriptor_->extension_range_count() > 0) {
- printer->Print(
- "size += extensionsSerializedSize();\n");
+ if (descriptor_->options().message_set_wire_format()) {
+ printer->Print(
+ "size += extensionsSerializedSizeAsMessageSet();\n");
+ } else {
+ printer->Print(
+ "size += extensionsSerializedSize();\n");
+ }
}
- if (descriptor_->options().message_set_wire_format()) {
- printer->Print(
- "size += getUnknownFields().getSerializedSizeAsMessageSet();\n");
- } else {
- printer->Print(
- "size += getUnknownFields().getSerializedSize();\n");
+ if (HasUnknownFields(descriptor_)) {
+ if (descriptor_->options().message_set_wire_format()) {
+ printer->Print(
+ "size += getUnknownFields().getSerializedSizeAsMessageSet();\n");
+ } else {
+ printer->Print(
+ "size += getUnknownFields().getSerializedSize();\n");
+ }
}
printer->Outdent();
@@ -439,7 +495,7 @@ GenerateParseFromMethods(io::Printer* printer) {
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.ByteString data,\n"
- " com.google.protobuf.ExtensionRegistry extensionRegistry)\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
" return newBuilder().mergeFrom(data, extensionRegistry)\n"
" .buildParsed();\n"
@@ -450,7 +506,7 @@ GenerateParseFromMethods(io::Printer* printer) {
"}\n"
"public static $classname$ parseFrom(\n"
" byte[] data,\n"
- " com.google.protobuf.ExtensionRegistry extensionRegistry)\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
" return newBuilder().mergeFrom(data, extensionRegistry)\n"
" .buildParsed();\n"
@@ -461,7 +517,7 @@ GenerateParseFromMethods(io::Printer* printer) {
"}\n"
"public static $classname$ parseFrom(\n"
" java.io.InputStream input,\n"
- " com.google.protobuf.ExtensionRegistry extensionRegistry)\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
" return newBuilder().mergeFrom(input, extensionRegistry)\n"
" .buildParsed();\n"
@@ -472,7 +528,7 @@ GenerateParseFromMethods(io::Printer* printer) {
"}\n"
"public static $classname$ parseDelimitedFrom(\n"
" java.io.InputStream input,\n"
- " com.google.protobuf.ExtensionRegistry extensionRegistry)\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
" return newBuilder().mergeDelimitedFrom(input, extensionRegistry)\n"
" .buildParsed();\n"
@@ -484,7 +540,7 @@ GenerateParseFromMethods(io::Printer* printer) {
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input,\n"
- " com.google.protobuf.ExtensionRegistry extensionRegistry)\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
" return newBuilder().mergeFrom(input, extensionRegistry)\n"
" .buildParsed();\n"
@@ -509,32 +565,57 @@ void MessageGenerator::GenerateSerializeOneExtensionRange(
void MessageGenerator::GenerateBuilder(io::Printer* printer) {
printer->Print(
- "public static Builder newBuilder() { return new Builder(); }\n"
- "public Builder newBuilderForType() { return new Builder(); }\n"
+ "public static Builder newBuilder() { return Builder.create(); }\n"
+ "public Builder newBuilderForType() { return newBuilder(); }\n"
"public static Builder newBuilder($classname$ prototype) {\n"
- " return new Builder().mergeFrom(prototype);\n"
+ " return newBuilder().mergeFrom(prototype);\n"
"}\n"
"public Builder toBuilder() { return newBuilder(this); }\n"
"\n",
"classname", ClassName(descriptor_));
if (descriptor_->extension_range_count() > 0) {
- printer->Print(
- "public static final class Builder extends\n"
- " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
- " $classname$, Builder> {\n",
- "classname", ClassName(descriptor_));
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public static final class Builder extends\n"
+ " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
+ " $classname$, Builder> {\n",
+ "classname", ClassName(descriptor_));
+ } else {
+ printer->Print(
+ "public static final class Builder extends\n"
+ " com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<\n"
+ " $classname$, Builder> {\n",
+ "classname", ClassName(descriptor_));
+ }
} else {
- printer->Print(
- "public static final class Builder extends\n"
- " com.google.protobuf.GeneratedMessage.Builder<Builder> {\n",
- "classname", ClassName(descriptor_));
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public static final class Builder extends\n"
+ " com.google.protobuf.GeneratedMessage.Builder<Builder> {\n",
+ "classname", ClassName(descriptor_));
+ } else {
+ printer->Print(
+ "public static final class Builder extends\n"
+ " com.google.protobuf.GeneratedMessageLite.Builder<\n"
+ " $classname$, Builder> {\n",
+ "classname", ClassName(descriptor_));
+ }
}
printer->Indent();
+ // By using a threadlocal queue, we do not have to worry about locking when
+ // accessing the queue. Current JDKs implement this very efficiently, using
+ // no locks themselves to acquire the value when needed.
+ printer->Print(
+ "private static final "
+ " com.google.protobuf.Internal.ThreadLocalQuickQueue<Builder> builders =\n"
+ " new com.google.protobuf.Internal.ThreadLocalQuickQueue<Builder>();\n"
+ "\n");
+
GenerateCommonBuilderMethods(printer);
- if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ if (HasGeneratedMethods(descriptor_)) {
GenerateBuilderParsingMethods(printer);
}
@@ -553,10 +634,19 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) {
void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
printer->Print(
+ "private $classname$ result;\n"
+ "\n"
"// Construct using $classname$.newBuilder()\n"
"private Builder() {}\n"
"\n"
- "$classname$ result = new $classname$();\n"
+ "private static Builder create() {\n"
+ " Builder builder = builders.get().poll();\n"
+ " if (builder == null) {\n"
+ " builder = new Builder();\n"
+ " }\n"
+ " builder.result = new $classname$();\n"
+ " return builder;\n"
+ "}\n"
"\n"
"@Override\n"
"protected $classname$ internalGetResult() {\n"
@@ -565,25 +655,38 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
"\n"
"@Override\n"
"public Builder clear() {\n"
+ " if (result == null) {\n"
+ " throw new IllegalStateException(\n"
+ " \"Cannot call clear() after build().\");\n"
+ " }\n"
" result = new $classname$();\n"
" return this;\n"
"}\n"
"\n"
"@Override\n"
"public Builder clone() {\n"
- " return new Builder().mergeFrom(result);\n"
+ " return create().mergeFrom(result);\n"
"}\n"
- "\n"
- "@Override\n"
- "public com.google.protobuf.Descriptors.Descriptor\n"
- " getDescriptorForType() {\n"
- " return $classname$.getDescriptor();\n"
- "}\n"
- "\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "@Override\n"
+ "public com.google.protobuf.Descriptors.Descriptor\n"
+ " getDescriptorForType() {\n"
+ " return $classname$.getDescriptor();\n"
+ "}\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+ }
+ printer->Print(
"public $classname$ getDefaultInstanceForType() {\n"
" return $classname$.getDefaultInstance();\n"
"}\n"
- "\n",
+ "\n"
+ "public boolean isInitialized() {\n"
+ " return result.isInitialized();\n"
+ "}\n",
"classname", ClassName(descriptor_));
// -----------------------------------------------------------------
@@ -592,8 +695,7 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
"public $classname$ build() {\n"
// If result == null, we'll throw an appropriate exception later.
" if (result != null && !isInitialized()) {\n"
- " throw new com.google.protobuf.UninitializedMessageException(\n"
- " result);\n"
+ " throw newUninitializedMessageException(result);\n"
" }\n"
" return buildPartial();\n"
"}\n"
@@ -601,7 +703,7 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
"private $classname$ buildParsed()\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
" if (!isInitialized()) {\n"
- " throw new com.google.protobuf.UninitializedMessageException(\n"
+ " throw newUninitializedMessageException(\n"
" result).asInvalidProtocolBufferException();\n"
" }\n"
" return buildPartial();\n"
@@ -610,7 +712,7 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
"public $classname$ buildPartial() {\n"
" if (result == null) {\n"
" throw new IllegalStateException(\n"
- " \"build() has already been called on this Builder.\");"
+ " \"build() has already been called on this Builder.\");\n"
" }\n",
"classname", ClassName(descriptor_));
printer->Indent();
@@ -623,6 +725,7 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
printer->Print(
" $classname$ returnMe = result;\n"
" result = null;\n"
+ " builders.get().offer(this);\n"
" return returnMe;\n"
"}\n"
"\n",
@@ -630,18 +733,25 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
// -----------------------------------------------------------------
- if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ if (HasGeneratedMethods(descriptor_)) {
+ // MergeFrom(Message other) requires the ability to distinguish the other
+ // messages type by its descriptor.
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "@Override\n"
+ "public Builder mergeFrom(com.google.protobuf.Message other) {\n"
+ " if (other instanceof $classname$) {\n"
+ " return mergeFrom(($classname$)other);\n"
+ " } else {\n"
+ " super.mergeFrom(other);\n"
+ " return this;\n"
+ " }\n"
+ "}\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+ }
+
printer->Print(
- "@Override\n"
- "public Builder mergeFrom(com.google.protobuf.Message other) {\n"
- " if (other instanceof $classname$) {\n"
- " return mergeFrom(($classname$)other);\n"
- " } else {\n"
- " super.mergeFrom(other);\n"
- " return this;\n"
- " }\n"
- "}\n"
- "\n"
"public Builder mergeFrom($classname$ other) {\n"
// Optimization: If other is the default instance, we know none of its
// fields are set so we can skip the merge.
@@ -661,8 +771,12 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
" this.mergeExtensionFields(other);\n");
}
+ if (HasUnknownFields(descriptor_)) {
+ printer->Print(
+ " this.mergeUnknownFields(other.getUnknownFields());\n");
+ }
+
printer->Print(
- " this.mergeUnknownFields(other.getUnknownFields());\n"
" return this;\n"
"}\n"
"\n");
@@ -678,23 +792,19 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
printer->Print(
"@Override\n"
"public Builder mergeFrom(\n"
- " com.google.protobuf.CodedInputStream input)\n"
- " throws java.io.IOException {\n"
- " return mergeFrom(input,\n"
- " com.google.protobuf.ExtensionRegistry.getEmptyRegistry());\n"
- "}\n"
- "\n"
- "@Override\n"
- "public Builder mergeFrom(\n"
" com.google.protobuf.CodedInputStream input,\n"
- " com.google.protobuf.ExtensionRegistry extensionRegistry)\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n");
printer->Indent();
+ if (HasUnknownFields(descriptor_)) {
+ printer->Print(
+ "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
+ " com.google.protobuf.UnknownFieldSet.newBuilder(\n"
+ " this.getUnknownFields());\n");
+ }
+
printer->Print(
- "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
- " com.google.protobuf.UnknownFieldSet.newBuilder(\n"
- " this.getUnknownFields());\n"
"while (true) {\n");
printer->Indent();
@@ -703,22 +813,34 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
"switch (tag) {\n");
printer->Indent();
- printer->Print(
- "case 0:\n" // zero signals EOF / limit reached
- " this.setUnknownFields(unknownFields.build());\n"
- " return this;\n"
- "default: {\n"
- " if (!parseUnknownField(input, unknownFields,\n"
- " extensionRegistry, tag)) {\n"
- " this.setUnknownFields(unknownFields.build());\n"
- " return this;\n" // it's an endgroup tag
- " }\n"
- " break;\n"
- "}\n");
+ if (HasUnknownFields(descriptor_)) {
+ printer->Print(
+ "case 0:\n" // zero signals EOF / limit reached
+ " this.setUnknownFields(unknownFields.build());\n"
+ " return this;\n"
+ "default: {\n"
+ " if (!parseUnknownField(input, unknownFields,\n"
+ " extensionRegistry, tag)) {\n"
+ " this.setUnknownFields(unknownFields.build());\n"
+ " return this;\n" // it's an endgroup tag
+ " }\n"
+ " break;\n"
+ "}\n");
+ } else {
+ printer->Print(
+ "case 0:\n" // zero signals EOF / limit reached
+ " return this;\n"
+ "default: {\n"
+ " if (!parseUnknownField(input, extensionRegistry, tag)) {\n"
+ " return this;\n" // it's an endgroup tag
+ " }\n"
+ " break;\n"
+ "}\n");
+ }
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = sorted_fields[i];
- uint32 tag = WireFormat::MakeTag(field->number(),
+ uint32 tag = WireFormatLite::MakeTag(field->number(),
WireFormat::WireTypeForField(field));
printer->Print(
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
index 798e8608..327c2053 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -39,9 +39,8 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/io/printer.h>
-#include <google/protobuf/wire_format_inl.h>
+#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/substitute.h>
namespace google {
namespace protobuf {
@@ -49,6 +48,7 @@ namespace compiler {
namespace java {
using internal::WireFormat;
+using internal::WireFormatLite;
namespace {
@@ -121,16 +121,6 @@ const char* GetCapitalizedType(const FieldDescriptor* field) {
return NULL;
}
-bool AllPrintableAscii(const string& text) {
- // Cannot use isprint() because it's locale-specific. :(
- for (int i = 0; i < text.size(); i++) {
- if ((text[i] < 0x20) || text[i] >= 0x7F) {
- return false;
- }
- }
- return true;
-}
-
// For encodings with fixed sizes, returns that size in bytes. Otherwise
// returns -1.
int FixedSize(FieldDescriptor::Type type) {
@@ -141,14 +131,14 @@ int FixedSize(FieldDescriptor::Type type) {
case FieldDescriptor::TYPE_UINT64 : return -1;
case FieldDescriptor::TYPE_SINT32 : return -1;
case FieldDescriptor::TYPE_SINT64 : return -1;
- case FieldDescriptor::TYPE_FIXED32 : return WireFormat::kFixed32Size;
- case FieldDescriptor::TYPE_FIXED64 : return WireFormat::kFixed64Size;
- case FieldDescriptor::TYPE_SFIXED32: return WireFormat::kSFixed32Size;
- case FieldDescriptor::TYPE_SFIXED64: return WireFormat::kSFixed64Size;
- case FieldDescriptor::TYPE_FLOAT : return WireFormat::kFloatSize;
- case FieldDescriptor::TYPE_DOUBLE : return WireFormat::kDoubleSize;
-
- case FieldDescriptor::TYPE_BOOL : return WireFormat::kBoolSize;
+ case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
+ case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
+ case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
+ case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
+ case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize;
+ case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize;
+
+ case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize;
case FieldDescriptor::TYPE_ENUM : return -1;
case FieldDescriptor::TYPE_STRING : return -1;
@@ -163,64 +153,6 @@ int FixedSize(FieldDescriptor::Type type) {
return -1;
}
-string DefaultValue(const FieldDescriptor* field) {
- // Switch on cpp_type since we need to know which default_value_* method
- // of FieldDescriptor to call.
- switch (field->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
- return SimpleItoa(field->default_value_int32());
- case FieldDescriptor::CPPTYPE_UINT32:
- // Need to print as a signed int since Java has no unsigned.
- return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
- case FieldDescriptor::CPPTYPE_INT64:
- return SimpleItoa(field->default_value_int64()) + "L";
- case FieldDescriptor::CPPTYPE_UINT64:
- return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
- "L";
- case FieldDescriptor::CPPTYPE_DOUBLE:
- return SimpleDtoa(field->default_value_double()) + "D";
- case FieldDescriptor::CPPTYPE_FLOAT:
- return SimpleFtoa(field->default_value_float()) + "F";
- case FieldDescriptor::CPPTYPE_BOOL:
- return field->default_value_bool() ? "true" : "false";
- case FieldDescriptor::CPPTYPE_STRING: {
- bool isBytes = field->type() == FieldDescriptor::TYPE_BYTES;
-
- if (!isBytes && AllPrintableAscii(field->default_value_string())) {
- // All chars are ASCII and printable. In this case CEscape() works
- // fine (it will only escape quotes and backslashes).
- // Note: If this "optimization" is removed, DescriptorProtos will
- // no longer be able to initialize itself due to bootstrapping
- // problems.
- return "\"" + CEscape(field->default_value_string()) + "\"";
- }
-
- if (isBytes && !field->has_default_value()) {
- return "com.google.protobuf.ByteString.EMPTY";
- }
-
- // Escaping strings correctly for Java and generating efficient
- // initializers for ByteStrings are both tricky. We can sidestep the
- // whole problem by just grabbing the default value from the descriptor.
- return strings::Substitute(
- "(($0) $1.getDescriptor().getFields().get($2).getDefaultValue())",
- isBytes ? "com.google.protobuf.ByteString" : "java.lang.String",
- ClassName(field->containing_type()), field->index());
- }
-
- case FieldDescriptor::CPPTYPE_ENUM:
- case FieldDescriptor::CPPTYPE_MESSAGE:
- GOOGLE_LOG(FATAL) << "Can't get here.";
- return "";
-
- // No default because we want the compiler to complain if any new
- // types are added.
- }
-
- GOOGLE_LOG(FATAL) << "Can't get here.";
- return "";
-}
-
void SetPrimitiveVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
(*variables)["name"] =
@@ -285,8 +217,17 @@ GenerateBuilderMembers(io::Printer* printer) const {
" return this;\n"
"}\n"
"public Builder clear$capitalized_name$() {\n"
- " result.has$capitalized_name$ = false;\n"
- " result.$name$_ = $default$;\n"
+ " result.has$capitalized_name$ = false;\n");
+ if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ // The default value is not a simple literal so we want to avoid executing
+ // it multiple times. Instead, get the default out of the default instance.
+ printer->Print(variables_,
+ " result.$name$_ = getDefaultInstance().get$capitalized_name$();\n");
+ } else {
+ printer->Print(variables_,
+ " result.$name$_ = $default$;\n");
+ }
+ printer->Print(variables_,
" return this;\n"
"}\n");
}
@@ -355,7 +296,7 @@ GenerateMembers(io::Printer* printer) const {
"}\n");
if (descriptor_->options().packed() &&
- descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ HasGeneratedMethods(descriptor_->containing_type())) {
printer->Print(variables_,
"private int $name$MemoizedSerializedSize;\n");
}
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index e9e01545..02304d6d 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -661,7 +661,7 @@ bool Parser::ParseOptionAssignment(Message* options) {
GOOGLE_CHECK(uninterpreted_option_field != NULL)
<< "No field named \"uninterpreted_option\" in the Options proto.";
- UninterpretedOption* uninterpreted_option = ::google::protobuf::down_cast<UninterpretedOption*>(
+ UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>(
options->GetReflection()->AddMessage(options,
uninterpreted_option_field));