From 80b1d62bfcea65c59e2160da71dad84b1bd19cef Mon Sep 17 00:00:00 2001 From: "kenton@google.com" Date: Wed, 29 Jul 2009 01:13:20 +0000 Subject: Submit recent changes from internal branch, including "lite mode" for C++ and Java. See CHANGES.txt for more details. --- src/google/protobuf/compiler/code_generator.cc | 22 + src/google/protobuf/compiler/code_generator.h | 11 + src/google/protobuf/compiler/cpp/cpp_enum.cc | 79 +- src/google/protobuf/compiler/cpp/cpp_enum.h | 4 + src/google/protobuf/compiler/cpp/cpp_enum_field.cc | 107 +- src/google/protobuf/compiler/cpp/cpp_extension.cc | 1 + src/google/protobuf/compiler/cpp/cpp_field.cc | 19 + src/google/protobuf/compiler/cpp/cpp_field.h | 10 + src/google/protobuf/compiler/cpp/cpp_file.cc | 315 ++-- src/google/protobuf/compiler/cpp/cpp_generator.cc | 29 +- src/google/protobuf/compiler/cpp/cpp_helpers.cc | 13 +- src/google/protobuf/compiler/cpp/cpp_helpers.h | 29 + src/google/protobuf/compiler/cpp/cpp_message.cc | 523 +++--- src/google/protobuf/compiler/cpp/cpp_message.h | 9 +- .../protobuf/compiler/cpp/cpp_message_field.cc | 67 +- .../protobuf/compiler/cpp/cpp_primitive_field.cc | 111 +- src/google/protobuf/compiler/cpp/cpp_service.cc | 2 +- .../protobuf/compiler/cpp/cpp_string_field.cc | 129 +- src/google/protobuf/compiler/cpp/cpp_unittest.cc | 64 +- src/google/protobuf/compiler/java/java_enum.cc | 148 +- .../protobuf/compiler/java/java_enum_field.cc | 43 +- .../protobuf/compiler/java/java_extension.cc | 99 +- src/google/protobuf/compiler/java/java_file.cc | 43 +- src/google/protobuf/compiler/java/java_file.h | 2 + .../protobuf/compiler/java/java_generator.cc | 28 +- src/google/protobuf/compiler/java/java_helpers.cc | 67 + src/google/protobuf/compiler/java/java_helpers.h | 30 + src/google/protobuf/compiler/java/java_message.cc | 478 ++++-- .../protobuf/compiler/java/java_primitive_field.cc | 103 +- src/google/protobuf/compiler/parser.cc | 2 +- src/google/protobuf/descriptor.cc | 80 +- src/google/protobuf/descriptor.pb.cc | 1739 ++++++++++++-------- src/google/protobuf/descriptor.pb.h | 197 ++- src/google/protobuf/descriptor.proto | 11 +- src/google/protobuf/descriptor_unittest.cc | 145 ++ src/google/protobuf/dynamic_message.cc | 84 +- src/google/protobuf/extension_set.cc | 730 ++++---- src/google/protobuf/extension_set.h | 144 +- src/google/protobuf/extension_set_heavy.cc | 218 +++ .../protobuf/generated_message_reflection.cc | 301 +++- src/google/protobuf/generated_message_reflection.h | 22 +- src/google/protobuf/generated_message_util.cc | 44 + src/google/protobuf/generated_message_util.h | 65 + src/google/protobuf/io/coded_stream.cc | 96 +- src/google/protobuf/io/coded_stream.h | 46 + src/google/protobuf/io/gzip_stream.cc | 7 +- src/google/protobuf/io/gzip_stream.h | 6 +- src/google/protobuf/io/tokenizer.cc | 2 +- src/google/protobuf/io/tokenizer_unittest.cc | 1 + src/google/protobuf/io/zero_copy_stream_impl.cc | 345 ---- src/google/protobuf/io/zero_copy_stream_impl.h | 280 +--- .../protobuf/io/zero_copy_stream_impl_lite.cc | 393 +++++ .../protobuf/io/zero_copy_stream_impl_lite.h | 338 ++++ .../protobuf/io/zero_copy_stream_unittest.cc | 1 + src/google/protobuf/lite_unittest.cc | 112 ++ src/google/protobuf/message.cc | 188 +-- src/google/protobuf/message.h | 205 +-- src/google/protobuf/message_lite.cc | 282 ++++ src/google/protobuf/message_lite.h | 237 +++ src/google/protobuf/message_unittest.cc | 30 - src/google/protobuf/repeated_field.cc | 49 +- src/google/protobuf/repeated_field.h | 687 ++++---- src/google/protobuf/stubs/common.h | 32 +- src/google/protobuf/test_util.cc | 12 +- src/google/protobuf/test_util.h | 3 +- src/google/protobuf/test_util_lite.cc | 1502 +++++++++++++++++ src/google/protobuf/test_util_lite.h | 101 ++ src/google/protobuf/text_format.cc | 64 +- src/google/protobuf/text_format.h | 12 + src/google/protobuf/text_format_unittest.cc | 120 +- src/google/protobuf/unittest_custom_options.proto | 2 + src/google/protobuf/unittest_import_lite.proto | 49 + src/google/protobuf/unittest_lite.proto | 312 ++++ .../protobuf/unittest_lite_imports_nonlite.proto | 43 + src/google/protobuf/wire_format.cc | 306 ++-- src/google/protobuf/wire_format.h | 436 +---- src/google/protobuf/wire_format_inl.h | 687 -------- src/google/protobuf/wire_format_lite.cc | 193 +++ src/google/protobuf/wire_format_lite.h | 558 +++++++ src/google/protobuf/wire_format_lite_inl.h | 657 ++++++++ src/google/protobuf/wire_format_unittest.cc | 63 +- 81 files changed, 10002 insertions(+), 4822 deletions(-) create mode 100644 src/google/protobuf/extension_set_heavy.cc create mode 100644 src/google/protobuf/generated_message_util.cc create mode 100644 src/google/protobuf/generated_message_util.h create mode 100644 src/google/protobuf/io/zero_copy_stream_impl_lite.cc create mode 100644 src/google/protobuf/io/zero_copy_stream_impl_lite.h create mode 100644 src/google/protobuf/lite_unittest.cc create mode 100644 src/google/protobuf/message_lite.cc create mode 100644 src/google/protobuf/message_lite.h create mode 100644 src/google/protobuf/test_util_lite.cc create mode 100644 src/google/protobuf/test_util_lite.h create mode 100644 src/google/protobuf/unittest_import_lite.proto create mode 100644 src/google/protobuf/unittest_lite.proto create mode 100644 src/google/protobuf/unittest_lite_imports_nonlite.proto delete mode 100644 src/google/protobuf/wire_format_inl.h create mode 100644 src/google/protobuf/wire_format_lite.cc create mode 100644 src/google/protobuf/wire_format_lite.h create mode 100644 src/google/protobuf/wire_format_lite_inl.h (limited to 'src/google') 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 +#include + 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 >* output) { + vector parts; + SplitStringUsing(text, ",", &parts); + + for (int i = 0; i < parts.size(); i++) { + string::size_type equals_pos = parts[i].find_first_of('='); + pair 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 #include +#include +#include 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 >*); + } // 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 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(). + // 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 #include #include -#include +#include #include 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* 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 $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& $name$() const;\n" - "inline ::google::protobuf::RepeatedField* 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& $name$() const$deprecation$;\n" + "inline ::google::protobuf::RepeatedField* 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 +#include #include #include #include #include #include +#include #include +#include namespace google { namespace protobuf { namespace compiler { namespace cpp { +using internal::WireFormat; + +void SetCommonFieldVariables(const FieldDescriptor* descriptor, + map* 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 +#include + #include #include @@ -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* 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 \n" + "#include \n" "#include \n" "#include \n"); - if (file_->service_count() > 0) { + if (HasDescriptorMethods(file_)) { printer->Print( - "#include \n"); + "#include \n"); + + if (file_->service_count() > 0) { + printer->Print( + "#include \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(); } + // 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 \n" - "#include \n" "#include \n" - "#include \n" - "#include \n", + "#include \n", "basename", StripProto(file_->name())); + if (HasDescriptorMethods(file_)) { + printer->Print( + "#include \n" + "#include \n" + "#include \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 #include #include -#include 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 >* output) { - vector parts; - SplitStringUsing(text, ",", &parts); - - for (int i = 0; i < parts.size(); i++) { - string::size_type equals_pos = parts[i].find_first_of('='); - pair 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 > 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 #include +#include 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 #include +#include +#include #include +#include #include #include #include #include #include #include -#include +#include #include namespace google { @@ -50,6 +53,7 @@ namespace compiler { namespace cpp { using internal::WireFormat; +using internal::WireFormatLite; namespace { @@ -195,6 +199,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++) { @@ -203,17 +217,16 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { PrintFieldComment(printer, field); map 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 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 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:: @@ -723,18 +773,6 @@ GenerateOffsets(io::Printer* printer) { printer->Print("};\n"); } -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( @@ -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(\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(\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(&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(0)); - uint32 end_tag = WireFormat::MakeTag( - range->end, static_cast(0)); + uint32 start_tag = WireFormatLite::MakeTag( + range->start, static_cast(0)); + uint32 end_tag = WireFormatLite::MakeTag( + range->end, static_cast(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(). + // 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 #include #include -#include #include 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* 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 #include #include -#include +#include #include 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* 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 #include #include -#include #include #include @@ -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* 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 #include #include -#include #include #include #include -#include #include #include #include @@ -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()); + EXPECT_EQ(unittest::ForeignEnum_descriptor(), + GetEnumDescriptor()); + EXPECT_EQ(unittest::TestEnumWithDupValue_descriptor(), + GetEnumDescriptor()); + EXPECT_EQ(unittest::TestSparseEnum_descriptor(), + GetEnumDescriptor()); +} + #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 #include #include -#include +#include #include namespace google { @@ -53,18 +53,13 @@ namespace { // repeat code between this and the other field types. void SetEnumVariables(const FieldDescriptor* descriptor, map* 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 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 >* output) { - vector parts; - SplitStringUsing(text, ",", &parts); - - for (int i = 0; i < parts.size(); i++) { - string::size_type equals_pos = parts[i].find_first_of('='); - pair 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 > 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 #include #include +#include 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(field->default_value_uint32())); + case FieldDescriptor::CPPTYPE_INT64: + return SimpleItoa(field->default_value_int64()) + "L"; + case FieldDescriptor::CPPTYPE_UINT64: + return SimpleItoa(static_cast(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 +#include #include 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 #include #include -#include +#include #include 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 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 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 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 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 {\n", - "classname", ClassName(descriptor_)); + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public static final class Builder extends\n" + " com.google.protobuf.GeneratedMessage.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 builders =\n" + " new com.google.protobuf.Internal.ThreadLocalQuickQueue();\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"); @@ -676,25 +790,21 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { SortFieldsByNumber(descriptor_)); 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 #include #include -#include +#include #include -#include 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(field->default_value_uint32())); - case FieldDescriptor::CPPTYPE_INT64: - return SimpleItoa(field->default_value_int64()) + "L"; - case FieldDescriptor::CPPTYPE_UINT64: - return SimpleItoa(static_cast(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* 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* uninterpreted_option = down_cast( options->GetReflection()->AddMessage(options, uninterpreted_option_field)); diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index dd7f28c8..f82a3450 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -798,7 +798,7 @@ namespace { EncodedDescriptorDatabase* generated_database_ = NULL; DescriptorPool* generated_pool_ = NULL; -GOOGLE_PROTOBUF_DECLARE_ONCE(generated_pool_init_); +GoogleOnceType generated_pool_init_; void DeleteGeneratedPool() { delete generated_database_; @@ -814,7 +814,7 @@ void InitGeneratedPool() { } inline void InitGeneratedPoolOnce() { - GoogleOnceInit(&generated_pool_init_, &InitGeneratedPool); + ::google::protobuf::GoogleOnceInit(&generated_pool_init_, &InitGeneratedPool); } } // anonymous namespace @@ -1859,7 +1859,11 @@ class DescriptorBuilder { // dependency of this file, it will fail, but will set // possible_undeclared_dependency_ to point at that file. This is only used // by AddNotDefinedError() to report a more useful error message. + // possible_undeclared_dependency_name_ is the name of the symbol that was + // actually found in possible_undeclared_dependency_, which may be a parent + // of the symbol actually looked for. const FileDescriptor* possible_undeclared_dependency_; + string possible_undeclared_dependency_name_; void AddError(const string& element_name, const Message& descriptor, @@ -2062,7 +2066,7 @@ class DescriptorBuilder { Message* options); // A recursive helper function that drills into the intermediate fields - // in unknown_fields to check if field #field_number is set on the + // in unknown_fields to check if field innermost_field is set on the // innermost message. Returns false and sets an error if so. bool ExamineIfOptionIsSet( vector::const_iterator intermediate_fields_iter, @@ -2233,8 +2237,9 @@ void DescriptorBuilder::AddNotDefinedError( "\"" + undefined_symbol + "\" is not defined."); } else { AddError(element_name, descriptor, location, - "\"" + undefined_symbol + "\" seems to be defined in \"" - + possible_undeclared_dependency_->name() + "\", which is not " + "\"" + possible_undeclared_dependency_name_ + + "\" seems to be defined in \"" + + possible_undeclared_dependency_->name() + "\", which is not " "imported by \"" + filename_ + "\". To use it here, please " "add the necessary import."); } @@ -2295,11 +2300,16 @@ Symbol DescriptorBuilder::FindSymbol(const string& name) { // symbol unless none of the dependencies define it. if (IsInPackage(file_, name)) return result; for (int i = 0; i < file_->dependency_count(); i++) { - if (IsInPackage(file_->dependency(i), name)) return result; + // Note: A dependency may be NULL if it was not found or had errors. + if (file_->dependency(i) != NULL && + IsInPackage(file_->dependency(i), name)) { + return result; + } } } possible_undeclared_dependency_ = file; + possible_undeclared_dependency_name_ = name; return kNullSymbol; } @@ -3592,12 +3602,38 @@ void DescriptorBuilder::CrossLinkMethod( proto.array_name(i)); \ } +// Determine if the file uses optimize_for = LITE_RUNTIME, being careful to +// avoid problems that exist at init time. +static bool IsLite(const FileDescriptor* file) { + // TODO(kenton): I don't even remember how many of these conditions are + // actually possible. I'm just being super-safe. + return file != NULL && + &file->options() != NULL && + &file->options() != &FileOptions::default_instance() && + file->options().optimize_for() == FileOptions::LITE_RUNTIME; +} + void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file, const FileDescriptorProto& proto) { VALIDATE_OPTIONS_FROM_ARRAY(file, message_type, Message); VALIDATE_OPTIONS_FROM_ARRAY(file, enum_type, Enum); VALIDATE_OPTIONS_FROM_ARRAY(file, service, Service); VALIDATE_OPTIONS_FROM_ARRAY(file, extension, Field); + + // Lite files can only be imported by other Lite files. + if (!IsLite(file)) { + for (int i = 0; i < file->dependency_count(); i++) { + if (IsLite(file->dependency(i))) { + AddError( + file->name(), proto, + DescriptorPool::ErrorCollector::OTHER, + "Files that do not use optimize_for = LITE_RUNTIME cannot import " + "files which do use this option. This file is not lite, but it " + "imports \"" + file->dependency(i)->name() + "\" which is."); + break; + } + } + } } void DescriptorBuilder::ValidateMessageOptions(Descriptor* message, @@ -3647,6 +3683,17 @@ void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field, "MessageSets cannot have fields, only extensions."); } } + + // Lite extensions can only be of Lite types. + if (IsLite(field->file()) && + field->containing_type_ != NULL && + !IsLite(field->containing_type()->file())) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::EXTENDEE, + "Extensions to non-lite types can only be declared in non-lite " + "files. Note that you cannot extend a non-lite type to contain " + "a lite type, but the reverse is allowed."); + } } void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm, @@ -3660,6 +3707,12 @@ void DescriptorBuilder::ValidateEnumValueOptions( } void DescriptorBuilder::ValidateServiceOptions(ServiceDescriptor* service, const ServiceDescriptorProto& proto) { + if (IsLite(service->file())) { + AddError(service->full_name(), proto, + DescriptorPool::ErrorCollector::NAME, + "Files with optimize_for = LITE_RUNTIME cannot define services."); + } + VALIDATE_OPTIONS_FROM_ARRAY(service, method, Method); } @@ -3761,7 +3814,7 @@ bool DescriptorBuilder::OptionInterpreter::InterpretOptions( const int num_uninterpreted_options = original_options->GetReflection()-> FieldSize(*original_options, original_uninterpreted_options_field); for (int i = 0; i < num_uninterpreted_options; ++i) { - uninterpreted_option_ = ::google::protobuf::down_cast( + uninterpreted_option_ = down_cast( &original_options->GetReflection()->GetRepeatedMessage( *original_options, original_uninterpreted_options_field, i)); if (!InterpretSingleOption(options)) { @@ -4009,14 +4062,13 @@ bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet( const UnknownField* unknown_field = &unknown_fields.field(i); FieldDescriptor::Type type = (*intermediate_fields_iter)->type(); // Recurse into the next submessage. - ++intermediate_fields_iter; switch (type) { case FieldDescriptor::TYPE_MESSAGE: if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) { UnknownFieldSet intermediate_unknown_fields; if (intermediate_unknown_fields.ParseFromString( unknown_field->length_delimited()) && - !ExamineIfOptionIsSet(intermediate_fields_iter, + !ExamineIfOptionIsSet(intermediate_fields_iter + 1, intermediate_fields_end, innermost_field, debug_msg_name, intermediate_unknown_fields)) { @@ -4027,7 +4079,7 @@ bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet( case FieldDescriptor::TYPE_GROUP: if (unknown_field->type() == UnknownField::TYPE_GROUP) { - if (!ExamineIfOptionIsSet(intermediate_fields_iter, + if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1, intermediate_fields_end, innermost_field, debug_msg_name, unknown_field->group())) { @@ -4139,7 +4191,7 @@ bool DescriptorBuilder::OptionInterpreter::SetOptionValue( option_field->full_name() + "\"."); } unknown_fields->AddFixed32(option_field->number(), - google::protobuf::internal::WireFormat::EncodeFloat(value)); + google::protobuf::internal::WireFormatLite::EncodeFloat(value)); break; } @@ -4156,7 +4208,7 @@ bool DescriptorBuilder::OptionInterpreter::SetOptionValue( option_field->full_name() + "\"."); } unknown_fields->AddFixed64(option_field->number(), - google::protobuf::internal::WireFormat::EncodeDouble(value)); + google::protobuf::internal::WireFormatLite::EncodeDouble(value)); break; } @@ -4267,7 +4319,7 @@ void DescriptorBuilder::OptionInterpreter::SetInt32(int number, int32 value, case FieldDescriptor::TYPE_SINT32: unknown_fields->AddVarint(number, - google::protobuf::internal::WireFormat::ZigZagEncode32(value)); + google::protobuf::internal::WireFormatLite::ZigZagEncode32(value)); break; default: @@ -4289,7 +4341,7 @@ void DescriptorBuilder::OptionInterpreter::SetInt64(int number, int64 value, case FieldDescriptor::TYPE_SINT64: unknown_fields->AddVarint(number, - google::protobuf::internal::WireFormat::ZigZagEncode64(value)); + google::protobuf::internal::WireFormatLite::ZigZagEncode64(value)); break; default: diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 0caed839..a68a6a40 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -1,11 +1,13 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION #include "google/protobuf/descriptor.pb.h" #include -#include #include +#include +#include #include -#include +#include namespace google { namespace protobuf { @@ -268,8 +270,9 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { sizeof(FileOptions)); FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0); MessageOptions_descriptor_ = file->message_type(9); - static const int MessageOptions_offsets_[2] = { + static const int MessageOptions_offsets_[3] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, message_set_wire_format_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, no_standard_descriptor_accessor_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, uninterpreted_option_), }; MessageOptions_reflection_ = @@ -409,7 +412,7 @@ inline void protobuf_AssignDescriptorsOnce() { &protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto); } -void protobuf_RegisterTypes() { +void protobuf_RegisterTypes(const ::std::string&) { protobuf_AssignDescriptorsOnce(); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( FileDescriptorSet_descriptor_, &FileDescriptorSet::default_instance()); @@ -549,42 +552,43 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { "ptions\"\177\n\025MethodDescriptorProto\022\014\n\004name\030" "\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013output_type" "\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google.protobu" - "f.MethodOptions\"\247\002\n\013FileOptions\022\024\n\014java_" + "f.MethodOptions\"\271\002\n\013FileOptions\022\024\n\014java_" "package\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 " "\001(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005false\022" "F\n\014optimize_for\030\t \001(\0162).google.protobuf." "FileOptions.OptimizeMode:\005SPEED\022C\n\024unint" "erpreted_option\030\347\007 \003(\0132$.google.protobuf" - ".UninterpretedOption\"(\n\014OptimizeMode\022\t\n\005" - "SPEED\020\001\022\r\n\tCODE_SIZE\020\002*\t\010\350\007\020\200\200\200\200\002\"\210\001\n\016Me" - "ssageOptions\022&\n\027message_set_wire_format\030" - "\001 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 " + ".UninterpretedOption\":\n\014OptimizeMode\022\t\n\005" + "SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003" + "*\t\010\350\007\020\200\200\200\200\002\"\270\001\n\016MessageOptions\022&\n\027messag" + "e_set_wire_format\030\001 \001(\010:\005false\022.\n\037no_sta" + "ndard_descriptor_accessor\030\002 \001(\010:\005false\022C" + "\n\024uninterpreted_option\030\347\007 \003(\0132$.google.p" + "rotobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\200" + "\002\n\014FieldOptions\0222\n\005ctype\030\001 \001(\0162#.google." + "protobuf.FieldOptions.CType\022\016\n\006packed\030\002 " + "\001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\034\n\024experi" + "mental_map_key\030\t \001(\t\022C\n\024uninterpreted_op" + "tion\030\347\007 \003(\0132$.google.protobuf.Uninterpre" + "tedOption\"#\n\005CType\022\010\n\004CORD\020\001\022\020\n\014STRING_P" + "IECE\020\002*\t\010\350\007\020\200\200\200\200\002\"]\n\013EnumOptions\022C\n\024unin" + "terpreted_option\030\347\007 \003(\0132$.google.protobu" + "f.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"b\n\020Enum" + "ValueOptions\022C\n\024uninterpreted_option\030\347\007 " "\003(\0132$.google.protobuf.UninterpretedOptio" - "n*\t\010\350\007\020\200\200\200\200\002\"\200\002\n\014FieldOptions\0222\n\005ctype\030\001" - " \001(\0162#.google.protobuf.FieldOptions.CTyp" - "e\022\016\n\006packed\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005f" - "alse\022\034\n\024experimental_map_key\030\t \001(\t\022C\n\024un" - "interpreted_option\030\347\007 \003(\0132$.google.proto" - "buf.UninterpretedOption\"#\n\005CType\022\010\n\004CORD" - "\020\001\022\020\n\014STRING_PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"]\n\013EnumO" - "ptions\022C\n\024uninterpreted_option\030\347\007 \003(\0132$." - "google.protobuf.UninterpretedOption*\t\010\350\007" - "\020\200\200\200\200\002\"b\n\020EnumValueOptions\022C\n\024uninterpre" - "ted_option\030\347\007 \003(\0132$.google.protobuf.Unin" - "terpretedOption*\t\010\350\007\020\200\200\200\200\002\"`\n\016ServiceOpt" - "ions\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go" - "ogle.protobuf.UninterpretedOption*\t\010\350\007\020\200" - "\200\200\200\002\"_\n\rMethodOptions\022C\n\024uninterpreted_o" - "ption\030\347\007 \003(\0132$.google.protobuf.Uninterpr" - "etedOption*\t\010\350\007\020\200\200\200\200\002\"\205\002\n\023UninterpretedO" - "ption\022;\n\004name\030\002 \003(\0132-.google.protobuf.Un" - "interpretedOption.NamePart\022\030\n\020identifier" - "_value\030\003 \001(\t\022\032\n\022positive_int_value\030\004 \001(\004" - "\022\032\n\022negative_int_value\030\005 \001(\003\022\024\n\014double_v" - "alue\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014\0323\n\010Name" - "Part\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_extension\030" - "\002 \002(\010B)\n\023com.google.protobufB\020Descriptor" - "ProtosH\001", 3488); + "n*\t\010\350\007\020\200\200\200\200\002\"`\n\016ServiceOptions\022C\n\024uninte" + "rpreted_option\030\347\007 \003(\0132$.google.protobuf." + "UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"_\n\rMethod" + "Options\022C\n\024uninterpreted_option\030\347\007 \003(\0132$" + ".google.protobuf.UninterpretedOption*\t\010\350" + "\007\020\200\200\200\200\002\"\205\002\n\023UninterpretedOption\022;\n\004name\030" + "\002 \003(\0132-.google.protobuf.UninterpretedOpt" + "ion.NamePart\022\030\n\020identifier_value\030\003 \001(\t\022\032" + "\n\022positive_int_value\030\004 \001(\004\022\032\n\022negative_i" + "nt_value\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014" + "string_value\030\007 \001(\014\0323\n\010NamePart\022\021\n\tname_p" + "art\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010B)\n\023com.g" + "oogle.protobufB\020DescriptorProtosH\001", 3554); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/descriptor.proto", &protobuf_RegisterTypes); FileDescriptorSet::default_instance_ = new FileDescriptorSet(); @@ -640,15 +644,14 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto { const int FileDescriptorSet::kFileFieldNumber; #endif // !_MSC_VER -FileDescriptorSet::FileDescriptorSet() - : ::google::protobuf::Message() { +FileDescriptorSet::FileDescriptorSet() { SharedCtor(); } -void FileDescriptorSet::InitAsDefaultInstance() {} +void FileDescriptorSet::InitAsDefaultInstance() { +} -FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from) - : ::google::protobuf::Message() { +FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from) { SharedCtor(); MergeFrom(from); } @@ -693,16 +696,16 @@ bool FileDescriptorSet::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .google.protobuf.FileDescriptorProto file = 1; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_file: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_file())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_file())); if (input->ExpectTag(10)) goto parse_file; if (input->ExpectAtEnd()) return true; break; @@ -710,8 +713,8 @@ bool FileDescriptorSet::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } DO_(::google::protobuf::internal::WireFormat::SkipField( @@ -734,7 +737,8 @@ void FileDescriptorSet::SerializeWithCachedSizes( // repeated .google.protobuf.FileDescriptorProto file = 1; for (int i = 0; i < this->file_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(1, this->file(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 1, this->file(i), output); } if (!unknown_fields().empty()) { @@ -747,7 +751,9 @@ void FileDescriptorSet::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // repeated .google.protobuf.FileDescriptorProto file = 1; for (int i = 0; i < this->file_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(1, this->file(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file(i), target); } if (!unknown_fields().empty()) { @@ -764,7 +770,7 @@ int FileDescriptorSet::ByteSize() const { total_size += 1 * this->file_size(); for (int i = 0; i < this->file_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->file(i)); } @@ -824,15 +830,15 @@ void FileDescriptorSet::Swap(FileDescriptorSet* other) { } } -const ::google::protobuf::Descriptor* FileDescriptorSet::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* FileDescriptorSet::GetReflection() const { +::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return FileDescriptorSet_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = FileDescriptorSet_descriptor_; + metadata.reflection = FileDescriptorSet_reflection_; + return metadata; } + // =================================================================== const ::std::string FileDescriptorProto::_default_name_; @@ -848,16 +854,15 @@ const int FileDescriptorProto::kExtensionFieldNumber; const int FileDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -FileDescriptorProto::FileDescriptorProto() - : ::google::protobuf::Message() { +FileDescriptorProto::FileDescriptorProto() { SharedCtor(); } -void FileDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance()); +void FileDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance()); } -FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) - : ::google::protobuf::Message() { +FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) { SharedCtor(); MergeFrom(from); } @@ -931,39 +936,50 @@ bool FileDescriptorProto::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(18)) goto parse_package; break; } // optional string package = 2; case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_package: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_package())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_package())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->package().data(), this->package().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(26)) goto parse_dependency; break; } // repeated string dependency = 3; case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_dependency: - DO_(::google::protobuf::internal::WireFormat::ReadString( - input, add_dependency())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_dependency())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dependency(0).data(), this->dependency(0).length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(26)) goto parse_dependency; if (input->ExpectTag(34)) goto parse_message_type; break; @@ -971,13 +987,13 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.DescriptorProto message_type = 4; case 4: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_message_type: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_message_type())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_message_type())); if (input->ExpectTag(34)) goto parse_message_type; if (input->ExpectTag(42)) goto parse_enum_type; break; @@ -985,13 +1001,13 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; case 5: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_enum_type: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_enum_type())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_enum_type())); if (input->ExpectTag(42)) goto parse_enum_type; if (input->ExpectTag(50)) goto parse_service; break; @@ -999,13 +1015,13 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.ServiceDescriptorProto service = 6; case 6: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_service: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_service())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_service())); if (input->ExpectTag(50)) goto parse_service; if (input->ExpectTag(58)) goto parse_extension; break; @@ -1013,13 +1029,13 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.FieldDescriptorProto extension = 7; case 7: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_extension: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_extension())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_extension())); if (input->ExpectTag(58)) goto parse_extension; if (input->ExpectTag(66)) goto parse_options; break; @@ -1027,12 +1043,12 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.FileOptions options = 8; case 8: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); if (input->ExpectAtEnd()) return true; break; @@ -1040,8 +1056,8 @@ bool FileDescriptorProto::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } DO_(::google::protobuf::internal::WireFormat::SkipField( @@ -1064,42 +1080,59 @@ void FileDescriptorProto::SerializeWithCachedSizes( // optional string name = 1; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); } // optional string package = 2; if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::WriteString(2, this->package(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->package().data(), this->package().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->package(), output); } // repeated string dependency = 3; for (int i = 0; i < this->dependency_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteString(3, this->dependency(i), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dependency(i).data(), this->dependency(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->dependency(i), output); } // repeated .google.protobuf.DescriptorProto message_type = 4; for (int i = 0; i < this->message_type_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(4, this->message_type(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 4, this->message_type(i), output); } // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; for (int i = 0; i < this->enum_type_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(5, this->enum_type(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 5, this->enum_type(i), output); } // repeated .google.protobuf.ServiceDescriptorProto service = 6; for (int i = 0; i < this->service_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(6, this->service(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 6, this->service(i), output); } // repeated .google.protobuf.FieldDescriptorProto extension = 7; for (int i = 0; i < this->extension_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(7, this->extension(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 7, this->extension(i), output); } // optional .google.protobuf.FileOptions options = 8; if (_has_bit(7)) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(8, this->options(), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 8, this->options(), output); } if (!unknown_fields().empty()) { @@ -1112,42 +1145,66 @@ void FileDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // optional string name = 1; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(1, this->name(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); } // optional string package = 2; if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(2, this->package(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->package().data(), this->package().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->package(), target); } // repeated string dependency = 3; for (int i = 0; i < this->dependency_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(3, this->dependency(i), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dependency(i).data(), this->dependency(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(3, this->dependency(i), target); } // repeated .google.protobuf.DescriptorProto message_type = 4; for (int i = 0; i < this->message_type_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(4, this->message_type(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->message_type(i), target); } // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; for (int i = 0; i < this->enum_type_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(5, this->enum_type(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 5, this->enum_type(i), target); } // repeated .google.protobuf.ServiceDescriptorProto service = 6; for (int i = 0; i < this->service_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(6, this->service(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 6, this->service(i), target); } // repeated .google.protobuf.FieldDescriptorProto extension = 7; for (int i = 0; i < this->extension_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(7, this->extension(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 7, this->extension(i), target); } // optional .google.protobuf.FileOptions options = 8; if (_has_bit(7)) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(8, this->options(), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 8, this->options(), target); } if (!unknown_fields().empty()) { @@ -1164,19 +1221,21 @@ int FileDescriptorProto::ByteSize() const { // optional string name = 1; if (has_name()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); } // optional string package = 2; if (has_package()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->package()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->package()); } // optional .google.protobuf.FileOptions options = 8; if (has_options()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->options()); } @@ -1184,7 +1243,7 @@ int FileDescriptorProto::ByteSize() const { // repeated string dependency = 3; total_size += 1 * this->dependency_size(); for (int i = 0; i < this->dependency_size(); i++) { - total_size += ::google::protobuf::internal::WireFormat::StringSize( + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( this->dependency(i)); } @@ -1192,7 +1251,7 @@ int FileDescriptorProto::ByteSize() const { total_size += 1 * this->message_type_size(); for (int i = 0; i < this->message_type_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->message_type(i)); } @@ -1200,7 +1259,7 @@ int FileDescriptorProto::ByteSize() const { total_size += 1 * this->enum_type_size(); for (int i = 0; i < this->enum_type_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->enum_type(i)); } @@ -1208,7 +1267,7 @@ int FileDescriptorProto::ByteSize() const { total_size += 1 * this->service_size(); for (int i = 0; i < this->service_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->service(i)); } @@ -1216,7 +1275,7 @@ int FileDescriptorProto::ByteSize() const { total_size += 1 * this->extension_size(); for (int i = 0; i < this->extension_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->extension(i)); } @@ -1310,15 +1369,15 @@ void FileDescriptorProto::Swap(FileDescriptorProto* other) { } } -const ::google::protobuf::Descriptor* FileDescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* FileDescriptorProto::GetReflection() const { +::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return FileDescriptorProto_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = FileDescriptorProto_descriptor_; + metadata.reflection = FileDescriptorProto_reflection_; + return metadata; } + // =================================================================== #ifndef _MSC_VER @@ -1326,15 +1385,14 @@ const int DescriptorProto_ExtensionRange::kStartFieldNumber; const int DescriptorProto_ExtensionRange::kEndFieldNumber; #endif // !_MSC_VER -DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange() - : ::google::protobuf::Message() { +DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange() { SharedCtor(); } -void DescriptorProto_ExtensionRange::InitAsDefaultInstance() {} +void DescriptorProto_ExtensionRange::InitAsDefaultInstance() { +} -DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) - : ::google::protobuf::Message() { +DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) { SharedCtor(); MergeFrom(from); } @@ -1384,14 +1442,14 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional int32 start = 1; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormat::ReadInt32( + DO_(::google::protobuf::internal::WireFormatLite::ReadInt32( input, &start_)); _set_bit(0); if (input->ExpectTag(16)) goto parse_end; @@ -1400,12 +1458,12 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( // optional int32 end = 2; case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } parse_end: - DO_(::google::protobuf::internal::WireFormat::ReadInt32( + DO_(::google::protobuf::internal::WireFormatLite::ReadInt32( input, &end_)); _set_bit(1); if (input->ExpectAtEnd()) return true; @@ -1414,8 +1472,8 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } DO_(::google::protobuf::internal::WireFormat::SkipField( @@ -1438,12 +1496,12 @@ void DescriptorProto_ExtensionRange::SerializeWithCachedSizes( // optional int32 start = 1; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::WriteInt32(1, this->start(), output); + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output); } // optional int32 end = 2; if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::WriteInt32(2, this->end(), output); + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output); } if (!unknown_fields().empty()) { @@ -1456,12 +1514,12 @@ void DescriptorProto_ExtensionRange::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // optional int32 start = 1; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormat::WriteInt32ToArray(1, this->start(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target); } // optional int32 end = 2; if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormat::WriteInt32ToArray(2, this->end(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target); } if (!unknown_fields().empty()) { @@ -1478,14 +1536,14 @@ int DescriptorProto_ExtensionRange::ByteSize() const { // optional int32 start = 1; if (has_start()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::Int32Size( + ::google::protobuf::internal::WireFormatLite::Int32Size( this->start()); } // optional int32 end = 2; if (has_end()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::Int32Size( + ::google::protobuf::internal::WireFormatLite::Int32Size( this->end()); } @@ -1551,15 +1609,15 @@ void DescriptorProto_ExtensionRange::Swap(DescriptorProto_ExtensionRange* other) } } -const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* DescriptorProto_ExtensionRange::GetReflection() const { +::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return DescriptorProto_ExtensionRange_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = DescriptorProto_ExtensionRange_descriptor_; + metadata.reflection = DescriptorProto_ExtensionRange_reflection_; + return metadata; } + // ------------------------------------------------------------------- const ::std::string DescriptorProto::_default_name_; @@ -1573,16 +1631,15 @@ const int DescriptorProto::kExtensionRangeFieldNumber; const int DescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -DescriptorProto::DescriptorProto() - : ::google::protobuf::Message() { +DescriptorProto::DescriptorProto() { SharedCtor(); } -void DescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::MessageOptions*>(&::google::protobuf::MessageOptions::default_instance()); +void DescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::MessageOptions*>(&::google::protobuf::MessageOptions::default_instance()); } -DescriptorProto::DescriptorProto(const DescriptorProto& from) - : ::google::protobuf::Message() { +DescriptorProto::DescriptorProto(const DescriptorProto& from) { SharedCtor(); MergeFrom(from); } @@ -1647,27 +1704,31 @@ bool DescriptorProto::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(18)) goto parse_field; break; } // repeated .google.protobuf.FieldDescriptorProto field = 2; case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_field: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_field())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_field())); if (input->ExpectTag(18)) goto parse_field; if (input->ExpectTag(26)) goto parse_nested_type; break; @@ -1675,13 +1736,13 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.DescriptorProto nested_type = 3; case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_nested_type: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_nested_type())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_nested_type())); if (input->ExpectTag(26)) goto parse_nested_type; if (input->ExpectTag(34)) goto parse_enum_type; break; @@ -1689,13 +1750,13 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; case 4: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_enum_type: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_enum_type())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_enum_type())); if (input->ExpectTag(34)) goto parse_enum_type; if (input->ExpectTag(42)) goto parse_extension_range; break; @@ -1703,13 +1764,13 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; case 5: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_extension_range: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_extension_range())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_extension_range())); if (input->ExpectTag(42)) goto parse_extension_range; if (input->ExpectTag(50)) goto parse_extension; break; @@ -1717,13 +1778,13 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.FieldDescriptorProto extension = 6; case 6: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_extension: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_extension())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_extension())); if (input->ExpectTag(50)) goto parse_extension; if (input->ExpectTag(58)) goto parse_options; break; @@ -1731,12 +1792,12 @@ bool DescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.MessageOptions options = 7; case 7: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); if (input->ExpectAtEnd()) return true; break; @@ -1744,8 +1805,8 @@ bool DescriptorProto::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } DO_(::google::protobuf::internal::WireFormat::SkipField( @@ -1768,37 +1829,47 @@ void DescriptorProto::SerializeWithCachedSizes( // optional string name = 1; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); } // repeated .google.protobuf.FieldDescriptorProto field = 2; for (int i = 0; i < this->field_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->field(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 2, this->field(i), output); } // repeated .google.protobuf.DescriptorProto nested_type = 3; for (int i = 0; i < this->nested_type_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->nested_type(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 3, this->nested_type(i), output); } // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; for (int i = 0; i < this->enum_type_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(4, this->enum_type(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 4, this->enum_type(i), output); } // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; for (int i = 0; i < this->extension_range_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(5, this->extension_range(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 5, this->extension_range(i), output); } // repeated .google.protobuf.FieldDescriptorProto extension = 6; for (int i = 0; i < this->extension_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(6, this->extension(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 6, this->extension(i), output); } // optional .google.protobuf.MessageOptions options = 7; if (_has_bit(6)) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(7, this->options(), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 7, this->options(), output); } if (!unknown_fields().empty()) { @@ -1811,37 +1882,54 @@ void DescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // optional string name = 1; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(1, this->name(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); } // repeated .google.protobuf.FieldDescriptorProto field = 2; for (int i = 0; i < this->field_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(2, this->field(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->field(i), target); } // repeated .google.protobuf.DescriptorProto nested_type = 3; for (int i = 0; i < this->nested_type_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(3, this->nested_type(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->nested_type(i), target); } // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; for (int i = 0; i < this->enum_type_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(4, this->enum_type(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->enum_type(i), target); } // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; for (int i = 0; i < this->extension_range_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(5, this->extension_range(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 5, this->extension_range(i), target); } // repeated .google.protobuf.FieldDescriptorProto extension = 6; for (int i = 0; i < this->extension_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(6, this->extension(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 6, this->extension(i), target); } // optional .google.protobuf.MessageOptions options = 7; if (_has_bit(6)) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(7, this->options(), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 7, this->options(), target); } if (!unknown_fields().empty()) { @@ -1858,13 +1946,14 @@ int DescriptorProto::ByteSize() const { // optional string name = 1; if (has_name()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); } // optional .google.protobuf.MessageOptions options = 7; if (has_options()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->options()); } @@ -1873,7 +1962,7 @@ int DescriptorProto::ByteSize() const { total_size += 1 * this->field_size(); for (int i = 0; i < this->field_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->field(i)); } @@ -1881,7 +1970,7 @@ int DescriptorProto::ByteSize() const { total_size += 1 * this->extension_size(); for (int i = 0; i < this->extension_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->extension(i)); } @@ -1889,7 +1978,7 @@ int DescriptorProto::ByteSize() const { total_size += 1 * this->nested_type_size(); for (int i = 0; i < this->nested_type_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->nested_type(i)); } @@ -1897,7 +1986,7 @@ int DescriptorProto::ByteSize() const { total_size += 1 * this->enum_type_size(); for (int i = 0; i < this->enum_type_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->enum_type(i)); } @@ -1905,7 +1994,7 @@ int DescriptorProto::ByteSize() const { total_size += 1 * this->extension_range_size(); for (int i = 0; i < this->extension_range_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->extension_range(i)); } @@ -1995,15 +2084,15 @@ void DescriptorProto::Swap(DescriptorProto* other) { } } -const ::google::protobuf::Descriptor* DescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* DescriptorProto::GetReflection() const { +::google::protobuf::Metadata DescriptorProto::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return DescriptorProto_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = DescriptorProto_descriptor_; + metadata.reflection = DescriptorProto_reflection_; + return metadata; } + // =================================================================== const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor() { @@ -2095,16 +2184,15 @@ const int FieldDescriptorProto::kDefaultValueFieldNumber; const int FieldDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -FieldDescriptorProto::FieldDescriptorProto() - : ::google::protobuf::Message() { +FieldDescriptorProto::FieldDescriptorProto() { SharedCtor(); } -void FieldDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::FieldOptions*>(&::google::protobuf::FieldOptions::default_instance()); +void FieldDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::FieldOptions*>(&::google::protobuf::FieldOptions::default_instance()); } -FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) - : ::google::protobuf::Message() { +FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) { SharedCtor(); MergeFrom(from); } @@ -2197,38 +2285,46 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(18)) goto parse_extendee; break; } // optional string extendee = 2; case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_extendee: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_extendee())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_extendee())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->extendee().data(), this->extendee().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(24)) goto parse_number; break; } // optional int32 number = 3; case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } parse_number: - DO_(::google::protobuf::internal::WireFormat::ReadInt32( + DO_(::google::protobuf::internal::WireFormatLite::ReadInt32( input, &number_)); _set_bit(1); if (input->ExpectTag(32)) goto parse_label; @@ -2237,13 +2333,13 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.FieldDescriptorProto.Label label = 4; case 4: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } parse_label: int value; - DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value)); + DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value)); if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) { set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value)); } else { @@ -2255,13 +2351,13 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.FieldDescriptorProto.Type type = 5; case 5: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } parse_type: int value; - DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value)); + DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value)); if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) { set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value)); } else { @@ -2273,36 +2369,44 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional string type_name = 6; case 6: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_type_name: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_type_name())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_type_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->type_name().data(), this->type_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(58)) goto parse_default_value; break; } // optional string default_value = 7; case 7: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_default_value: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_default_value())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_default_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->default_value().data(), this->default_value().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(66)) goto parse_options; break; } // optional .google.protobuf.FieldOptions options = 8; case 8: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); if (input->ExpectAtEnd()) return true; break; @@ -2310,8 +2414,8 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } DO_(::google::protobuf::internal::WireFormat::SkipField( @@ -2334,42 +2438,61 @@ void FieldDescriptorProto::SerializeWithCachedSizes( // optional string name = 1; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); } // optional string extendee = 2; if (_has_bit(5)) { - ::google::protobuf::internal::WireFormat::WriteString(2, this->extendee(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->extendee().data(), this->extendee().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->extendee(), output); } // optional int32 number = 3; if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::WriteInt32(3, this->number(), output); + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output); } // optional .google.protobuf.FieldDescriptorProto.Label label = 4; if (_has_bit(2)) { - ::google::protobuf::internal::WireFormat::WriteEnum(4, this->label(), output); + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 4, this->label(), output); } // optional .google.protobuf.FieldDescriptorProto.Type type = 5; if (_has_bit(3)) { - ::google::protobuf::internal::WireFormat::WriteEnum(5, this->type(), output); + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 5, this->type(), output); } // optional string type_name = 6; if (_has_bit(4)) { - ::google::protobuf::internal::WireFormat::WriteString(6, this->type_name(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->type_name().data(), this->type_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 6, this->type_name(), output); } // optional string default_value = 7; if (_has_bit(6)) { - ::google::protobuf::internal::WireFormat::WriteString(7, this->default_value(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->default_value().data(), this->default_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 7, this->default_value(), output); } // optional .google.protobuf.FieldOptions options = 8; if (_has_bit(7)) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(8, this->options(), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 8, this->options(), output); } if (!unknown_fields().empty()) { @@ -2382,42 +2505,66 @@ void FieldDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // optional string name = 1; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(1, this->name(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); } // optional string extendee = 2; if (_has_bit(5)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(2, this->extendee(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->extendee().data(), this->extendee().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->extendee(), target); } // optional int32 number = 3; if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormat::WriteInt32ToArray(3, this->number(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target); } // optional .google.protobuf.FieldDescriptorProto.Label label = 4; if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormat::WriteEnumToArray(4, this->label(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 4, this->label(), target); } // optional .google.protobuf.FieldDescriptorProto.Type type = 5; if (_has_bit(3)) { - target = ::google::protobuf::internal::WireFormat::WriteEnumToArray(5, this->type(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 5, this->type(), target); } // optional string type_name = 6; if (_has_bit(4)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(6, this->type_name(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->type_name().data(), this->type_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 6, this->type_name(), target); } // optional string default_value = 7; if (_has_bit(6)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(7, this->default_value(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->default_value().data(), this->default_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 7, this->default_value(), target); } // optional .google.protobuf.FieldOptions options = 8; if (_has_bit(7)) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(8, this->options(), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 8, this->options(), target); } if (!unknown_fields().empty()) { @@ -2434,50 +2581,54 @@ int FieldDescriptorProto::ByteSize() const { // optional string name = 1; if (has_name()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); } // optional int32 number = 3; if (has_number()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::Int32Size( + ::google::protobuf::internal::WireFormatLite::Int32Size( this->number()); } // optional .google.protobuf.FieldDescriptorProto.Label label = 4; if (has_label()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::EnumSize(this->label()); + ::google::protobuf::internal::WireFormatLite::EnumSize(this->label()); } // optional .google.protobuf.FieldDescriptorProto.Type type = 5; if (has_type()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::EnumSize(this->type()); + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); } // optional string type_name = 6; if (has_type_name()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->type_name()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->type_name()); } // optional string extendee = 2; if (has_extendee()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->extendee()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->extendee()); } // optional string default_value = 7; if (has_default_value()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->default_value()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->default_value()); } // optional .google.protobuf.FieldOptions options = 8; if (has_options()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->options()); } @@ -2570,15 +2721,15 @@ void FieldDescriptorProto::Swap(FieldDescriptorProto* other) { } } -const ::google::protobuf::Descriptor* FieldDescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* FieldDescriptorProto::GetReflection() const { +::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return FieldDescriptorProto_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = FieldDescriptorProto_descriptor_; + metadata.reflection = FieldDescriptorProto_reflection_; + return metadata; } + // =================================================================== const ::std::string EnumDescriptorProto::_default_name_; @@ -2588,16 +2739,15 @@ const int EnumDescriptorProto::kValueFieldNumber; const int EnumDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -EnumDescriptorProto::EnumDescriptorProto() - : ::google::protobuf::Message() { +EnumDescriptorProto::EnumDescriptorProto() { SharedCtor(); } -void EnumDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::EnumOptions*>(&::google::protobuf::EnumOptions::default_instance()); +void EnumDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::EnumOptions*>(&::google::protobuf::EnumOptions::default_instance()); } -EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from) - : ::google::protobuf::Message() { +EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from) { SharedCtor(); MergeFrom(from); } @@ -2658,27 +2808,31 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(18)) goto parse_value; break; } // repeated .google.protobuf.EnumValueDescriptorProto value = 2; case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_value: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_value())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_value())); if (input->ExpectTag(18)) goto parse_value; if (input->ExpectTag(26)) goto parse_options; break; @@ -2686,12 +2840,12 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.EnumOptions options = 3; case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); if (input->ExpectAtEnd()) return true; break; @@ -2699,8 +2853,8 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } DO_(::google::protobuf::internal::WireFormat::SkipField( @@ -2723,17 +2877,23 @@ void EnumDescriptorProto::SerializeWithCachedSizes( // optional string name = 1; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); } // repeated .google.protobuf.EnumValueDescriptorProto value = 2; for (int i = 0; i < this->value_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->value(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 2, this->value(i), output); } // optional .google.protobuf.EnumOptions options = 3; if (_has_bit(2)) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->options(), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 3, this->options(), output); } if (!unknown_fields().empty()) { @@ -2746,17 +2906,26 @@ void EnumDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // optional string name = 1; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(1, this->name(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); } // repeated .google.protobuf.EnumValueDescriptorProto value = 2; for (int i = 0; i < this->value_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(2, this->value(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->value(i), target); } // optional .google.protobuf.EnumOptions options = 3; if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(3, this->options(), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->options(), target); } if (!unknown_fields().empty()) { @@ -2773,13 +2942,14 @@ int EnumDescriptorProto::ByteSize() const { // optional string name = 1; if (has_name()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); } // optional .google.protobuf.EnumOptions options = 3; if (has_options()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->options()); } @@ -2788,7 +2958,7 @@ int EnumDescriptorProto::ByteSize() const { total_size += 1 * this->value_size(); for (int i = 0; i < this->value_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->value(i)); } @@ -2861,15 +3031,15 @@ void EnumDescriptorProto::Swap(EnumDescriptorProto* other) { } } -const ::google::protobuf::Descriptor* EnumDescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* EnumDescriptorProto::GetReflection() const { +::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return EnumDescriptorProto_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = EnumDescriptorProto_descriptor_; + metadata.reflection = EnumDescriptorProto_reflection_; + return metadata; } + // =================================================================== const ::std::string EnumValueDescriptorProto::_default_name_; @@ -2879,16 +3049,15 @@ const int EnumValueDescriptorProto::kNumberFieldNumber; const int EnumValueDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -EnumValueDescriptorProto::EnumValueDescriptorProto() - : ::google::protobuf::Message() { +EnumValueDescriptorProto::EnumValueDescriptorProto() { SharedCtor(); } -void EnumValueDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::EnumValueOptions*>(&::google::protobuf::EnumValueOptions::default_instance()); +void EnumValueDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::EnumValueOptions*>(&::google::protobuf::EnumValueOptions::default_instance()); } -EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from) - : ::google::protobuf::Message() { +EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from) { SharedCtor(); MergeFrom(from); } @@ -2950,26 +3119,30 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(16)) goto parse_number; break; } // optional int32 number = 2; case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } parse_number: - DO_(::google::protobuf::internal::WireFormat::ReadInt32( + DO_(::google::protobuf::internal::WireFormatLite::ReadInt32( input, &number_)); _set_bit(1); if (input->ExpectTag(26)) goto parse_options; @@ -2978,12 +3151,12 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.EnumValueOptions options = 3; case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); if (input->ExpectAtEnd()) return true; break; @@ -2991,8 +3164,8 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } DO_(::google::protobuf::internal::WireFormat::SkipField( @@ -3015,17 +3188,22 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( // optional string name = 1; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); } // optional int32 number = 2; if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::WriteInt32(2, this->number(), output); + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output); } // optional .google.protobuf.EnumValueOptions options = 3; if (_has_bit(2)) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->options(), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 3, this->options(), output); } if (!unknown_fields().empty()) { @@ -3038,17 +3216,24 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // optional string name = 1; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(1, this->name(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); } // optional int32 number = 2; if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormat::WriteInt32ToArray(2, this->number(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target); } // optional .google.protobuf.EnumValueOptions options = 3; if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(3, this->options(), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->options(), target); } if (!unknown_fields().empty()) { @@ -3065,20 +3250,21 @@ int EnumValueDescriptorProto::ByteSize() const { // optional string name = 1; if (has_name()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); } // optional int32 number = 2; if (has_number()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::Int32Size( + ::google::protobuf::internal::WireFormatLite::Int32Size( this->number()); } // optional .google.protobuf.EnumValueOptions options = 3; if (has_options()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->options()); } @@ -3151,15 +3337,15 @@ void EnumValueDescriptorProto::Swap(EnumValueDescriptorProto* other) { } } -const ::google::protobuf::Descriptor* EnumValueDescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* EnumValueDescriptorProto::GetReflection() const { +::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return EnumValueDescriptorProto_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = EnumValueDescriptorProto_descriptor_; + metadata.reflection = EnumValueDescriptorProto_reflection_; + return metadata; } + // =================================================================== const ::std::string ServiceDescriptorProto::_default_name_; @@ -3169,16 +3355,15 @@ const int ServiceDescriptorProto::kMethodFieldNumber; const int ServiceDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -ServiceDescriptorProto::ServiceDescriptorProto() - : ::google::protobuf::Message() { +ServiceDescriptorProto::ServiceDescriptorProto() { SharedCtor(); } -void ServiceDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::ServiceOptions*>(&::google::protobuf::ServiceOptions::default_instance()); +void ServiceDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::ServiceOptions*>(&::google::protobuf::ServiceOptions::default_instance()); } -ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from) - : ::google::protobuf::Message() { +ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from) { SharedCtor(); MergeFrom(from); } @@ -3239,27 +3424,31 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(18)) goto parse_method; break; } // repeated .google.protobuf.MethodDescriptorProto method = 2; case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_method: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_method())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_method())); if (input->ExpectTag(18)) goto parse_method; if (input->ExpectTag(26)) goto parse_options; break; @@ -3267,12 +3456,12 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.ServiceOptions options = 3; case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); if (input->ExpectAtEnd()) return true; break; @@ -3280,8 +3469,8 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } DO_(::google::protobuf::internal::WireFormat::SkipField( @@ -3304,17 +3493,23 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( // optional string name = 1; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); } // repeated .google.protobuf.MethodDescriptorProto method = 2; for (int i = 0; i < this->method_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->method(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 2, this->method(i), output); } // optional .google.protobuf.ServiceOptions options = 3; if (_has_bit(2)) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->options(), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 3, this->options(), output); } if (!unknown_fields().empty()) { @@ -3327,17 +3522,26 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // optional string name = 1; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(1, this->name(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); } // repeated .google.protobuf.MethodDescriptorProto method = 2; for (int i = 0; i < this->method_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(2, this->method(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->method(i), target); } // optional .google.protobuf.ServiceOptions options = 3; if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(3, this->options(), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->options(), target); } if (!unknown_fields().empty()) { @@ -3354,13 +3558,14 @@ int ServiceDescriptorProto::ByteSize() const { // optional string name = 1; if (has_name()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); } // optional .google.protobuf.ServiceOptions options = 3; if (has_options()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->options()); } @@ -3369,7 +3574,7 @@ int ServiceDescriptorProto::ByteSize() const { total_size += 1 * this->method_size(); for (int i = 0; i < this->method_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->method(i)); } @@ -3442,15 +3647,15 @@ void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) { } } -const ::google::protobuf::Descriptor* ServiceDescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* ServiceDescriptorProto::GetReflection() const { +::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return ServiceDescriptorProto_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = ServiceDescriptorProto_descriptor_; + metadata.reflection = ServiceDescriptorProto_reflection_; + return metadata; } + // =================================================================== const ::std::string MethodDescriptorProto::_default_name_; @@ -3463,16 +3668,15 @@ const int MethodDescriptorProto::kOutputTypeFieldNumber; const int MethodDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -MethodDescriptorProto::MethodDescriptorProto() - : ::google::protobuf::Message() { +MethodDescriptorProto::MethodDescriptorProto() { SharedCtor(); } -void MethodDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::MethodOptions*>(&::google::protobuf::MethodOptions::default_instance()); +void MethodDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::MethodOptions*>(&::google::protobuf::MethodOptions::default_instance()); } -MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from) - : ::google::protobuf::Message() { +MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from) { SharedCtor(); MergeFrom(from); } @@ -3550,50 +3754,62 @@ bool MethodDescriptorProto::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(18)) goto parse_input_type; break; } // optional string input_type = 2; case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_input_type: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_input_type())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_input_type())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->input_type().data(), this->input_type().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(26)) goto parse_output_type; break; } // optional string output_type = 3; case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_output_type: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_output_type())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_output_type())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->output_type().data(), this->output_type().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(34)) goto parse_options; break; } // optional .google.protobuf.MethodOptions options = 4; case 4: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); if (input->ExpectAtEnd()) return true; break; @@ -3601,8 +3817,8 @@ bool MethodDescriptorProto::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } DO_(::google::protobuf::internal::WireFormat::SkipField( @@ -3625,22 +3841,35 @@ void MethodDescriptorProto::SerializeWithCachedSizes( // optional string name = 1; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); } // optional string input_type = 2; if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::WriteString(2, this->input_type(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->input_type().data(), this->input_type().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->input_type(), output); } // optional string output_type = 3; if (_has_bit(2)) { - ::google::protobuf::internal::WireFormat::WriteString(3, this->output_type(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->output_type().data(), this->output_type().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->output_type(), output); } // optional .google.protobuf.MethodOptions options = 4; if (_has_bit(3)) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(4, this->options(), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 4, this->options(), output); } if (!unknown_fields().empty()) { @@ -3653,22 +3882,39 @@ void MethodDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // optional string name = 1; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(1, this->name(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); } // optional string input_type = 2; if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(2, this->input_type(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->input_type().data(), this->input_type().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->input_type(), target); } // optional string output_type = 3; if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(3, this->output_type(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->output_type().data(), this->output_type().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->output_type(), target); } // optional .google.protobuf.MethodOptions options = 4; if (_has_bit(3)) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(4, this->options(), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->options(), target); } if (!unknown_fields().empty()) { @@ -3685,25 +3931,28 @@ int MethodDescriptorProto::ByteSize() const { // optional string name = 1; if (has_name()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); } // optional string input_type = 2; if (has_input_type()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->input_type()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->input_type()); } // optional string output_type = 3; if (has_output_type()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->output_type()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->output_type()); } // optional .google.protobuf.MethodOptions options = 4; if (has_options()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->options()); } @@ -3780,15 +4029,15 @@ void MethodDescriptorProto::Swap(MethodDescriptorProto* other) { } } -const ::google::protobuf::Descriptor* MethodDescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* MethodDescriptorProto::GetReflection() const { +::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return MethodDescriptorProto_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = MethodDescriptorProto_descriptor_; + metadata.reflection = MethodDescriptorProto_reflection_; + return metadata; } + // =================================================================== const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() { @@ -3799,6 +4048,7 @@ bool FileOptions_OptimizeMode_IsValid(int value) { switch(value) { case 1: case 2: + case 3: return true; default: return false; @@ -3808,6 +4058,7 @@ bool FileOptions_OptimizeMode_IsValid(int value) { #ifndef _MSC_VER const FileOptions_OptimizeMode FileOptions::SPEED; const FileOptions_OptimizeMode FileOptions::CODE_SIZE; +const FileOptions_OptimizeMode FileOptions::LITE_RUNTIME; const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN; const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX; #endif // _MSC_VER @@ -3821,15 +4072,14 @@ const int FileOptions::kOptimizeForFieldNumber; const int FileOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -FileOptions::FileOptions() - : ::google::protobuf::Message() { +FileOptions::FileOptions() { SharedCtor(); } -void FileOptions::InitAsDefaultInstance() {} +void FileOptions::InitAsDefaultInstance() { +} -FileOptions::FileOptions(const FileOptions& from) - : ::google::protobuf::Message() { +FileOptions::FileOptions(const FileOptions& from) { SharedCtor(); MergeFrom(from); } @@ -3899,39 +4149,47 @@ bool FileOptions::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string java_package = 1; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_java_package())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_java_package())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_package().data(), this->java_package().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(66)) goto parse_java_outer_classname; break; } // optional string java_outer_classname = 8; case 8: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_java_outer_classname: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_java_outer_classname())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_java_outer_classname())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_outer_classname().data(), this->java_outer_classname().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(72)) goto parse_optimize_for; break; } // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; case 9: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } parse_optimize_for: int value; - DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value)); + DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value)); if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) { set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value)); } else { @@ -3943,12 +4201,12 @@ bool FileOptions::MergePartialFromCodedStream( // optional bool java_multiple_files = 10 [default = false]; case 10: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } parse_java_multiple_files: - DO_(::google::protobuf::internal::WireFormat::ReadBool( + DO_(::google::protobuf::internal::WireFormatLite::ReadBool( input, &java_multiple_files_)); _set_bit(2); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; @@ -3957,13 +4215,13 @@ bool FileOptions::MergePartialFromCodedStream( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_uninterpreted_option())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -3971,8 +4229,8 @@ bool FileOptions::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } if ((8000u <= tag)) { @@ -4000,27 +4258,37 @@ void FileOptions::SerializeWithCachedSizes( // optional string java_package = 1; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::WriteString(1, this->java_package(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_package().data(), this->java_package().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->java_package(), output); } // optional string java_outer_classname = 8; if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::WriteString(8, this->java_outer_classname(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_outer_classname().data(), this->java_outer_classname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 8, this->java_outer_classname(), output); } // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; if (_has_bit(3)) { - ::google::protobuf::internal::WireFormat::WriteEnum(9, this->optimize_for(), output); + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 9, this->optimize_for(), output); } // optional bool java_multiple_files = 10 [default = false]; if (_has_bit(2)) { - ::google::protobuf::internal::WireFormat::WriteBool(10, this->java_multiple_files(), output); + ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 999, this->uninterpreted_option(i), output); } // Extension range [1000, 536870912) @@ -4037,27 +4305,40 @@ void FileOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // optional string java_package = 1; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(1, this->java_package(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_package().data(), this->java_package().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->java_package(), target); } // optional string java_outer_classname = 8; if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(8, this->java_outer_classname(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_outer_classname().data(), this->java_outer_classname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 8, this->java_outer_classname(), target); } // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; if (_has_bit(3)) { - target = ::google::protobuf::internal::WireFormat::WriteEnumToArray(9, this->optimize_for(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 9, this->optimize_for(), target); } // optional bool java_multiple_files = 10 [default = false]; if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormat::WriteBoolToArray(10, this->java_multiple_files(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(999, this->uninterpreted_option(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); } // Extension range [1000, 536870912) @@ -4078,13 +4359,15 @@ int FileOptions::ByteSize() const { // optional string java_package = 1; if (has_java_package()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->java_package()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->java_package()); } // optional string java_outer_classname = 8; if (has_java_outer_classname()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->java_outer_classname()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->java_outer_classname()); } // optional bool java_multiple_files = 10 [default = false]; @@ -4095,7 +4378,7 @@ int FileOptions::ByteSize() const { // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; if (has_optimize_for()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::EnumSize(this->optimize_for()); + ::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for()); } } @@ -4103,7 +4386,7 @@ int FileOptions::ByteSize() const { total_size += 2 * this->uninterpreted_option_size(); for (int i = 0; i < this->uninterpreted_option_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->uninterpreted_option(i)); } @@ -4186,31 +4469,31 @@ void FileOptions::Swap(FileOptions* other) { } } -const ::google::protobuf::Descriptor* FileOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* FileOptions::GetReflection() const { +::google::protobuf::Metadata FileOptions::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return FileOptions_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = FileOptions_descriptor_; + metadata.reflection = FileOptions_reflection_; + return metadata; } + // =================================================================== #ifndef _MSC_VER const int MessageOptions::kMessageSetWireFormatFieldNumber; +const int MessageOptions::kNoStandardDescriptorAccessorFieldNumber; const int MessageOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -MessageOptions::MessageOptions() - : ::google::protobuf::Message() { +MessageOptions::MessageOptions() { SharedCtor(); } -void MessageOptions::InitAsDefaultInstance() {} +void MessageOptions::InitAsDefaultInstance() { +} -MessageOptions::MessageOptions(const MessageOptions& from) - : ::google::protobuf::Message() { +MessageOptions::MessageOptions(const MessageOptions& from) { SharedCtor(); MergeFrom(from); } @@ -4218,6 +4501,7 @@ MessageOptions::MessageOptions(const MessageOptions& from) void MessageOptions::SharedCtor() { _cached_size_ = 0; message_set_wire_format_ = false; + no_standard_descriptor_accessor_ = false; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -4249,6 +4533,7 @@ void MessageOptions::Clear() { _extensions_.Clear(); if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { message_set_wire_format_ = false; + no_standard_descriptor_accessor_ = false; } uninterpreted_option_.Clear(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); @@ -4260,29 +4545,43 @@ bool MessageOptions::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional bool message_set_wire_format = 1 [default = false]; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormat::ReadBool( + DO_(::google::protobuf::internal::WireFormatLite::ReadBool( input, &message_set_wire_format_)); _set_bit(0); + if (input->ExpectTag(16)) goto parse_no_standard_descriptor_accessor; + break; + } + + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + goto handle_uninterpreted; + } + parse_no_standard_descriptor_accessor: + DO_(::google::protobuf::internal::WireFormatLite::ReadBool( + input, &no_standard_descriptor_accessor_)); + _set_bit(1); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; break; } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_uninterpreted_option())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -4290,8 +4589,8 @@ bool MessageOptions::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } if ((8000u <= tag)) { @@ -4319,12 +4618,18 @@ void MessageOptions::SerializeWithCachedSizes( // optional bool message_set_wire_format = 1 [default = false]; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::WriteBool(1, this->message_set_wire_format(), output); + ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output); + } + + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + if (_has_bit(1)) { + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 999, this->uninterpreted_option(i), output); } // Extension range [1000, 536870912) @@ -4341,12 +4646,19 @@ void MessageOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // optional bool message_set_wire_format = 1 [default = false]; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormat::WriteBoolToArray(1, this->message_set_wire_format(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target); + } + + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + if (_has_bit(1)) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(999, this->uninterpreted_option(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); } // Extension range [1000, 536870912) @@ -4369,12 +4681,17 @@ int MessageOptions::ByteSize() const { total_size += 1 + 1; } + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + if (has_no_standard_descriptor_accessor()) { + total_size += 1 + 1; + } + } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; total_size += 2 * this->uninterpreted_option_size(); for (int i = 0; i < this->uninterpreted_option_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->uninterpreted_option(i)); } @@ -4408,6 +4725,9 @@ void MessageOptions::MergeFrom(const MessageOptions& from) { if (from._has_bit(0)) { set_message_set_wire_format(from.message_set_wire_format()); } + if (from._has_bit(1)) { + set_no_standard_descriptor_accessor(from.no_standard_descriptor_accessor()); + } } _extensions_.MergeFrom(from._extensions_); mutable_unknown_fields()->MergeFrom(from.unknown_fields()); @@ -4437,6 +4757,7 @@ bool MessageOptions::IsInitialized() const { void MessageOptions::Swap(MessageOptions* other) { if (other != this) { std::swap(message_set_wire_format_, other->message_set_wire_format_); + std::swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_); uninterpreted_option_.Swap(&other->uninterpreted_option_); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); @@ -4445,15 +4766,15 @@ void MessageOptions::Swap(MessageOptions* other) { } } -const ::google::protobuf::Descriptor* MessageOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* MessageOptions::GetReflection() const { +::google::protobuf::Metadata MessageOptions::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return MessageOptions_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = MessageOptions_descriptor_; + metadata.reflection = MessageOptions_reflection_; + return metadata; } + // =================================================================== const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() { @@ -4485,15 +4806,14 @@ const int FieldOptions::kExperimentalMapKeyFieldNumber; const int FieldOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -FieldOptions::FieldOptions() - : ::google::protobuf::Message() { +FieldOptions::FieldOptions() { SharedCtor(); } -void FieldOptions::InitAsDefaultInstance() {} +void FieldOptions::InitAsDefaultInstance() { +} -FieldOptions::FieldOptions(const FieldOptions& from) - : ::google::protobuf::Message() { +FieldOptions::FieldOptions(const FieldOptions& from) { SharedCtor(); MergeFrom(from); } @@ -4556,15 +4876,15 @@ bool FieldOptions::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional .google.protobuf.FieldOptions.CType ctype = 1; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } int value; - DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value)); + DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value)); if (::google::protobuf::FieldOptions_CType_IsValid(value)) { set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value)); } else { @@ -4576,12 +4896,12 @@ bool FieldOptions::MergePartialFromCodedStream( // optional bool packed = 2; case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } parse_packed: - DO_(::google::protobuf::internal::WireFormat::ReadBool( + DO_(::google::protobuf::internal::WireFormatLite::ReadBool( input, &packed_)); _set_bit(1); if (input->ExpectTag(24)) goto parse_deprecated; @@ -4590,12 +4910,12 @@ bool FieldOptions::MergePartialFromCodedStream( // optional bool deprecated = 3 [default = false]; case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } parse_deprecated: - DO_(::google::protobuf::internal::WireFormat::ReadBool( + DO_(::google::protobuf::internal::WireFormatLite::ReadBool( input, &deprecated_)); _set_bit(2); if (input->ExpectTag(74)) goto parse_experimental_map_key; @@ -4604,25 +4924,29 @@ bool FieldOptions::MergePartialFromCodedStream( // optional string experimental_map_key = 9; case 9: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_experimental_map_key: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_experimental_map_key())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_experimental_map_key())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->experimental_map_key().data(), this->experimental_map_key().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; break; } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_uninterpreted_option())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -4630,8 +4954,8 @@ bool FieldOptions::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } if ((8000u <= tag)) { @@ -4659,27 +4983,33 @@ void FieldOptions::SerializeWithCachedSizes( // optional .google.protobuf.FieldOptions.CType ctype = 1; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::WriteEnum(1, this->ctype(), output); + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->ctype(), output); } // optional bool packed = 2; if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::WriteBool(2, this->packed(), output); + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output); } // optional bool deprecated = 3 [default = false]; if (_has_bit(2)) { - ::google::protobuf::internal::WireFormat::WriteBool(3, this->deprecated(), output); + ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output); } // optional string experimental_map_key = 9; if (_has_bit(3)) { - ::google::protobuf::internal::WireFormat::WriteString(9, this->experimental_map_key(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->experimental_map_key().data(), this->experimental_map_key().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 9, this->experimental_map_key(), output); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 999, this->uninterpreted_option(i), output); } // Extension range [1000, 536870912) @@ -4696,27 +5026,35 @@ void FieldOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // optional .google.protobuf.FieldOptions.CType ctype = 1; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormat::WriteEnumToArray(1, this->ctype(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->ctype(), target); } // optional bool packed = 2; if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormat::WriteBoolToArray(2, this->packed(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target); } // optional bool deprecated = 3 [default = false]; if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormat::WriteBoolToArray(3, this->deprecated(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target); } // optional string experimental_map_key = 9; if (_has_bit(3)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(9, this->experimental_map_key(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->experimental_map_key().data(), this->experimental_map_key().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 9, this->experimental_map_key(), target); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(999, this->uninterpreted_option(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); } // Extension range [1000, 536870912) @@ -4737,7 +5075,7 @@ int FieldOptions::ByteSize() const { // optional .google.protobuf.FieldOptions.CType ctype = 1; if (has_ctype()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::EnumSize(this->ctype()); + ::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype()); } // optional bool packed = 2; @@ -4753,7 +5091,8 @@ int FieldOptions::ByteSize() const { // optional string experimental_map_key = 9; if (has_experimental_map_key()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->experimental_map_key()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->experimental_map_key()); } } @@ -4761,7 +5100,7 @@ int FieldOptions::ByteSize() const { total_size += 2 * this->uninterpreted_option_size(); for (int i = 0; i < this->uninterpreted_option_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->uninterpreted_option(i)); } @@ -4844,30 +5183,29 @@ void FieldOptions::Swap(FieldOptions* other) { } } -const ::google::protobuf::Descriptor* FieldOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* FieldOptions::GetReflection() const { +::google::protobuf::Metadata FieldOptions::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return FieldOptions_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = FieldOptions_descriptor_; + metadata.reflection = FieldOptions_reflection_; + return metadata; } + // =================================================================== #ifndef _MSC_VER const int EnumOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -EnumOptions::EnumOptions() - : ::google::protobuf::Message() { +EnumOptions::EnumOptions() { SharedCtor(); } -void EnumOptions::InitAsDefaultInstance() {} +void EnumOptions::InitAsDefaultInstance() { +} -EnumOptions::EnumOptions(const EnumOptions& from) - : ::google::protobuf::Message() { +EnumOptions::EnumOptions(const EnumOptions& from) { SharedCtor(); MergeFrom(from); } @@ -4913,16 +5251,16 @@ bool EnumOptions::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_uninterpreted_option())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -4930,8 +5268,8 @@ bool EnumOptions::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } if ((8000u <= tag)) { @@ -4959,7 +5297,8 @@ void EnumOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 999, this->uninterpreted_option(i), output); } // Extension range [1000, 536870912) @@ -4976,7 +5315,9 @@ void EnumOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(999, this->uninterpreted_option(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); } // Extension range [1000, 536870912) @@ -4997,7 +5338,7 @@ int EnumOptions::ByteSize() const { total_size += 2 * this->uninterpreted_option_size(); for (int i = 0; i < this->uninterpreted_option_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->uninterpreted_option(i)); } @@ -5062,30 +5403,29 @@ void EnumOptions::Swap(EnumOptions* other) { } } -const ::google::protobuf::Descriptor* EnumOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* EnumOptions::GetReflection() const { +::google::protobuf::Metadata EnumOptions::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return EnumOptions_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = EnumOptions_descriptor_; + metadata.reflection = EnumOptions_reflection_; + return metadata; } + // =================================================================== #ifndef _MSC_VER const int EnumValueOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -EnumValueOptions::EnumValueOptions() - : ::google::protobuf::Message() { +EnumValueOptions::EnumValueOptions() { SharedCtor(); } -void EnumValueOptions::InitAsDefaultInstance() {} +void EnumValueOptions::InitAsDefaultInstance() { +} -EnumValueOptions::EnumValueOptions(const EnumValueOptions& from) - : ::google::protobuf::Message() { +EnumValueOptions::EnumValueOptions(const EnumValueOptions& from) { SharedCtor(); MergeFrom(from); } @@ -5131,16 +5471,16 @@ bool EnumValueOptions::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_uninterpreted_option())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -5148,8 +5488,8 @@ bool EnumValueOptions::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } if ((8000u <= tag)) { @@ -5177,7 +5517,8 @@ void EnumValueOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 999, this->uninterpreted_option(i), output); } // Extension range [1000, 536870912) @@ -5194,7 +5535,9 @@ void EnumValueOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(999, this->uninterpreted_option(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); } // Extension range [1000, 536870912) @@ -5215,7 +5558,7 @@ int EnumValueOptions::ByteSize() const { total_size += 2 * this->uninterpreted_option_size(); for (int i = 0; i < this->uninterpreted_option_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->uninterpreted_option(i)); } @@ -5280,30 +5623,29 @@ void EnumValueOptions::Swap(EnumValueOptions* other) { } } -const ::google::protobuf::Descriptor* EnumValueOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* EnumValueOptions::GetReflection() const { +::google::protobuf::Metadata EnumValueOptions::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return EnumValueOptions_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = EnumValueOptions_descriptor_; + metadata.reflection = EnumValueOptions_reflection_; + return metadata; } + // =================================================================== #ifndef _MSC_VER const int ServiceOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -ServiceOptions::ServiceOptions() - : ::google::protobuf::Message() { +ServiceOptions::ServiceOptions() { SharedCtor(); } -void ServiceOptions::InitAsDefaultInstance() {} +void ServiceOptions::InitAsDefaultInstance() { +} -ServiceOptions::ServiceOptions(const ServiceOptions& from) - : ::google::protobuf::Message() { +ServiceOptions::ServiceOptions(const ServiceOptions& from) { SharedCtor(); MergeFrom(from); } @@ -5349,16 +5691,16 @@ bool ServiceOptions::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_uninterpreted_option())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -5366,8 +5708,8 @@ bool ServiceOptions::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } if ((8000u <= tag)) { @@ -5395,7 +5737,8 @@ void ServiceOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 999, this->uninterpreted_option(i), output); } // Extension range [1000, 536870912) @@ -5412,7 +5755,9 @@ void ServiceOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(999, this->uninterpreted_option(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); } // Extension range [1000, 536870912) @@ -5433,7 +5778,7 @@ int ServiceOptions::ByteSize() const { total_size += 2 * this->uninterpreted_option_size(); for (int i = 0; i < this->uninterpreted_option_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->uninterpreted_option(i)); } @@ -5498,30 +5843,29 @@ void ServiceOptions::Swap(ServiceOptions* other) { } } -const ::google::protobuf::Descriptor* ServiceOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* ServiceOptions::GetReflection() const { +::google::protobuf::Metadata ServiceOptions::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return ServiceOptions_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = ServiceOptions_descriptor_; + metadata.reflection = ServiceOptions_reflection_; + return metadata; } + // =================================================================== #ifndef _MSC_VER const int MethodOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -MethodOptions::MethodOptions() - : ::google::protobuf::Message() { +MethodOptions::MethodOptions() { SharedCtor(); } -void MethodOptions::InitAsDefaultInstance() {} +void MethodOptions::InitAsDefaultInstance() { +} -MethodOptions::MethodOptions(const MethodOptions& from) - : ::google::protobuf::Message() { +MethodOptions::MethodOptions(const MethodOptions& from) { SharedCtor(); MergeFrom(from); } @@ -5567,16 +5911,16 @@ bool MethodOptions::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_uninterpreted_option())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -5584,8 +5928,8 @@ bool MethodOptions::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } if ((8000u <= tag)) { @@ -5613,7 +5957,8 @@ void MethodOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 999, this->uninterpreted_option(i), output); } // Extension range [1000, 536870912) @@ -5630,7 +5975,9 @@ void MethodOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(999, this->uninterpreted_option(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); } // Extension range [1000, 536870912) @@ -5651,7 +5998,7 @@ int MethodOptions::ByteSize() const { total_size += 2 * this->uninterpreted_option_size(); for (int i = 0; i < this->uninterpreted_option_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->uninterpreted_option(i)); } @@ -5716,15 +6063,15 @@ void MethodOptions::Swap(MethodOptions* other) { } } -const ::google::protobuf::Descriptor* MethodOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* MethodOptions::GetReflection() const { +::google::protobuf::Metadata MethodOptions::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return MethodOptions_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = MethodOptions_descriptor_; + metadata.reflection = MethodOptions_reflection_; + return metadata; } + // =================================================================== const ::std::string UninterpretedOption_NamePart::_default_name_part_; @@ -5733,15 +6080,14 @@ const int UninterpretedOption_NamePart::kNamePartFieldNumber; const int UninterpretedOption_NamePart::kIsExtensionFieldNumber; #endif // !_MSC_VER -UninterpretedOption_NamePart::UninterpretedOption_NamePart() - : ::google::protobuf::Message() { +UninterpretedOption_NamePart::UninterpretedOption_NamePart() { SharedCtor(); } -void UninterpretedOption_NamePart::InitAsDefaultInstance() {} +void UninterpretedOption_NamePart::InitAsDefaultInstance() { +} -UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from) - : ::google::protobuf::Message() { +UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from) { SharedCtor(); MergeFrom(from); } @@ -5798,26 +6144,30 @@ bool UninterpretedOption_NamePart::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // required string name_part = 1; case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name_part())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name_part())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name_part().data(), this->name_part().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(16)) goto parse_is_extension; break; } // required bool is_extension = 2; case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } parse_is_extension: - DO_(::google::protobuf::internal::WireFormat::ReadBool( + DO_(::google::protobuf::internal::WireFormatLite::ReadBool( input, &is_extension_)); _set_bit(1); if (input->ExpectAtEnd()) return true; @@ -5826,8 +6176,8 @@ bool UninterpretedOption_NamePart::MergePartialFromCodedStream( default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } DO_(::google::protobuf::internal::WireFormat::SkipField( @@ -5850,12 +6200,16 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes( // required string name_part = 1; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::WriteString(1, this->name_part(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name_part().data(), this->name_part().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name_part(), output); } // required bool is_extension = 2; if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::WriteBool(2, this->is_extension(), output); + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output); } if (!unknown_fields().empty()) { @@ -5868,12 +6222,17 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // required string name_part = 1; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(1, this->name_part(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name_part().data(), this->name_part().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name_part(), target); } // required bool is_extension = 2; if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormat::WriteBoolToArray(2, this->is_extension(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target); } if (!unknown_fields().empty()) { @@ -5890,7 +6249,8 @@ int UninterpretedOption_NamePart::ByteSize() const { // required string name_part = 1; if (has_name_part()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name_part()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name_part()); } // required bool is_extension = 2; @@ -5961,15 +6321,15 @@ void UninterpretedOption_NamePart::Swap(UninterpretedOption_NamePart* other) { } } -const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* UninterpretedOption_NamePart::GetReflection() const { +::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return UninterpretedOption_NamePart_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = UninterpretedOption_NamePart_descriptor_; + metadata.reflection = UninterpretedOption_NamePart_reflection_; + return metadata; } + // ------------------------------------------------------------------- const ::std::string UninterpretedOption::_default_identifier_value_; @@ -5983,15 +6343,14 @@ const int UninterpretedOption::kDoubleValueFieldNumber; const int UninterpretedOption::kStringValueFieldNumber; #endif // !_MSC_VER -UninterpretedOption::UninterpretedOption() - : ::google::protobuf::Message() { +UninterpretedOption::UninterpretedOption() { SharedCtor(); } -void UninterpretedOption::InitAsDefaultInstance() {} +void UninterpretedOption::InitAsDefaultInstance() { +} -UninterpretedOption::UninterpretedOption(const UninterpretedOption& from) - : ::google::protobuf::Message() { +UninterpretedOption::UninterpretedOption(const UninterpretedOption& from) { SharedCtor(); MergeFrom(from); } @@ -6062,16 +6421,16 @@ bool UninterpretedOption::MergePartialFromCodedStream( #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_name: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_name())); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_name())); if (input->ExpectTag(18)) goto parse_name; if (input->ExpectTag(26)) goto parse_identifier_value; break; @@ -6079,24 +6438,28 @@ bool UninterpretedOption::MergePartialFromCodedStream( // optional string identifier_value = 3; case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_identifier_value: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_identifier_value())); + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_identifier_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->identifier_value().data(), this->identifier_value().length(), + ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(32)) goto parse_positive_int_value; break; } // optional uint64 positive_int_value = 4; case 4: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } parse_positive_int_value: - DO_(::google::protobuf::internal::WireFormat::ReadUInt64( + DO_(::google::protobuf::internal::WireFormatLite::ReadUInt64( input, &positive_int_value_)); _set_bit(2); if (input->ExpectTag(40)) goto parse_negative_int_value; @@ -6105,12 +6468,12 @@ bool UninterpretedOption::MergePartialFromCodedStream( // optional int64 negative_int_value = 5; case 5: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { goto handle_uninterpreted; } parse_negative_int_value: - DO_(::google::protobuf::internal::WireFormat::ReadInt64( + DO_(::google::protobuf::internal::WireFormatLite::ReadInt64( input, &negative_int_value_)); _set_bit(3); if (input->ExpectTag(49)) goto parse_double_value; @@ -6119,12 +6482,12 @@ bool UninterpretedOption::MergePartialFromCodedStream( // optional double double_value = 6; case 6: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_FIXED64) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { goto handle_uninterpreted; } parse_double_value: - DO_(::google::protobuf::internal::WireFormat::ReadDouble( + DO_(::google::protobuf::internal::WireFormatLite::ReadDouble( input, &double_value_)); _set_bit(4); if (input->ExpectTag(58)) goto parse_string_value; @@ -6133,20 +6496,21 @@ bool UninterpretedOption::MergePartialFromCodedStream( // optional bytes string_value = 7; case 7: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { goto handle_uninterpreted; } parse_string_value: - DO_(::google::protobuf::internal::WireFormat::ReadBytes(input, mutable_string_value())); + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_string_value())); if (input->ExpectAtEnd()) return true; break; } default: { handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { return true; } DO_(::google::protobuf::internal::WireFormat::SkipField( @@ -6169,32 +6533,38 @@ void UninterpretedOption::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; for (int i = 0; i < this->name_size(); i++) { - ::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->name(i), output); + ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + 2, this->name(i), output); } // optional string identifier_value = 3; if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::WriteString(3, this->identifier_value(), output); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->identifier_value().data(), this->identifier_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->identifier_value(), output); } // optional uint64 positive_int_value = 4; if (_has_bit(2)) { - ::google::protobuf::internal::WireFormat::WriteUInt64(4, this->positive_int_value(), output); + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output); } // optional int64 negative_int_value = 5; if (_has_bit(3)) { - ::google::protobuf::internal::WireFormat::WriteInt64(5, this->negative_int_value(), output); + ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output); } // optional double double_value = 6; if (_has_bit(4)) { - ::google::protobuf::internal::WireFormat::WriteDouble(6, this->double_value(), output); + ::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output); } // optional bytes string_value = 7; if (_has_bit(5)) { - ::google::protobuf::internal::WireFormat::WriteBytes(7, this->string_value(), output); + ::google::protobuf::internal::WireFormatLite::WriteBytes( + 7, this->string_value(), output); } if (!unknown_fields().empty()) { @@ -6207,32 +6577,41 @@ void UninterpretedOption::SerializeWithCachedSizes( ::google::protobuf::uint8* target) const { // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; for (int i = 0; i < this->name_size(); i++) { - target = ::google::protobuf::internal::WireFormat::WriteMessageNoVirtualToArray(2, this->name(i), target); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->name(i), target); } // optional string identifier_value = 3; if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormat::WriteStringToArray(3, this->identifier_value(), target); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->identifier_value().data(), this->identifier_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->identifier_value(), target); } // optional uint64 positive_int_value = 4; if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormat::WriteUInt64ToArray(4, this->positive_int_value(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target); } // optional int64 negative_int_value = 5; if (_has_bit(3)) { - target = ::google::protobuf::internal::WireFormat::WriteInt64ToArray(5, this->negative_int_value(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target); } // optional double double_value = 6; if (_has_bit(4)) { - target = ::google::protobuf::internal::WireFormat::WriteDoubleToArray(6, this->double_value(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target); } // optional bytes string_value = 7; if (_has_bit(5)) { - target = ::google::protobuf::internal::WireFormat::WriteBytesToArray(7, this->string_value(), target); + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 7, this->string_value(), target); } if (!unknown_fields().empty()) { @@ -6249,20 +6628,21 @@ int UninterpretedOption::ByteSize() const { // optional string identifier_value = 3; if (has_identifier_value()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->identifier_value()); + ::google::protobuf::internal::WireFormatLite::StringSize( + this->identifier_value()); } // optional uint64 positive_int_value = 4; if (has_positive_int_value()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::UInt64Size( + ::google::protobuf::internal::WireFormatLite::UInt64Size( this->positive_int_value()); } // optional int64 negative_int_value = 5; if (has_negative_int_value()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::Int64Size( + ::google::protobuf::internal::WireFormatLite::Int64Size( this->negative_int_value()); } @@ -6274,7 +6654,8 @@ int UninterpretedOption::ByteSize() const { // optional bytes string_value = 7; if (has_string_value()) { total_size += 1 + - ::google::protobuf::internal::WireFormat::BytesSize(this->string_value()); + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->string_value()); } } @@ -6282,7 +6663,7 @@ int UninterpretedOption::ByteSize() const { total_size += 1 * this->name_size(); for (int i = 0; i < this->name_size(); i++) { total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->name(i)); } @@ -6364,14 +6745,14 @@ void UninterpretedOption::Swap(UninterpretedOption* other) { } } -const ::google::protobuf::Descriptor* UninterpretedOption::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* UninterpretedOption::GetReflection() const { +::google::protobuf::Metadata UninterpretedOption::GetMetadata() const { protobuf_AssignDescriptorsOnce(); - return UninterpretedOption_reflection_; + ::google::protobuf::Metadata metadata; + metadata.descriptor = UninterpretedOption_descriptor_; + metadata.reflection = UninterpretedOption_reflection_; + return metadata; } + } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 6be84719..782a9efb 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -18,9 +18,10 @@ #error regenerate this file with a newer version of protoc. #endif -#include +#include #include #include +#include namespace google { namespace protobuf { @@ -69,11 +70,11 @@ enum FieldDescriptorProto_Type { FieldDescriptorProto_Type_TYPE_SINT32 = 17, FieldDescriptorProto_Type_TYPE_SINT64 = 18 }; -LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor(); LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value); const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE; const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64; +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor(); inline const ::std::string& FieldDescriptorProto_Type_Name(FieldDescriptorProto_Type value) { return ::google::protobuf::internal::NameOfEnum( FieldDescriptorProto_Type_descriptor(), value); @@ -88,11 +89,11 @@ enum FieldDescriptorProto_Label { FieldDescriptorProto_Label_LABEL_REQUIRED = 2, FieldDescriptorProto_Label_LABEL_REPEATED = 3 }; -LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor(); LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value); const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL; const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED; +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor(); inline const ::std::string& FieldDescriptorProto_Label_Name(FieldDescriptorProto_Label value) { return ::google::protobuf::internal::NameOfEnum( FieldDescriptorProto_Label_descriptor(), value); @@ -104,13 +105,14 @@ inline bool FieldDescriptorProto_Label_Parse( } enum FileOptions_OptimizeMode { FileOptions_OptimizeMode_SPEED = 1, - FileOptions_OptimizeMode_CODE_SIZE = 2 + FileOptions_OptimizeMode_CODE_SIZE = 2, + FileOptions_OptimizeMode_LITE_RUNTIME = 3 }; -LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor(); LIBPROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value); const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED; -const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_CODE_SIZE; +const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_LITE_RUNTIME; +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor(); inline const ::std::string& FileOptions_OptimizeMode_Name(FileOptions_OptimizeMode value) { return ::google::protobuf::internal::NameOfEnum( FileOptions_OptimizeMode_descriptor(), value); @@ -124,11 +126,11 @@ enum FieldOptions_CType { FieldOptions_CType_CORD = 1, FieldOptions_CType_STRING_PIECE = 2 }; -LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor(); LIBPROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value); const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_CORD; const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE; +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor(); inline const ::std::string& FieldOptions_CType_Name(FieldOptions_CType value) { return ::google::protobuf::internal::NameOfEnum( FieldOptions_CType_descriptor(), value); @@ -187,8 +189,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -212,6 +213,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -277,8 +279,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -384,6 +385,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -449,8 +451,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -479,6 +480,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -544,8 +546,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -635,6 +636,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -700,8 +702,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -724,13 +725,17 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa static const Type TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64; static const Type TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32; static const Type TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64; + static inline bool Type_IsValid(int value) { + return FieldDescriptorProto_Type_IsValid(value); + } + static const Type Type_MIN = + FieldDescriptorProto_Type_Type_MIN; + static const Type Type_MAX = + FieldDescriptorProto_Type_Type_MAX; static inline const ::google::protobuf::EnumDescriptor* Type_descriptor() { return FieldDescriptorProto_Type_descriptor(); } - static inline bool Type_IsValid(int value) { - return FieldDescriptorProto_Type_IsValid(value); - } static inline const ::std::string& Type_Name(Type value) { return FieldDescriptorProto_Type_Name(value); } @@ -738,22 +743,22 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa Type* value) { return FieldDescriptorProto_Type_Parse(name, value); } - static const Type Type_MIN = - FieldDescriptorProto_Type_Type_MIN; - static const Type Type_MAX = - FieldDescriptorProto_Type_Type_MAX; typedef FieldDescriptorProto_Label Label; static const Label LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL; static const Label LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED; static const Label LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED; + static inline bool Label_IsValid(int value) { + return FieldDescriptorProto_Label_IsValid(value); + } + static const Label Label_MIN = + FieldDescriptorProto_Label_Label_MIN; + static const Label Label_MAX = + FieldDescriptorProto_Label_Label_MAX; static inline const ::google::protobuf::EnumDescriptor* Label_descriptor() { return FieldDescriptorProto_Label_descriptor(); } - static inline bool Label_IsValid(int value) { - return FieldDescriptorProto_Label_IsValid(value); - } static inline const ::std::string& Label_Name(Label value) { return FieldDescriptorProto_Label_Name(value); } @@ -761,10 +766,6 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa Label* value) { return FieldDescriptorProto_Label_Parse(name, value); } - static const Label Label_MIN = - FieldDescriptorProto_Label_Label_MIN; - static const Label Label_MAX = - FieldDescriptorProto_Label_Label_MAX; // accessors ------------------------------------------------------- @@ -855,6 +856,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -920,8 +922,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -965,6 +966,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -1030,8 +1032,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -1072,6 +1073,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -1137,8 +1139,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -1182,6 +1183,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -1247,8 +1249,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -1305,6 +1306,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -1370,21 +1372,25 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- typedef FileOptions_OptimizeMode OptimizeMode; static const OptimizeMode SPEED = FileOptions_OptimizeMode_SPEED; static const OptimizeMode CODE_SIZE = FileOptions_OptimizeMode_CODE_SIZE; + static const OptimizeMode LITE_RUNTIME = FileOptions_OptimizeMode_LITE_RUNTIME; + static inline bool OptimizeMode_IsValid(int value) { + return FileOptions_OptimizeMode_IsValid(value); + } + static const OptimizeMode OptimizeMode_MIN = + FileOptions_OptimizeMode_OptimizeMode_MIN; + static const OptimizeMode OptimizeMode_MAX = + FileOptions_OptimizeMode_OptimizeMode_MAX; static inline const ::google::protobuf::EnumDescriptor* OptimizeMode_descriptor() { return FileOptions_OptimizeMode_descriptor(); } - static inline bool OptimizeMode_IsValid(int value) { - return FileOptions_OptimizeMode_IsValid(value); - } static inline const ::std::string& OptimizeMode_Name(OptimizeMode value) { return FileOptions_OptimizeMode_Name(value); } @@ -1392,10 +1398,6 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { OptimizeMode* value) { return FileOptions_OptimizeMode_Parse(name, value); } - static const OptimizeMode OptimizeMode_MIN = - FileOptions_OptimizeMode_OptimizeMode_MIN; - static const OptimizeMode OptimizeMode_MAX = - FileOptions_OptimizeMode_OptimizeMode_MAX; // accessors ------------------------------------------------------- @@ -1459,6 +1461,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -1524,8 +1527,7 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -1538,6 +1540,13 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { inline bool message_set_wire_format() const; inline void set_message_set_wire_format(bool value); + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + inline bool has_no_standard_descriptor_accessor() const; + inline void clear_no_standard_descriptor_accessor(); + static const int kNoStandardDescriptorAccessorFieldNumber = 2; + inline bool no_standard_descriptor_accessor() const; + inline void set_no_standard_descriptor_accessor(bool value); + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; inline int uninterpreted_option_size() const; inline void clear_uninterpreted_option(); @@ -1555,11 +1564,13 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { mutable int _cached_size_; bool message_set_wire_format_; + bool no_standard_descriptor_accessor_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? inline bool _has_bit(int index) const { @@ -1624,21 +1635,24 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- typedef FieldOptions_CType CType; static const CType CORD = FieldOptions_CType_CORD; static const CType STRING_PIECE = FieldOptions_CType_STRING_PIECE; + static inline bool CType_IsValid(int value) { + return FieldOptions_CType_IsValid(value); + } + static const CType CType_MIN = + FieldOptions_CType_CType_MIN; + static const CType CType_MAX = + FieldOptions_CType_CType_MAX; static inline const ::google::protobuf::EnumDescriptor* CType_descriptor() { return FieldOptions_CType_descriptor(); } - static inline bool CType_IsValid(int value) { - return FieldOptions_CType_IsValid(value); - } static inline const ::std::string& CType_Name(CType value) { return FieldOptions_CType_Name(value); } @@ -1646,10 +1660,6 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { CType* value) { return FieldOptions_CType_Parse(name, value); } - static const CType CType_MIN = - FieldOptions_CType_CType_MIN; - static const CType CType_MAX = - FieldOptions_CType_CType_MAX; // accessors ------------------------------------------------------- @@ -1709,6 +1719,7 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -1774,8 +1785,7 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message { void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -1801,6 +1811,7 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message { friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -1866,8 +1877,7 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message { void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -1893,6 +1903,7 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message { friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -1958,8 +1969,7 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message { void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -1985,6 +1995,7 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message { friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -2050,8 +2061,7 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message { void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -2077,6 +2087,7 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message { friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -2142,8 +2153,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -2176,6 +2186,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -2241,8 +2252,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag void SetCachedSize(int size) const { _cached_size_ = size; } public: - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; + ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -2316,6 +2326,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? @@ -3647,6 +3658,22 @@ inline void MessageOptions::set_message_set_wire_format(bool value) { message_set_wire_format_ = value; } +// optional bool no_standard_descriptor_accessor = 2 [default = false]; +inline bool MessageOptions::has_no_standard_descriptor_accessor() const { + return _has_bit(1); +} +inline void MessageOptions::clear_no_standard_descriptor_accessor() { + no_standard_descriptor_accessor_ = false; + _clear_bit(1); +} +inline bool MessageOptions::no_standard_descriptor_accessor() const { + return no_standard_descriptor_accessor_; +} +inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) { + _set_bit(1); + no_standard_descriptor_accessor_ = value; +} + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; inline int MessageOptions::uninterpreted_option_size() const { return uninterpreted_option_.size(); @@ -4134,4 +4161,30 @@ inline ::std::string* UninterpretedOption::mutable_string_value() { } // namespace protobuf } // namespace google + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Type>() { + return ::google::protobuf::FieldDescriptorProto_Type_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Label>() { + return ::google::protobuf::FieldDescriptorProto_Label_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FileOptions_OptimizeMode>() { + return ::google::protobuf::FileOptions_OptimizeMode_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions_CType>() { + return ::google::protobuf::FieldOptions_CType_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + #endif // PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index 381a7438..4db88a82 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -247,8 +247,10 @@ message FileOptions { // Generated classes can be optimized for speed or code size. enum OptimizeMode { - SPEED = 1; // Generate complete code for parsing, serialization, etc. - CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. } optional OptimizeMode optimize_for = 9 [default=SPEED]; @@ -282,6 +284,11 @@ message MessageOptions { // the protocol compiler. optional bool message_set_wire_format = 1 [default=false]; + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default=false]; + // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index ce216135..8fcfba3e 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -2135,6 +2135,83 @@ TEST(CustomOptions, OptionsFromOtherFile) { EXPECT_EQ(FileOptions::SPEED, file->options().optimize_for()); } +TEST(CustomOptions, MessageOptionThreeFieldsSet) { + // This tests a bug which previously existed in custom options parsing. The + // bug occurred when you defined a custom option with message type and then + // set three fields of that option on a single definition (see the example + // below). The bug is a bit hard to explain, so check the change history if + // you want to know more. + DescriptorPool pool; + + FileDescriptorProto file_proto; + FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); + ASSERT_TRUE(pool.BuildFile(file_proto) != NULL); + + protobuf_unittest::TestMessageWithCustomOptions::descriptor() + ->file()->CopyTo(&file_proto); + ASSERT_TRUE(pool.BuildFile(file_proto) != NULL); + + // The following represents the definition: + // + // import "google/protobuf/unittest_custom_options.proto" + // package protobuf_unittest; + // message Foo { + // option (complex_opt1).foo = 1234; + // option (complex_opt1).foo2 = 1234; + // option (complex_opt1).foo3 = 1234; + // } + ASSERT_TRUE(TextFormat::ParseFromString( + "name: \"custom_options_import.proto\" " + "package: \"protobuf_unittest\" " + "dependency: \"google/protobuf/unittest_custom_options.proto\" " + "message_type { " + " name: \"Foo\" " + " options { " + " uninterpreted_option { " + " name { " + " name_part: \"complex_opt1\" " + " is_extension: true " + " } " + " name { " + " name_part: \"foo\" " + " is_extension: false " + " } " + " positive_int_value: 1234 " + " } " + " uninterpreted_option { " + " name { " + " name_part: \"complex_opt1\" " + " is_extension: true " + " } " + " name { " + " name_part: \"foo2\" " + " is_extension: false " + " } " + " positive_int_value: 1234 " + " } " + " uninterpreted_option { " + " name { " + " name_part: \"complex_opt1\" " + " is_extension: true " + " } " + " name { " + " name_part: \"foo3\" " + " is_extension: false " + " } " + " positive_int_value: 1234 " + " } " + " } " + "}", + &file_proto)); + + const FileDescriptor* file = pool.BuildFile(file_proto); + ASSERT_TRUE(file != NULL); + ASSERT_EQ(1, file->message_type_count()); + + const MessageOptions& options = file->message_type(0)->options(); + EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo()); +} + // =================================================================== @@ -2335,6 +2412,30 @@ TEST_F(ValidationErrorTest, UnknownDependency) { "bar.proto: bar.proto: OTHER: Import \"foo.proto\" has not been loaded.\n"); } +TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) { + // Used to crash: If we depend on a non-existent file and then refer to a + // package defined in a file that we didn't import, and that package is + // nested within a parent package which this file is also in, and we don't + // include that parent package in the name (i.e. we do a relative lookup)... + // Yes, really. + BuildFile( + "name: 'foo.proto' " + "package: 'outer.foo' "); + BuildFileWithErrors( + "name: 'bar.proto' " + "dependency: 'baz.proto' " + "package: 'outer.bar' " + "message_type { " + " name: 'Bar' " + " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }" + "}", + + "bar.proto: bar.proto: OTHER: Import \"baz.proto\" has not been loaded.\n" + "bar.proto: outer.bar.Bar.bar: TYPE: \"outer.foo\" seems to be defined in " + "\"foo.proto\", which is not imported by \"bar.proto\". To use it here, " + "please add the necessary import.\n"); +} + TEST_F(ValidationErrorTest, DupeFile) { BuildFile( "name: \"foo.proto\" " @@ -3345,6 +3446,50 @@ TEST_F(ValidationErrorTest, TryingToSetMessageValuedOption) { "message type.\n"); } +TEST_F(ValidationErrorTest, NotLiteImportsLite) { + BuildFile( + "name: \"bar.proto\" " + "options { optimize_for: LITE_RUNTIME } "); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"bar.proto\" ", + + "foo.proto: foo.proto: OTHER: Files that do not use optimize_for = " + "LITE_RUNTIME cannot import files which do use this option. This file " + "is not lite, but it imports \"bar.proto\" which is.\n"); +} + +TEST_F(ValidationErrorTest, LiteExtendsNotLite) { + BuildFile( + "name: \"bar.proto\" " + "message_type: {" + " name: \"Bar\"" + " extension_range { start: 1 end: 1000 }" + "}"); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"bar.proto\" " + "options { optimize_for: LITE_RUNTIME } " + "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL " + " type: TYPE_INT32 extendee: \"Bar\" }", + + "foo.proto: ext: EXTENDEE: Extensions to non-lite types can only be " + "declared in non-lite files. Note that you cannot extend a non-lite " + "type to contain a lite type, but the reverse is allowed.\n"); +} + +TEST_F(ValidationErrorTest, NoLiteServices) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "options { optimize_for: LITE_RUNTIME } " + "service { name: \"Foo\" }", + + "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot " + "define services.\n"); +} + TEST_F(ValidationErrorTest, RollbackAfterError) { // Build a file which contains every kind of construct but references an // undefined type. All these constructs will be added to the symbol table diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index be8235e7..f8b5b4ea 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -82,7 +83,6 @@ namespace protobuf { using internal::WireFormat; using internal::ExtensionSet; using internal::GeneratedMessageReflection; -using internal::GenericRepeatedField; // =================================================================== @@ -186,8 +186,7 @@ class DynamicMessage : public Message { int GetCachedSize() const; void SetCachedSize(int size) const; - const Descriptor* GetDescriptor() const; - const Reflection* GetReflection() const; + Metadata GetMetadata() const; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage); @@ -279,20 +278,10 @@ DynamicMessage::DynamicMessage(const TypeInfo* type_info) break; case FieldDescriptor::CPPTYPE_MESSAGE: { - // If this object is the prototype, its CPPTYPE_MESSAGE fields - // must be initialized later, in CrossLinkPrototypes(), so we don't - // initialize them here. - if (!is_prototype()) { - if (!field->is_repeated()) { - new(field_ptr) Message*(NULL); - } else { - const RepeatedPtrField* prototype_field = - reinterpret_cast*>( - type_info_->prototype->OffsetToPointer( - type_info_->offsets[i])); - new(field_ptr) RepeatedPtrField( - prototype_field->prototype()); - } + if (!field->is_repeated()) { + new(field_ptr) Message*(NULL); + } else { + new(field_ptr) RepeatedPtrField(); } break; } @@ -322,9 +311,33 @@ DynamicMessage::~DynamicMessage() { void* field_ptr = OffsetToPointer(type_info_->offsets[i]); if (field->is_repeated()) { - GenericRepeatedField* field = - reinterpret_cast(field_ptr); - field->~GenericRepeatedField(); + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE : \ + reinterpret_cast*>(field_ptr) \ + ->~RepeatedField(); \ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + reinterpret_cast*>(field_ptr) + ->~RepeatedPtrField(); + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: + reinterpret_cast*>(field_ptr) + ->~RepeatedPtrField(); + break; + } } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { string* ptr = *reinterpret_cast(field_ptr); @@ -353,24 +366,14 @@ void DynamicMessage::CrossLinkPrototypes() { const FieldDescriptor* field = descriptor->field(i); void* field_ptr = OffsetToPointer(type_info_->offsets[i]); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + !field->is_repeated()) { // For fields with message types, we need to cross-link with the // prototype for the field's type. - const Message* field_prototype = + // For singular fields, the field is just a pointer which should + // point to the prototype. + *reinterpret_cast(field_ptr) = factory->GetPrototype(field->message_type()); - - if (field->is_repeated()) { - // For repeated fields, we actually construct the RepeatedPtrField - // here, but only for fields with message types. All other repeated - // fields are constructed in DynamicMessage's constructor. - new(field_ptr) RepeatedPtrField(field_prototype); - } else { - // For singular fields, the field is just a pointer which should - // point to the prototype. (OK to const_cast here because the - // prototype itself will only be available const to the outside - // world.) - new(field_ptr) Message*(const_cast(field_prototype)); - } } } } @@ -392,12 +395,11 @@ void DynamicMessage::SetCachedSize(int size) const { cached_byte_size_ = size; } -const Descriptor* DynamicMessage::GetDescriptor() const { - return type_info_->type; -} - -const Reflection* DynamicMessage::GetReflection() const { - return type_info_->reflection.get(); +Metadata DynamicMessage::GetMetadata() const { + Metadata metadata; + metadata.descriptor = type_info_->type; + metadata.reflection = type_info_->reflection.get(); + return metadata; } // =================================================================== diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index 61b8daae..0f799a5b 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -36,14 +36,11 @@ #include #include #include -#include -#include -#include +#include #include #include -#include +#include #include -#include #include namespace google { @@ -52,13 +49,13 @@ namespace internal { namespace { -inline FieldDescriptor::Type real_type(FieldType type) { - GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE); - return static_cast(type); +inline WireFormatLite::FieldType real_type(FieldType type) { + GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE); + return static_cast(type); } -inline FieldDescriptor::CppType cpp_type(FieldType type) { - return FieldDescriptor::TypeToCppType(real_type(type)); +inline WireFormatLite::CppType cpp_type(FieldType type) { + return WireFormatLite::FieldTypeToCppType(real_type(type)); } // Registry stuff. @@ -72,13 +69,14 @@ struct ExtensionInfo { union { ExtensionSet::EnumValidityFunc* enum_is_valid; - const Message* message_prototype; + const MessageLite* message_prototype; }; }; -typedef hash_map, ExtensionInfo> ExtensionRegistry; +typedef hash_map, + ExtensionInfo> ExtensionRegistry; ExtensionRegistry* registry_ = NULL; -GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_); +GoogleOnceType registry_init_; void DeleteRegistry() { delete registry_; @@ -92,56 +90,58 @@ void InitRegistry() { // This function is only called at startup, so there is no need for thread- // safety. -void Register(const Message* containing_type, int number, ExtensionInfo info) { - GoogleOnceInit(®istry_init_, &InitRegistry); +void Register(const MessageLite* containing_type, + int number, ExtensionInfo info) { + ::google::protobuf::GoogleOnceInit(®istry_init_, &InitRegistry); if (!InsertIfNotPresent(registry_, make_pair(containing_type, number), info)) { GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \"" - << containing_type->GetDescriptor()->full_name() + << containing_type->GetTypeName() << "\", field number " << number << "."; } } const ExtensionInfo* FindRegisteredExtension( - const Message* containing_type, int number) { + const MessageLite* containing_type, int number) { return (registry_ == NULL) ? NULL : FindOrNull(*registry_, make_pair(containing_type, number)); } } // namespace -void ExtensionSet::RegisterExtension(const Message* containing_type, +void ExtensionSet::RegisterExtension(const MessageLite* containing_type, int number, FieldType type, bool is_repeated, bool is_packed) { - GOOGLE_CHECK_NE(type, FieldDescriptor::TYPE_ENUM); - GOOGLE_CHECK_NE(type, FieldDescriptor::TYPE_MESSAGE); - GOOGLE_CHECK_NE(type, FieldDescriptor::TYPE_GROUP); + GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM); + GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE); + GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP); ExtensionInfo info(type, is_repeated, is_packed); Register(containing_type, number, info); } -void ExtensionSet::RegisterEnumExtension(const Message* containing_type, +void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type, int number, FieldType type, bool is_repeated, bool is_packed, EnumValidityFunc* is_valid) { - GOOGLE_CHECK_EQ(type, FieldDescriptor::TYPE_ENUM); + GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM); ExtensionInfo info(type, is_repeated, is_packed); info.enum_is_valid = is_valid; Register(containing_type, number, info); } -void ExtensionSet::RegisterMessageExtension(const Message* containing_type, +void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type, int number, FieldType type, bool is_repeated, bool is_packed, - const Message* prototype) { - GOOGLE_CHECK(type == FieldDescriptor::TYPE_MESSAGE || - type == FieldDescriptor::TYPE_GROUP); + const MessageLite* prototype) { + GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE || + type == WireFormatLite::TYPE_GROUP); ExtensionInfo info(type, is_repeated, is_packed); info.message_prototype = prototype; Register(containing_type, number, info); } + // =================================================================== // Constructors and basic methods. @@ -154,24 +154,10 @@ ExtensionSet::~ExtensionSet() { } } -void ExtensionSet::AppendToList(const Descriptor* containing_type, - const DescriptorPool* pool, - vector* output) const { - for (map::const_iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - bool has = false; - if (iter->second.is_repeated) { - has = iter->second.GetSize() > 0; - } else { - has = !iter->second.is_cleared; - } - - if (has) { - output->push_back( - pool->FindExtensionByNumber(containing_type, iter->first)); - } - } -} +// Defined in extension_set_heavy.cc. +// void ExtensionSet::AppendToList(const Descriptor* containing_type, +// const DescriptorPool* pool, +// vector* output) const bool ExtensionSet::Has(int number) const { map::const_iterator iter = extensions_.find(number); @@ -195,11 +181,18 @@ void ExtensionSet::ClearExtension(int number) { // =================================================================== // Field accessors -#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ - GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \ - : FieldDescriptor::LABEL_OPTIONAL, \ - FieldDescriptor::LABEL_##LABEL); \ - GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE) +namespace { + +enum Cardinality { + REPEATED, + OPTIONAL +}; + +} // namespace + +#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ + GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \ + GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE) // ------------------------------------------------------------------- // Primitives @@ -222,7 +215,7 @@ void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \ Extension* extension; \ if (MaybeNewExtension(number, &extension)) { \ extension->type = type; \ - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_##UPPERCASE);\ + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ extension->is_repeated = false; \ } else { \ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \ @@ -251,7 +244,7 @@ void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \ Extension* extension; \ if (MaybeNewExtension(number, &extension)) { \ extension->type = type; \ - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_##UPPERCASE);\ + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ extension->is_repeated = true; \ extension->is_packed = packed; \ extension->repeated_##LOWERCASE##_value = new RepeatedField(); \ @@ -290,7 +283,7 @@ void ExtensionSet::SetEnum(int number, FieldType type, int value) { Extension* extension; if (MaybeNewExtension(number, &extension)) { extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_ENUM); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); extension->is_repeated = false; } else { GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM); @@ -318,7 +311,7 @@ void ExtensionSet::AddEnum(int number, FieldType type, Extension* extension; if (MaybeNewExtension(number, &extension)) { extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_ENUM); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); extension->is_repeated = true; extension->is_packed = packed; extension->repeated_enum_value = new RepeatedField(); @@ -348,7 +341,7 @@ string* ExtensionSet::MutableString(int number, FieldType type) { Extension* extension; if (MaybeNewExtension(number, &extension)) { extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_STRING); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); extension->is_repeated = false; extension->string_value = new string; } else { @@ -376,7 +369,7 @@ string* ExtensionSet::AddString(int number, FieldType type) { Extension* extension; if (MaybeNewExtension(number, &extension)) { extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_STRING); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); extension->is_repeated = true; extension->is_packed = false; extension->repeated_string_value = new RepeatedPtrField(); @@ -389,8 +382,8 @@ string* ExtensionSet::AddString(int number, FieldType type) { // ------------------------------------------------------------------- // Messages -const Message& ExtensionSet::GetMessage(int number, - const Message& default_value) const { +const MessageLite& ExtensionSet::GetMessage( + int number, const MessageLite& default_value) const { map::const_iterator iter = extensions_.find(number); if (iter == extensions_.end()) { // Not present. Return the default value. @@ -401,25 +394,17 @@ const Message& ExtensionSet::GetMessage(int number, } } -const Message& ExtensionSet::GetMessage(int number, - const Descriptor* message_type, - MessageFactory* factory) const { - map::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end() || iter->second.is_cleared) { - // Not present. Return the default value. - return *factory->GetPrototype(message_type); - } else { - GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); - return *iter->second.message_value; - } -} +// Defined in extension_set_heavy.cc. +// const MessageLite& ExtensionSet::GetMessage(int number, +// const Descriptor* message_type, +// MessageFactory* factory) const -Message* ExtensionSet::MutableMessage(int number, FieldType type, - const Message& prototype) { +MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, + const MessageLite& prototype) { Extension* extension; if (MaybeNewExtension(number, &extension)) { extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); extension->is_repeated = false; extension->message_value = prototype.New(); } else { @@ -429,72 +414,55 @@ Message* ExtensionSet::MutableMessage(int number, FieldType type, return extension->message_value; } -Message* ExtensionSet::MutableMessage(int number, FieldType type, - const Descriptor* message_type, - MessageFactory* factory) { - Extension* extension; - if (MaybeNewExtension(number, &extension)) { - extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); - extension->is_repeated = false; - extension->is_packed = false; - const Message* prototype = factory->GetPrototype(message_type); - GOOGLE_CHECK(prototype != NULL); - extension->message_value = prototype->New(); - } else { - GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); - } - extension->is_cleared = false; - return extension->message_value; -} +// Defined in extension_set_heavy.cc. +// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, +// const Descriptor* message_type, +// MessageFactory* factory) -const Message& ExtensionSet::GetRepeatedMessage(int number, int index) const { +const MessageLite& ExtensionSet::GetRepeatedMessage( + int number, int index) const { map::const_iterator iter = extensions_.find(number); GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE); return iter->second.repeated_message_value->Get(index); } -Message* ExtensionSet::MutableRepeatedMessage(int number, int index) { +MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) { map::iterator iter = extensions_.find(number); GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE); return iter->second.repeated_message_value->Mutable(index); } -Message* ExtensionSet::AddMessage(int number, FieldType type, - const Message& prototype) { +MessageLite* ExtensionSet::AddMessage(int number, FieldType type, + const MessageLite& prototype) { Extension* extension; if (MaybeNewExtension(number, &extension)) { extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); extension->is_repeated = true; extension->repeated_message_value = - new RepeatedPtrField(&prototype); + new RepeatedPtrField(); } else { GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); } - return extension->repeated_message_value->Add(); -} -Message* ExtensionSet::AddMessage(int number, FieldType type, - const Descriptor* message_type, - MessageFactory* factory) { - Extension* extension; - if (MaybeNewExtension(number, &extension)) { - extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); - extension->is_repeated = true; - const Message* prototype = factory->GetPrototype(message_type); - GOOGLE_CHECK(prototype != NULL); - extension->repeated_message_value = - new RepeatedPtrField(prototype); - } else { - GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); + // RepeatedPtrField does not know how to Add() since it cannot + // allocate an abstract object, so we have to be tricky. + MessageLite* result = extension->repeated_message_value + ->AddFromCleared >(); + if (result == NULL) { + result = prototype.New(); + extension->repeated_message_value->AddAllocated(result); } - return extension->repeated_message_value->Add(); + return result; } +// Defined in extension_set_heavy.cc. +// MessageLite* ExtensionSet::AddMessage(int number, FieldType type, +// const Descriptor* message_type, +// MessageFactory* factory) + #undef GOOGLE_DCHECK_TYPE void ExtensionSet::RemoveLast(int number) { @@ -505,35 +473,35 @@ void ExtensionSet::RemoveLast(int number) { GOOGLE_DCHECK(extension->is_repeated); switch(cpp_type(extension->type)) { - case FieldDescriptor::CPPTYPE_INT32: - extension->repeated_int32_value->RemoveLast(); + case WireFormatLite::CPPTYPE_INT32: + extension->repeated_int32_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_INT64: - extension->repeated_int64_value->RemoveLast(); + case WireFormatLite::CPPTYPE_INT64: + extension->repeated_int64_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_UINT32: - extension->repeated_uint32_value->RemoveLast(); + case WireFormatLite::CPPTYPE_UINT32: + extension->repeated_uint32_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_UINT64: - extension->repeated_uint64_value->RemoveLast(); + case WireFormatLite::CPPTYPE_UINT64: + extension->repeated_uint64_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_FLOAT: - extension->repeated_float_value->RemoveLast(); + case WireFormatLite::CPPTYPE_FLOAT: + extension->repeated_float_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_DOUBLE: - extension->repeated_double_value->RemoveLast(); + case WireFormatLite::CPPTYPE_DOUBLE: + extension->repeated_double_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_BOOL: - extension->repeated_bool_value->RemoveLast(); + case WireFormatLite::CPPTYPE_BOOL: + extension->repeated_bool_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_ENUM: - extension->repeated_enum_value->RemoveLast(); + case WireFormatLite::CPPTYPE_ENUM: + extension->repeated_enum_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_STRING: - extension->repeated_string_value->RemoveLast(); + case WireFormatLite::CPPTYPE_STRING: + extension->repeated_string_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_MESSAGE: - extension->repeated_message_value->RemoveLast(); + case WireFormatLite::CPPTYPE_MESSAGE: + extension->repeated_message_value->RemoveLast(); break; } } @@ -546,35 +514,35 @@ void ExtensionSet::SwapElements(int number, int index1, int index2) { GOOGLE_DCHECK(extension->is_repeated); switch(cpp_type(extension->type)) { - case FieldDescriptor::CPPTYPE_INT32: + case WireFormatLite::CPPTYPE_INT32: extension->repeated_int32_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_INT64: - extension->repeated_int64_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_INT64: + extension->repeated_int64_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_UINT32: + case WireFormatLite::CPPTYPE_UINT32: extension->repeated_uint32_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_UINT64: + case WireFormatLite::CPPTYPE_UINT64: extension->repeated_uint64_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_FLOAT: - extension->repeated_float_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_FLOAT: + extension->repeated_float_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_DOUBLE: - extension->repeated_double_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_DOUBLE: + extension->repeated_double_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_BOOL: - extension->repeated_bool_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_BOOL: + extension->repeated_bool_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_ENUM: - extension->repeated_enum_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_ENUM: + extension->repeated_enum_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_STRING: - extension->repeated_string_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_STRING: + extension->repeated_string_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_MESSAGE: - extension->repeated_message_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_MESSAGE: + extension->repeated_message_value->SwapElements(index1, index2); break; } } @@ -607,7 +575,7 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) { switch (cpp_type(other_extension.type)) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ if (is_new) { \ extension->repeated_##LOWERCASE##_value = \ new REPEATED_TYPE; \ @@ -627,20 +595,32 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) { HANDLE_TYPE( STRING, string, RepeatedPtrField< string>); #undef HANDLE_TYPE - case FieldDescriptor::CPPTYPE_MESSAGE: + case WireFormatLite::CPPTYPE_MESSAGE: if (is_new) { - extension->repeated_message_value = new RepeatedPtrField( - other_extension.repeated_message_value->prototype()); + extension->repeated_message_value = + new RepeatedPtrField(); + } + // We can't call RepeatedPtrField::MergeFrom() because + // it would attempt to allocate new objects. + RepeatedPtrField* other_repeated_message = + other_extension.repeated_message_value; + for (int i = 0; i < other_repeated_message->size(); i++) { + const MessageLite& other_message = other_repeated_message->Get(i); + MessageLite* target = extension->repeated_message_value + ->AddFromCleared >(); + if (target == NULL) { + target = other_message.New(); + extension->repeated_message_value->AddAllocated(target); + } + target->CheckTypeAndMergeFrom(other_message); } - extension->repeated_message_value->MergeFrom( - *other_extension.repeated_message_value); break; } } else { if (!other_extension.is_cleared) { switch (cpp_type(other_extension.type)) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ Set##CAMELCASE(iter->first, other_extension.type, \ other_extension.LOWERCASE##_value); \ break; @@ -654,14 +634,14 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) { HANDLE_TYPE( BOOL, bool, Bool); HANDLE_TYPE( ENUM, enum, Enum); #undef HANDLE_TYPE - case FieldDescriptor::CPPTYPE_STRING: + case WireFormatLite::CPPTYPE_STRING: SetString(iter->first, other_extension.type, *other_extension.string_value); break; - case FieldDescriptor::CPPTYPE_MESSAGE: + case WireFormatLite::CPPTYPE_MESSAGE: MutableMessage(iter->first, other_extension.type, *other_extension.message_value) - ->MergeFrom(*other_extension.message_value); + ->CheckTypeAndMergeFrom(*other_extension.message_value); break; } } @@ -679,7 +659,7 @@ bool ExtensionSet::IsInitialized() const { for (map::const_iterator iter = extensions_.begin(); iter != extensions_.end(); ++iter) { const Extension& extension = iter->second; - if (cpp_type(extension.type) == FieldDescriptor::CPPTYPE_MESSAGE) { + if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) { if (extension.is_repeated) { for (int i = 0; i < extension.repeated_message_value->size(); i++) { if (!extension.repeated_message_value->Get(i).IsInitialized()) { @@ -698,10 +678,10 @@ bool ExtensionSet::IsInitialized() const { } bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, - const Message* containing_type, - UnknownFieldSet* unknown_fields) { - int number = WireFormat::GetTagFieldNumber(tag); - WireFormat::WireType wire_type = WireFormat::GetTagWireType(tag); + const MessageLite* containing_type, + FieldSkipper* field_skipper) { + int number = WireFormatLite::GetTagFieldNumber(tag); + WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); const ExtensionInfo* extension = FindRegisteredExtension(containing_type, number); @@ -710,15 +690,15 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, if (extension == NULL) { is_unknown = true; } else if (extension->is_packed) { - is_unknown = (wire_type != WireFormat::WIRETYPE_LENGTH_DELIMITED); + is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED); } else { - WireFormat::WireType expected_wire_type = - WireFormat::WireTypeForFieldType(real_type(extension->type)); + WireFormatLite::WireType expected_wire_type = + WireFormatLite::WireTypeForFieldType(real_type(extension->type)); is_unknown = (wire_type != expected_wire_type); } if (is_unknown) { - WireFormat::SkipField(input, tag, unknown_fields); + field_skipper->SkipField(input, tag); } else if (extension->is_packed) { uint32 size; if (!input->ReadVarint32(&size)) return false; @@ -726,11 +706,11 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, switch (extension->type) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ + case WireFormatLite::TYPE_##UPPERCASE: \ while (input->BytesUntilLimit() > 0) { \ CPP_LOWERCASE value; \ - if (!WireFormat::Read##CAMELCASE(input, &value)) return false; \ - Add##CPP_CAMELCASE(number, FieldDescriptor::TYPE_##UPPERCASE, \ + if (!WireFormatLite::Read##CAMELCASE(input, &value)) return false; \ + Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ true, value); \ } \ break @@ -750,20 +730,20 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, HANDLE_TYPE( BOOL, Bool, Bool, bool); #undef HANDLE_TYPE - case FieldDescriptor::TYPE_ENUM: + case WireFormatLite::TYPE_ENUM: while (input->BytesUntilLimit() > 0) { int value; - if (!WireFormat::ReadEnum(input, &value)) return false; + if (!WireFormatLite::ReadEnum(input, &value)) return false; if (extension->enum_is_valid(value)) { - AddEnum(number, FieldDescriptor::TYPE_ENUM, true, value); + AddEnum(number, WireFormatLite::TYPE_ENUM, true, value); } } break; - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_BYTES: - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; break; } @@ -772,14 +752,14 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, } else { switch (extension->type) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: { \ + case WireFormatLite::TYPE_##UPPERCASE: { \ CPP_LOWERCASE value; \ - if (!WireFormat::Read##CAMELCASE(input, &value)) return false; \ + if (!WireFormatLite::Read##CAMELCASE(input, &value)) return false; \ if (extension->is_repeated) { \ - Add##CPP_CAMELCASE(number, FieldDescriptor::TYPE_##UPPERCASE, \ + Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ false, value); \ } else { \ - Set##CPP_CAMELCASE(number, FieldDescriptor::TYPE_##UPPERCASE, value);\ + Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value); \ } \ } break @@ -798,56 +778,54 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, HANDLE_TYPE( BOOL, Bool, Bool, bool); #undef HANDLE_TYPE - case FieldDescriptor::TYPE_ENUM: { + case WireFormatLite::TYPE_ENUM: { int value; - if (!WireFormat::ReadEnum(input, &value)) return false; + if (!WireFormatLite::ReadEnum(input, &value)) return false; if (!extension->enum_is_valid(value)) { // Invalid value. Treat as unknown. - if (unknown_fields != NULL) { - unknown_fields->AddVarint(number, value); - } + field_skipper->SkipUnknownEnum(number, value); } else if (extension->is_repeated) { - AddEnum(number, FieldDescriptor::TYPE_ENUM, false, value); + AddEnum(number, WireFormatLite::TYPE_ENUM, false, value); } else { - SetEnum(number, FieldDescriptor::TYPE_ENUM, value); + SetEnum(number, WireFormatLite::TYPE_ENUM, value); } break; } - case FieldDescriptor::TYPE_STRING: { + case WireFormatLite::TYPE_STRING: { string* value = extension->is_repeated ? - AddString(number, FieldDescriptor::TYPE_STRING) : - MutableString(number, FieldDescriptor::TYPE_STRING); - if (!WireFormat::ReadString(input, value)) return false; + AddString(number, WireFormatLite::TYPE_STRING) : + MutableString(number, WireFormatLite::TYPE_STRING); + if (!WireFormatLite::ReadString(input, value)) return false; break; } - case FieldDescriptor::TYPE_BYTES: { + case WireFormatLite::TYPE_BYTES: { string* value = extension->is_repeated ? - AddString(number, FieldDescriptor::TYPE_STRING) : - MutableString(number, FieldDescriptor::TYPE_STRING); - if (!WireFormat::ReadBytes(input, value)) return false; + AddString(number, WireFormatLite::TYPE_STRING) : + MutableString(number, WireFormatLite::TYPE_STRING); + if (!WireFormatLite::ReadBytes(input, value)) return false; break; } - case FieldDescriptor::TYPE_GROUP: { - Message* value = extension->is_repeated ? - AddMessage(number, FieldDescriptor::TYPE_GROUP, + case WireFormatLite::TYPE_GROUP: { + MessageLite* value = extension->is_repeated ? + AddMessage(number, WireFormatLite::TYPE_GROUP, *extension->message_prototype) : - MutableMessage(number, FieldDescriptor::TYPE_GROUP, + MutableMessage(number, WireFormatLite::TYPE_GROUP, *extension->message_prototype); - if (!WireFormat::ReadGroup(number, input, value)) return false; + if (!WireFormatLite::ReadGroup(number, input, value)) return false; break; } - case FieldDescriptor::TYPE_MESSAGE: { - Message* value = extension->is_repeated ? - AddMessage(number, FieldDescriptor::TYPE_MESSAGE, + case WireFormatLite::TYPE_MESSAGE: { + MessageLite* value = extension->is_repeated ? + AddMessage(number, WireFormatLite::TYPE_MESSAGE, *extension->message_prototype) : - MutableMessage(number, FieldDescriptor::TYPE_MESSAGE, + MutableMessage(number, WireFormatLite::TYPE_MESSAGE, *extension->message_prototype); - if (!WireFormat::ReadMessage(input, value)) return false; + if (!WireFormatLite::ReadMessage(input, value)) return false; break; } } @@ -856,6 +834,130 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, return true; } +bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, + const MessageLite* containing_type) { + FieldSkipper skipper; + return ParseField(tag, input, containing_type, &skipper); +} + +// Defined in extension_set_heavy.cc. +// bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, +// const MessageLite* containing_type, +// UnknownFieldSet* unknown_fields) + +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, + const MessageLite* containing_type, + FieldSkipper* field_skipper) { + while (true) { + uint32 tag = input->ReadTag(); + switch (tag) { + case 0: + return true; + case WireFormatLite::kMessageSetItemStartTag: + if (!ParseMessageSetItem(input, containing_type, field_skipper)) { + return false; + } + break; + default: + if (!ParseField(tag, input, containing_type, field_skipper)) { + return false; + } + break; + } + } +} + +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, + const MessageLite* containing_type) { + FieldSkipper skipper; + return ParseMessageSet(input, containing_type, &skipper); +} + +// Defined in extension_set_heavy.cc. +// bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, +// const MessageLite* containing_type, +// UnknownFieldSet* unknown_fields); + +bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, + const MessageLite* containing_type, + FieldSkipper* field_skipper) { + // TODO(kenton): It would be nice to share code between this and + // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the + // differences would be hard to factor out. + + // This method parses a group which should contain two fields: + // required int32 type_id = 2; + // required data message = 3; + + // Once we see a type_id, we'll construct a fake tag for this extension + // which is the tag it would have had under the proto2 extensions wire + // format. + uint32 fake_tag = 0; + + // If we see message data before the type_id, we'll append it to this so + // we can parse it later. This will probably never happen in practice, + // as no MessageSet encoder I know of writes the message before the type ID. + // But, it's technically valid so we should allow it. + // TODO(kenton): Use a Cord instead? Do I care? + string message_data; + + while (true) { + uint32 tag = input->ReadTag(); + if (tag == 0) return false; + + switch (tag) { + case WireFormatLite::kMessageSetTypeIdTag: { + uint32 type_id; + if (!input->ReadVarint32(&type_id)) return false; + fake_tag = WireFormatLite::MakeTag(type_id, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + + if (!message_data.empty()) { + // We saw some message data before the type_id. Have to parse it + // now. + io::CodedInputStream sub_input( + reinterpret_cast(message_data.data()), + message_data.size()); + if (!ParseField(fake_tag, &sub_input, + containing_type, field_skipper)) { + return false; + } + message_data.clear(); + } + + break; + } + + case WireFormatLite::kMessageSetMessageTag: { + if (fake_tag == 0) { + // We haven't seen a type_id yet. Append this data to message_data. + string temp; + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->ReadString(&temp, length)) return false; + message_data.append(temp); + } else { + // Already saw type_id, so we can parse this directly. + if (!ParseField(fake_tag, input, + containing_type, field_skipper)) { + return false; + } + } + + break; + } + + case WireFormatLite::kMessageSetItemEndTag: { + return true; + } + + default: { + if (!field_skipper->SkipField(input, tag)) return false; + } + } + } +} + void ExtensionSet::SerializeWithCachedSizes( int start_field_number, int end_field_number, io::CodedOutputStream* output) const { @@ -887,6 +989,31 @@ uint8* ExtensionSet::SerializeWithCachedSizesToArray( return target + written_bytes; } +void ExtensionSet::SerializeMessageSetWithCachedSizes( + io::CodedOutputStream* output) const { + map::const_iterator iter; + for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) { + iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output); + } +} + +uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray( + uint8* target) const { + // For now, just create an array output stream around the target and dispatch + // to SerializeWithCachedSizes(). Give the array output stream kint32max + // bytes; we will certainly write less than that. It is up to the caller to + // ensure that the buffer has sufficient space. + int written_bytes; + { + io::ArrayOutputStream array_stream(target, kint32max); + io::CodedOutputStream output_stream(&array_stream); + SerializeMessageSetWithCachedSizes(&output_stream); + written_bytes = output_stream.ByteCount(); + GOOGLE_DCHECK(!output_stream.HadError()); + } + return target + written_bytes; +} + int ExtensionSet::ByteSize() const { int total_size = 0; @@ -898,18 +1025,20 @@ int ExtensionSet::ByteSize() const { return total_size; } -int ExtensionSet::SpaceUsedExcludingSelf() const { - int total_size = - extensions_.size() * sizeof(map::value_type); - for (map::const_iterator iter = extensions_.begin(), - end = extensions_.end(); - iter != end; - ++iter) { - total_size += iter->second.SpaceUsedExcludingSelf(); +int ExtensionSet::MessageSetByteSize() const { + int total_size = 0; + + for (map::const_iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + total_size += iter->second.MessageSetItemByteSize(iter->first); } + return total_size; } +// Defined in extension_set_heavy.cc. +// int ExtensionSet::SpaceUsedExcludingSelf() const + bool ExtensionSet::MaybeNewExtension(int number, Extension** result) { pair::iterator, bool> insert_result = extensions_.insert(make_pair(number, Extension())); @@ -924,7 +1053,7 @@ void ExtensionSet::Extension::Clear() { if (is_repeated) { switch (cpp_type(type)) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ repeated_##LOWERCASE##_value->Clear(); \ break @@ -943,10 +1072,10 @@ void ExtensionSet::Extension::Clear() { } else { if (!is_cleared) { switch (cpp_type(type)) { - case FieldDescriptor::CPPTYPE_STRING: + case WireFormatLite::CPPTYPE_STRING: string_value->clear(); break; - case FieldDescriptor::CPPTYPE_MESSAGE: + case WireFormatLite::CPPTYPE_MESSAGE: message_value->Clear(); break; default: @@ -968,15 +1097,15 @@ void ExtensionSet::Extension::SerializeFieldWithCachedSizes( if (is_packed) { if (cached_size == 0) return; - WireFormat::WriteTag(number, WireFormat::WIRETYPE_LENGTH_DELIMITED, - output); + WireFormatLite::WriteTag(number, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); output->WriteVarint32(cached_size); switch (real_type(type)) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ + case WireFormatLite::TYPE_##UPPERCASE: \ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - WireFormat::Write##CAMELCASE##NoTag( \ + WireFormatLite::Write##CAMELCASE##NoTag( \ repeated_##LOWERCASE##_value->Get(i), output); \ } \ break @@ -997,19 +1126,19 @@ void ExtensionSet::Extension::SerializeFieldWithCachedSizes( HANDLE_TYPE( ENUM, Enum, enum); #undef HANDLE_TYPE - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_BYTES: - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; break; } } else { switch (real_type(type)) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ + case WireFormatLite::TYPE_##UPPERCASE: \ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - WireFormat::Write##CAMELCASE(number, \ + WireFormatLite::Write##CAMELCASE(number, \ repeated_##LOWERCASE##_value->Get(i), output); \ } \ break @@ -1038,8 +1167,8 @@ void ExtensionSet::Extension::SerializeFieldWithCachedSizes( } else if (!is_cleared) { switch (real_type(type)) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - WireFormat::Write##CAMELCASE(number, VALUE, output); \ + case WireFormatLite::TYPE_##UPPERCASE: \ + WireFormatLite::Write##CAMELCASE(number, VALUE, output); \ break HANDLE_TYPE( INT32, Int32, int32_value); @@ -1065,6 +1194,34 @@ void ExtensionSet::Extension::SerializeFieldWithCachedSizes( } } +void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes( + int number, + io::CodedOutputStream* output) const { + if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { + // Not a valid MessageSet extension, but serialize it the normal way. + SerializeFieldWithCachedSizes(number, output); + return; + } + + if (is_cleared) return; + + // Start group. + output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag); + + // Write type ID. + output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag); + output->WriteVarint32(number); + + // Write message. + output->WriteVarint32(WireFormatLite::kMessageSetMessageTag); + + output->WriteVarint32(message_value->GetCachedSize()); + message_value->SerializeWithCachedSizes(output); + + // End group. + output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag); +} + int ExtensionSet::Extension::ByteSize(int number) const { int result = 0; @@ -1072,9 +1229,9 @@ int ExtensionSet::Extension::ByteSize(int number) const { if (is_packed) { switch (real_type(type)) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ + case WireFormatLite::TYPE_##UPPERCASE: \ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - result += WireFormat::CAMELCASE##Size( \ + result += WireFormatLite::CAMELCASE##Size( \ repeated_##LOWERCASE##_value->Get(i)); \ } \ break @@ -1090,8 +1247,8 @@ int ExtensionSet::Extension::ByteSize(int number) const { // Stuff with fixed size. #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - result += WireFormat::k##CAMELCASE##Size * \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += WireFormatLite::k##CAMELCASE##Size * \ repeated_##LOWERCASE##_value->size(); \ break HANDLE_TYPE( FIXED32, Fixed32, uint32); @@ -1103,10 +1260,10 @@ int ExtensionSet::Extension::ByteSize(int number) const { HANDLE_TYPE( BOOL, Bool, bool); #undef HANDLE_TYPE - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_BYTES: - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; break; } @@ -1115,17 +1272,18 @@ int ExtensionSet::Extension::ByteSize(int number) const { if (result > 0) { result += io::CodedOutputStream::VarintSize32(result); result += io::CodedOutputStream::VarintSize32( - WireFormat::MakeTag(number, WireFormat::WIRETYPE_LENGTH_DELIMITED)); + WireFormatLite::MakeTag(number, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); } } else { - int tag_size = WireFormat::TagSize(number, real_type(type)); + int tag_size = WireFormatLite::TagSize(number, real_type(type)); switch (real_type(type)) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ + case WireFormatLite::TYPE_##UPPERCASE: \ result += tag_size * repeated_##LOWERCASE##_value->size(); \ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - result += WireFormat::CAMELCASE##Size( \ + result += WireFormatLite::CAMELCASE##Size( \ repeated_##LOWERCASE##_value->Get(i)); \ } \ break @@ -1145,8 +1303,8 @@ int ExtensionSet::Extension::ByteSize(int number) const { // Stuff with fixed size. #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - result += (tag_size + WireFormat::k##CAMELCASE##Size) * \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \ repeated_##LOWERCASE##_value->size(); \ break HANDLE_TYPE( FIXED32, Fixed32, uint32); @@ -1160,11 +1318,11 @@ int ExtensionSet::Extension::ByteSize(int number) const { } } } else if (!is_cleared) { - result += WireFormat::TagSize(number, real_type(type)); + result += WireFormatLite::TagSize(number, real_type(type)); switch (real_type(type)) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - result += WireFormat::CAMELCASE##Size(LOWERCASE); \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \ break HANDLE_TYPE( INT32, Int32, int32_value); @@ -1182,8 +1340,8 @@ int ExtensionSet::Extension::ByteSize(int number) const { // Stuff with fixed size. #define HANDLE_TYPE(UPPERCASE, CAMELCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - result += WireFormat::k##CAMELCASE##Size; \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += WireFormatLite::k##CAMELCASE##Size; \ break HANDLE_TYPE( FIXED32, Fixed32); HANDLE_TYPE( FIXED64, Fixed64); @@ -1199,11 +1357,34 @@ int ExtensionSet::Extension::ByteSize(int number) const { return result; } +int ExtensionSet::Extension::MessageSetItemByteSize(int number) const { + if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { + // Not a valid MessageSet extension, but compute the byte size for it the + // normal way. + return ByteSize(number); + } + + if (is_cleared) return 0; + + int our_size = WireFormatLite::kMessageSetItemTagsSize; + + // type_id + our_size += io::CodedOutputStream::VarintSize32(number); + + // message + int message_size = message_value->ByteSize(); + + our_size += io::CodedOutputStream::VarintSize32(message_size); + our_size += message_size; + + return our_size; +} + int ExtensionSet::Extension::GetSize() const { GOOGLE_DCHECK(is_repeated); switch (cpp_type(type)) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ return repeated_##LOWERCASE##_value->size() HANDLE_TYPE( INT32, int32); @@ -1227,7 +1408,7 @@ void ExtensionSet::Extension::Free() { if (is_repeated) { switch (cpp_type(type)) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ delete repeated_##LOWERCASE##_value; \ break @@ -1245,10 +1426,10 @@ void ExtensionSet::Extension::Free() { } } else { switch (cpp_type(type)) { - case FieldDescriptor::CPPTYPE_STRING: + case WireFormatLite::CPPTYPE_STRING: delete string_value; break; - case FieldDescriptor::CPPTYPE_MESSAGE: + case WireFormatLite::CPPTYPE_MESSAGE: delete message_value; break; default: @@ -1257,43 +1438,8 @@ void ExtensionSet::Extension::Free() { } } -int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { - int total_size = 0; - if (is_repeated) { - switch (cpp_type(type)) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ - total_size += sizeof(*repeated_##LOWERCASE##_value) + \ - repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE( UINT32, uint32); - HANDLE_TYPE( UINT64, uint64); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( DOUBLE, double); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, enum); - HANDLE_TYPE( STRING, string); - HANDLE_TYPE(MESSAGE, message); - } - } else { - switch (cpp_type(type)) { - case FieldDescriptor::CPPTYPE_STRING: - total_size += sizeof(*string_value) + - StringSpaceUsedExcludingSelf(*string_value); - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - total_size += message_value->SpaceUsed(); - break; - default: - // No extra storage costs for primitive types. - break; - } - } - return total_size; -} +// Defined in extension_set_heavy.cc. +// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index e04614cc..8c1d73b8 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -45,20 +45,23 @@ #include #include -#include namespace google { + namespace protobuf { class Descriptor; // descriptor.h class FieldDescriptor; // descriptor.h class DescriptorPool; // descriptor.h - class Message; // message.h + class MessageLite; // message_lite.h class MessageFactory; // message.h class UnknownFieldSet; // unknown_field_set.h namespace io { class CodedInputStream; // coded_stream.h class CodedOutputStream; // coded_stream.h } + namespace internal { + class FieldSkipper; // wire_format_lite.h + } template class RepeatedField; // repeated_field.h template class RepeatedPtrField; // repeated_field.h } @@ -66,9 +69,9 @@ namespace protobuf { namespace protobuf { namespace internal { -// Used to store values of type FieldDescriptor::Type without having to -// #include descriptor.h. Also, ensures that we use only one byte to store -// these values, which is important to keep the layout of +// Used to store values of type WireFormatLite::FieldType without having to +// #include wire_format_lite.h. Also, ensures that we use only one byte to +// store these values, which is important to keep the layout of // ExtensionSet::Extension small. typedef uint8 FieldType; @@ -98,17 +101,17 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // to look up extensions for parsed field numbers. Note that dynamic parsing // does not use ParseField(); only protocol-compiler-generated parsing // methods do. - static void RegisterExtension(const Message* containing_type, + static void RegisterExtension(const MessageLite* containing_type, int number, FieldType type, bool is_repeated, bool is_packed); - static void RegisterEnumExtension(const Message* containing_type, + static void RegisterEnumExtension(const MessageLite* containing_type, int number, FieldType type, bool is_repeated, bool is_packed, EnumValidityFunc* is_valid); - static void RegisterMessageExtension(const Message* containing_type, + static void RegisterMessageExtension(const MessageLite* containing_type, int number, FieldType type, bool is_repeated, bool is_packed, - const Message* prototype); + const MessageLite* prototype); // ================================================================= @@ -167,9 +170,10 @@ class LIBPROTOBUF_EXPORT ExtensionSet { bool GetBool (int number, bool default_value) const; int GetEnum (int number, int default_value) const; const string & GetString (int number, const string& default_value) const; - const Message& GetMessage(int number, const Message& default_value) const; - const Message& GetMessage(int number, const Descriptor* message_type, - MessageFactory* factory) const; + const MessageLite& GetMessage(int number, + const MessageLite& default_value) const; + const MessageLite& GetMessage(int number, const Descriptor* message_type, + MessageFactory* factory) const; void SetInt32 (int number, FieldType type, int32 value); void SetInt64 (int number, FieldType type, int64 value); @@ -181,11 +185,11 @@ class LIBPROTOBUF_EXPORT ExtensionSet { void SetEnum (int number, FieldType type, int value); void SetString(int number, FieldType type, const string& value); string * MutableString (int number, FieldType type); - Message* MutableMessage(int number, FieldType type, - const Message& prototype); - Message* MutableMessage(int number, FieldType type, - const Descriptor* message_type, - MessageFactory* factory); + MessageLite* MutableMessage(int number, FieldType type, + const MessageLite& prototype); + MessageLite* MutableMessage(int number, FieldType type, + const Descriptor* message_type, + MessageFactory* factory); // repeated fields ------------------------------------------------- @@ -198,7 +202,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { bool GetRepeatedBool (int number, int index) const; int GetRepeatedEnum (int number, int index) const; const string & GetRepeatedString (int number, int index) const; - const Message& GetRepeatedMessage(int number, int index) const; + const MessageLite& GetRepeatedMessage(int number, int index) const; void SetRepeatedInt32 (int number, int index, int32 value); void SetRepeatedInt64 (int number, int index, int64 value); @@ -210,7 +214,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { void SetRepeatedEnum (int number, int index, int value); void SetRepeatedString(int number, int index, const string& value); string * MutableRepeatedString (int number, int index); - Message* MutableRepeatedMessage(int number, int index); + MessageLite* MutableRepeatedMessage(int number, int index); void AddInt32 (int number, FieldType type, bool packed, int32 value); void AddInt64 (int number, FieldType type, bool packed, int64 value); @@ -222,11 +226,11 @@ class LIBPROTOBUF_EXPORT ExtensionSet { void AddEnum (int number, FieldType type, bool packed, int value); void AddString(int number, FieldType type, const string& value); string * AddString (int number, FieldType type); - Message* AddMessage(int number, FieldType type, - const Message& prototype); - Message* AddMessage(int number, FieldType type, - const Descriptor* message_type, - MessageFactory* factory); + MessageLite* AddMessage(int number, FieldType type, + const MessageLite& prototype); + MessageLite* AddMessage(int number, FieldType type, + const Descriptor* message_type, + MessageFactory* factory); void RemoveLast(int number); void SwapElements(int number, int index1, int index2); @@ -252,9 +256,31 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // methods of ExtensionSet, this only works for generated message types -- // it looks up extensions registered using RegisterExtension(). bool ParseField(uint32 tag, io::CodedInputStream* input, - const Message* containing_type, + const MessageLite* containing_type, + FieldSkipper* field_skipper); + + // Specific versions for lite or full messages (constructs the appropriate + // FieldSkipper automatically). + bool ParseField(uint32 tag, io::CodedInputStream* input, + const MessageLite* containing_type); + bool ParseField(uint32 tag, io::CodedInputStream* input, + const MessageLite* containing_type, UnknownFieldSet* unknown_fields); + // Parse an entire message in MessageSet format. Such messages have no + // fields, only extensions. + bool ParseMessageSet(io::CodedInputStream* input, + const MessageLite* containing_type, + FieldSkipper* field_skipper); + + // Specific versions for lite or full messages (constructs the appropriate + // FieldSkipper automatically). + bool ParseMessageSet(io::CodedInputStream* input, + const MessageLite* containing_type); + bool ParseMessageSet(io::CodedInputStream* input, + const MessageLite* containing_type, + UnknownFieldSet* unknown_fields); + // Write all extension fields with field numbers in the range // [start_field_number, end_field_number) // to the output stream, using the cached sizes computed when ByteSize() was @@ -272,37 +298,50 @@ class LIBPROTOBUF_EXPORT ExtensionSet { int end_field_number, uint8* target) const; + // Like above but serializes in MessageSet format. + void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const; + uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const; + // Returns the total serialized size of all the extensions. int ByteSize() const; + // Like ByteSize() but uses MessageSet format. + int MessageSetByteSize() const; + // Returns (an estimate of) the total number of bytes used for storing the - // extensions in memory, excluding sizeof(*this). + // extensions in memory, excluding sizeof(*this). If the ExtensionSet is + // for a lite message (and thus possibly contains lite messages), the results + // are undefined (might work, might crash, might corrupt data, might not even + // be linked in). It's up to the protocol compiler to avoid calling this on + // such ExtensionSets (easy enough since lite messages don't implement + // SpaceUsed()). int SpaceUsedExcludingSelf() const; private: + struct Extension { union { - int32 int32_value; - int64 int64_value; - uint32 uint32_value; - uint64 uint64_value; - float float_value; - double double_value; - bool bool_value; - int enum_value; - string* string_value; - Message* message_value; - - RepeatedField * repeated_int32_value; - RepeatedField * repeated_int64_value; - RepeatedField * repeated_uint32_value; - RepeatedField * repeated_uint64_value; - RepeatedField * repeated_float_value; - RepeatedField * repeated_double_value; - RepeatedField * repeated_bool_value; - RepeatedField * repeated_enum_value; - RepeatedPtrField* repeated_string_value; - RepeatedPtrField* repeated_message_value; + int32 int32_value; + int64 int64_value; + uint32 uint32_value; + uint64 uint64_value; + float float_value; + double double_value; + bool bool_value; + int enum_value; + string* string_value; + MessageLite* message_value; + + RepeatedField * repeated_int32_value; + RepeatedField * repeated_int64_value; + RepeatedField * repeated_uint32_value; + RepeatedField * repeated_uint64_value; + RepeatedField * repeated_float_value; + RepeatedField * repeated_double_value; + RepeatedField * repeated_bool_value; + RepeatedField * repeated_enum_value; + RepeatedPtrField* repeated_string_value; + RepeatedPtrField* repeated_message_value; }; FieldType type; @@ -328,7 +367,11 @@ class LIBPROTOBUF_EXPORT ExtensionSet { void SerializeFieldWithCachedSizes( int number, io::CodedOutputStream* output) const; + void SerializeMessageSetItemWithCachedSizes( + int number, + io::CodedOutputStream* output) const; int ByteSize(int number) const; + int MessageSetItemByteSize(int number) const; void Clear(); int GetSize() const; void Free(); @@ -339,6 +382,13 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // already exist. Returns true if the extension did not already exist. bool MaybeNewExtension(int number, Extension** result); + // Parse a single MessageSet item -- called just after the item group start + // tag has been read. + bool ParseMessageSetItem(io::CodedInputStream* input, + const MessageLite* containing_type, + FieldSkipper* field_skipper); + + // The Extension struct is small enough to be passed by value, so we use it // directly as the value type in the map rather than use pointers. We use // a map rather than hash_map here because we expect most ExtensionSets will diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc new file mode 100644 index 00000000..dbe9e336 --- /dev/null +++ b/src/google/protobuf/extension_set_heavy.cc @@ -0,0 +1,218 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Contains methods defined in extension_set.h which cannot be part of the +// lite library because they use descriptors or reflection. + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +void ExtensionSet::AppendToList(const Descriptor* containing_type, + const DescriptorPool* pool, + vector* output) const { + for (map::const_iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + bool has = false; + if (iter->second.is_repeated) { + has = iter->second.GetSize() > 0; + } else { + has = !iter->second.is_cleared; + } + + if (has) { + output->push_back( + pool->FindExtensionByNumber(containing_type, iter->first)); + } + } +} + +inline FieldDescriptor::CppType cpp_type(FieldType type) { + return FieldDescriptor::TypeToCppType( + static_cast(type)); +} + +#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ + GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \ + : FieldDescriptor::LABEL_OPTIONAL, \ + FieldDescriptor::LABEL_##LABEL); \ + GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE) + +const MessageLite& ExtensionSet::GetMessage(int number, + const Descriptor* message_type, + MessageFactory* factory) const { + map::const_iterator iter = extensions_.find(number); + if (iter == extensions_.end() || iter->second.is_cleared) { + // Not present. Return the default value. + return *factory->GetPrototype(message_type); + } else { + GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); + return *iter->second.message_value; + } +} + +MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, + const Descriptor* message_type, + MessageFactory* factory) { + Extension* extension; + if (MaybeNewExtension(number, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); + extension->is_repeated = false; + extension->is_packed = false; + const MessageLite* prototype = factory->GetPrototype(message_type); + GOOGLE_CHECK(prototype != NULL); + extension->message_value = prototype->New(); + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); + } + extension->is_cleared = false; + return extension->message_value; +} + +MessageLite* ExtensionSet::AddMessage(int number, FieldType type, + const Descriptor* message_type, + MessageFactory* factory) { + Extension* extension; + if (MaybeNewExtension(number, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); + extension->is_repeated = true; + extension->repeated_message_value = + new RepeatedPtrField(); + } else { + GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); + } + + // RepeatedPtrField does not know how to Add() since it cannot + // allocate an abstract object, so we have to be tricky. + MessageLite* result = extension->repeated_message_value + ->AddFromCleared >(); + if (result == NULL) { + const MessageLite* prototype; + if (extension->repeated_message_value->size() == 0) { + prototype = factory->GetPrototype(message_type); + GOOGLE_CHECK(prototype != NULL); + } else { + prototype = &extension->repeated_message_value->Get(0); + } + result = prototype->New(); + extension->repeated_message_value->AddAllocated(result); + } + return result; +} + +bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, + const MessageLite* containing_type, + UnknownFieldSet* unknown_fields) { + UnknownFieldSetFieldSkipper skipper(unknown_fields); + return ParseField(tag, input, containing_type, &skipper); +} + +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, + const MessageLite* containing_type, + UnknownFieldSet* unknown_fields) { + UnknownFieldSetFieldSkipper skipper(unknown_fields); + return ParseMessageSet(input, containing_type, &skipper); +} + +int ExtensionSet::SpaceUsedExcludingSelf() const { + int total_size = + extensions_.size() * sizeof(map::value_type); + for (map::const_iterator iter = extensions_.begin(), + end = extensions_.end(); + iter != end; + ++iter) { + total_size += iter->second.SpaceUsedExcludingSelf(); + } + return total_size; +} + +int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { + int total_size = 0; + if (is_repeated) { + switch (cpp_type(type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ + total_size += sizeof(*repeated_##LOWERCASE##_value) + \ + repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE( UINT32, uint32); + HANDLE_TYPE( UINT64, uint64); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( DOUBLE, double); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, enum); + HANDLE_TYPE( STRING, string); + + case WireFormatLite::CPPTYPE_MESSAGE: + // repeated_message_value is actually a RepeatedPtrField, + // but MessageLite has no SpaceUsed(), so we must directly call + // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type + // handler. + total_size += sizeof(*repeated_message_value) + + repeated_message_value-> + RepeatedPtrFieldBase::SpaceUsedExcludingSelf< + GenericTypeHandler >(); + break; + } + } else { + switch (cpp_type(type)) { + case WireFormatLite::CPPTYPE_STRING: + total_size += sizeof(*string_value) + + StringSpaceUsedExcludingSelf(*string_value); + break; + case WireFormatLite::CPPTYPE_MESSAGE: + total_size += down_cast(message_value)->SpaceUsed(); + break; + default: + // No extra storage costs for primitive types. + break; + } + } + return total_size; +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 0cd367de..d294e587 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -38,6 +38,7 @@ #include #include #include +#include #include namespace google { @@ -220,8 +221,36 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const { const FieldDescriptor* field = descriptor_->field(i); if (field->is_repeated()) { - total_size += GetRaw(message, field) - .GenericSpaceUsedExcludingSelf(); + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE : \ + total_size += GetRaw >(message, field) \ + .SpaceUsedExcludingSelf(); \ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + total_size += GetRaw >(message, field) + .SpaceUsedExcludingSelf(); + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: + // We don't know which subclass of RepeatedPtrFieldBase the type is, + // so we use RepeatedPtrFieldBase directly. + total_size += + GetRaw(message, field) + .SpaceUsedExcludingSelf >(); + break; + } } else { switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32 : @@ -274,25 +303,59 @@ void GeneratedMessageReflection::Swap( Message* message2) const { if (message1 == message2) return; + // TODO(kenton): Other Reflection methods should probably check this too. GOOGLE_CHECK_EQ(message1->GetReflection(), this) - << "Tried to swap using reflection object incompatible with message1."; - + << "First argument to Swap() (of type \"" + << message1->GetDescriptor()->full_name() + << "\") is not compatible with this reflection object (which is for type \"" + << descriptor_->full_name() + << "\"). Note that the exact same class is required; not just the same " + "descriptor."; GOOGLE_CHECK_EQ(message2->GetReflection(), this) - << "Tried to swap using reflection object incompatible with message2."; + << "Second argument to Swap() (of type \"" + << message1->GetDescriptor()->full_name() + << "\") is not compatible with this reflection object (which is for type \"" + << descriptor_->full_name() + << "\"). Note that the exact same class is required; not just the same " + "descriptor."; uint32* has_bits1 = MutableHasBits(message1); uint32* has_bits2 = MutableHasBits(message2); int has_bits_size = (descriptor_->field_count() + 31) / 32; for (int i = 0; i < has_bits_size; i++) { - std::swap(has_bits1[i], has_bits2[i]); + swap(has_bits1[i], has_bits2[i]); } for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); if (field->is_repeated()) { - MutableRaw(message1, field)->GenericSwap( - MutableRaw(message2, field)); + switch (field->cpp_type()) { +#define SWAP_ARRAYS(CPPTYPE, TYPE) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + MutableRaw >(message1, field)->Swap( \ + MutableRaw >(message2, field)); \ + break; + + SWAP_ARRAYS(INT32 , int32 ); + SWAP_ARRAYS(INT64 , int64 ); + SWAP_ARRAYS(UINT32, uint32); + SWAP_ARRAYS(UINT64, uint64); + SWAP_ARRAYS(FLOAT , float ); + SWAP_ARRAYS(DOUBLE, double); + SWAP_ARRAYS(BOOL , bool ); + SWAP_ARRAYS(ENUM , int ); +#undef SWAP_ARRAYS + + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + MutableRaw(message1, field)->Swap( + MutableRaw(message2, field)); + break; + + default: + GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type(); + } } else { switch (field->cpp_type()) { #define SWAP_VALUES(CPPTYPE, TYPE) \ @@ -300,6 +363,7 @@ void GeneratedMessageReflection::Swap( swap(*MutableRaw(message1, field), \ *MutableRaw(message2, field)); \ break; + SWAP_VALUES(INT32 , int32 ); SWAP_VALUES(INT64 , int64 ); SWAP_VALUES(UINT32, uint32); @@ -307,10 +371,15 @@ void GeneratedMessageReflection::Swap( SWAP_VALUES(FLOAT , float ); SWAP_VALUES(DOUBLE, double); SWAP_VALUES(BOOL , bool ); - SWAP_VALUES(ENUM , int32 ); - SWAP_VALUES(STRING, string*); + SWAP_VALUES(ENUM , int ); SWAP_VALUES(MESSAGE, Message*); -#undef SWAP_PRIMITIVE_VALUES +#undef SWAP_VALUES + + case FieldDescriptor::CPPTYPE_STRING: + swap(*MutableRaw(message1, field), + *MutableRaw(message2, field)); + break; + default: GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type(); } @@ -346,7 +415,28 @@ int GeneratedMessageReflection::FieldSize(const Message& message, if (field->is_extension()) { return GetExtensionSet(message).ExtensionSize(field->number()); } else { - return GetRaw(message, field).GenericSize(); + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE : \ + return GetRaw >(message, field).size() + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + return GetRaw(message, field).size(); + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return 0; } } @@ -401,7 +491,35 @@ void GeneratedMessageReflection::ClearField( } } } else { - MutableRaw(message, field)->GenericClear(); + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE : \ + MutableRaw >(message, field)->Clear(); \ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: { + MutableRaw >(message, field)->Clear(); + break; + } + + case FieldDescriptor::CPPTYPE_MESSAGE: { + // We don't know which subclass of RepeatedPtrFieldBase the type is, + // so we use RepeatedPtrFieldBase directly. + MutableRaw(message, field) + ->Clear >(); + break; + } + } } } @@ -414,7 +532,31 @@ void GeneratedMessageReflection::RemoveLast( if (field->is_extension()) { MutableExtensionSet(message)->RemoveLast(field->number()); } else { - MutableRaw(message, field)->GenericRemoveLast(); + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE : \ + MutableRaw >(message, field)->RemoveLast(); \ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + MutableRaw >(message, field)->RemoveLast(); + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: + MutableRaw(message, field) + ->RemoveLast >(); + break; + } } } @@ -427,11 +569,31 @@ void GeneratedMessageReflection::SwapElements( USAGE_CHECK_REPEATED(Swap); if (field->is_extension()) { - MutableExtensionSet(message)->SwapElements( - field->number(), index1, index2); + MutableExtensionSet(message)->SwapElements(field->number(), index1, index2); } else { - MutableRaw(message, field)->GenericSwapElements( - index1, index2); + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE : \ + MutableRaw >(message, field) \ + ->SwapElements(index1, index2); \ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + MutableRaw(message, field) + ->SwapElements(index1, index2); + break; + } } } @@ -456,7 +618,7 @@ void GeneratedMessageReflection::ListFields( for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); if (field->is_repeated()) { - if (GetRaw(message, field).GenericSize() > 0) { + if (FieldSize(message, field) > 0) { output->push_back(field); } } else { @@ -597,7 +759,7 @@ string GeneratedMessageReflection::GetRepeatedString( if (field->is_extension()) { return GetExtensionSet(message).GetRepeatedString(field->number(), index); } else { - return GetRepeatedField(message, field, index); + return GetRepeatedPtrField(message, field, index); } } @@ -608,7 +770,7 @@ const string& GeneratedMessageReflection::GetRepeatedStringReference( if (field->is_extension()) { return GetExtensionSet(message).GetRepeatedString(field->number(), index); } else { - return GetRepeatedField(message, field, index); + return GetRepeatedPtrField(message, field, index); } } @@ -621,7 +783,7 @@ void GeneratedMessageReflection::SetRepeatedString( MutableExtensionSet(message)->SetRepeatedString( field->number(), index, value); } else { - SetRepeatedField(message, field, index, value); + *MutableRepeatedField(message, field, index) = value; } } @@ -634,7 +796,7 @@ void GeneratedMessageReflection::AddString( MutableExtensionSet(message)->AddString(field->number(), field->type(), value); } else { - AddField(message, field, value); + *AddField(message, field) = value; } } @@ -725,9 +887,10 @@ const Message& GeneratedMessageReflection::GetMessage( USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE); if (field->is_extension()) { - return GetExtensionSet(message).GetMessage(field->number(), - field->message_type(), - message_factory_); + return static_cast( + GetExtensionSet(message).GetMessage(field->number(), + field->message_type(), + message_factory_)); } else { const Message* result = GetRaw(message, field); if (result == NULL) { @@ -742,10 +905,11 @@ Message* GeneratedMessageReflection::MutableMessage( USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE); if (field->is_extension()) { - return MutableExtensionSet(message)->MutableMessage(field->number(), - field->type(), - field->message_type(), - message_factory_); + return static_cast( + MutableExtensionSet(message)->MutableMessage(field->number(), + field->type(), + field->message_type(), + message_factory_)); } else { Message** result = MutableField(message, field); if (*result == NULL) { @@ -761,9 +925,11 @@ const Message& GeneratedMessageReflection::GetRepeatedMessage( USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE); if (field->is_extension()) { - return GetExtensionSet(message).GetRepeatedMessage(field->number(), index); + return static_cast( + GetExtensionSet(message).GetRepeatedMessage(field->number(), index)); } else { - return GetRepeatedField(message, field, index); + return GetRaw(message, field) + .Get >(index); } } @@ -772,10 +938,12 @@ Message* GeneratedMessageReflection::MutableRepeatedMessage( USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE); if (field->is_extension()) { - return MutableExtensionSet(message)->MutableRepeatedMessage( - field->number(), index); + return static_cast( + MutableExtensionSet(message)->MutableRepeatedMessage( + field->number(), index)); } else { - return MutableRepeatedField(message, field, index); + return MutableRaw(message, field) + ->Mutable >(index); } } @@ -784,12 +952,29 @@ Message* GeneratedMessageReflection::AddMessage( USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE); if (field->is_extension()) { - return MutableExtensionSet(message)->AddMessage(field->number(), - field->type(), - field->message_type(), - message_factory_); + return static_cast( + MutableExtensionSet(message)->AddMessage(field->number(), + field->type(), + field->message_type(), + message_factory_)); } else { - return AddField(message, field); + // We can't use AddField() because RepeatedPtrFieldBase doesn't + // know how to allocate one. + RepeatedPtrFieldBase* repeated = + MutableRaw(message, field); + Message* result = repeated->AddFromCleared >(); + if (result == NULL) { + // We must allocate a new object. + const Message* prototype; + if (repeated->size() == 0) { + prototype = message_factory_->GetPrototype(field->message_type()); + } else { + prototype = &repeated->Get >(0); + } + result = prototype->New(); + repeated->AddAllocated >(result); + } + return result; } } @@ -925,46 +1110,46 @@ inline Type* GeneratedMessageReflection::MutableField( } template -inline const Type& GeneratedMessageReflection::GetRepeatedField( +inline Type GeneratedMessageReflection::GetRepeatedField( + const Message& message, const FieldDescriptor* field, int index) const { + return GetRaw >(message, field).Get(index); +} + +template +inline const Type& GeneratedMessageReflection::GetRepeatedPtrField( const Message& message, const FieldDescriptor* field, int index) const { - return *reinterpret_cast( - GetRaw(message, field).GenericGet(index)); + return GetRaw >(message, field).Get(index); } template inline void GeneratedMessageReflection::SetRepeatedField( Message* message, const FieldDescriptor* field, - int index, const Type& value) const { - GenericRepeatedField* repeated = - MutableRaw(message, field); - *reinterpret_cast(repeated->GenericMutable(index)) = value; + int index, Type value) const { + MutableRaw >(message, field)->Set(index, value); } template inline Type* GeneratedMessageReflection::MutableRepeatedField( Message* message, const FieldDescriptor* field, int index) const { - GenericRepeatedField* repeated = - MutableRaw(message, field); - return reinterpret_cast(repeated->GenericMutable(index)); + RepeatedPtrField* repeated = + MutableRaw >(message, field); + return repeated->Mutable(index); } template inline void GeneratedMessageReflection::AddField( - Message* message, const FieldDescriptor* field, const Type& value) const { - GenericRepeatedField* repeated = - MutableRaw(message, field); - *reinterpret_cast(repeated->GenericAdd()) = value; + Message* message, const FieldDescriptor* field, Type value) const { + MutableRaw >(message, field)->Add(value); } template inline Type* GeneratedMessageReflection::AddField( Message* message, const FieldDescriptor* field) const { - GenericRepeatedField* repeated = - MutableRaw(message, field); - return reinterpret_cast(repeated->GenericAdd()); + RepeatedPtrField* repeated = + MutableRaw >(message, field); + return repeated->Add(); } - } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index 702f189e..d0b5b43b 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -142,7 +142,7 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { void ClearField(Message* message, const FieldDescriptor* field) const; void RemoveLast(Message* message, const FieldDescriptor* field) const; void Swap(Message* message1, Message* message2) const; - void SwapElements(Message* message, const FieldDescriptor* field, + void SwapElements(Message* message, const FieldDescriptor* field, int index1, int index2) const; void ListFields(const Message& message, vector* output) const; @@ -314,20 +314,24 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { inline Type* MutableField(Message* message, const FieldDescriptor* field) const; template - inline const Type& GetRepeatedField(const Message& message, - const FieldDescriptor* field, - int index) const; + inline Type GetRepeatedField(const Message& message, + const FieldDescriptor* field, + int index) const; + template + inline const Type& GetRepeatedPtrField(const Message& message, + const FieldDescriptor* field, + int index) const; template inline void SetRepeatedField(Message* message, const FieldDescriptor* field, int index, - const Type& value) const; + Type value) const; template inline Type* MutableRepeatedField(Message* message, const FieldDescriptor* field, int index) const; template inline void AddField(Message* message, - const FieldDescriptor* field, const Type& value) const; + const FieldDescriptor* field, Type value) const; template inline Type* AddField(Message* message, const FieldDescriptor* field) const; @@ -388,11 +392,6 @@ inline To dynamic_cast_if_available(From from) { #endif } -// Compute the space used by a string, not including sizeof(string) itself. -// This is slightly complicated because small strings store their data within -// the string object but large strings do not. -LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str); - // Helper for EnumType_Parse functions: try to parse the string 'name' as an // enum name of the given type, returning true and filling in value on success, // or returning false and leaving value unchanged on failure. @@ -415,7 +414,6 @@ bool ParseNamedEnum(const EnumDescriptor* descriptor, // descriptor.h. LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value); - } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc new file mode 100644 index 00000000..9470bb08 --- /dev/null +++ b/src/google/protobuf/generated_message_util.cc @@ -0,0 +1,44 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +namespace google { +namespace protobuf { +namespace internal { + + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h new file mode 100644 index 00000000..80dd028e --- /dev/null +++ b/src/google/protobuf/generated_message_util.h @@ -0,0 +1,65 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains miscellaneous helper code used by generated code -- +// including lite types -- but which should not be used directly by users. + +#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ + +#include + + +namespace google { +namespace protobuf { +namespace internal { + +// Annotation for the compiler to emit a deprecation message if a field marked +// with option 'deprecated=true' is used in the code. +// +// For internal use in the pb.cc files, deprecation warnings are suppressed +// there. +#undef DEPRECATED_PROTOBUF_FIELD +#if !defined(INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION) +# define DEPRECATED_PROTOBUF_FIELD GOOGLE_ATTRIBUTE_DEPRECATED +#else +# define DEPRECATED_PROTOBUF_FIELD +#endif + + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index 0a00d2bb..e17a4775 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc @@ -80,18 +80,49 @@ CodedInputStream::CodedInputStream(ZeroCopyInputStream* input) total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), recursion_depth_(0), recursion_limit_(kDefaultRecursionLimit) { + // Eagerly Refresh() so buffer space is immediately available. + Refresh(); +} + +CodedInputStream::CodedInputStream(const uint8* buffer, int size) + : input_(NULL), + buffer_(buffer), + buffer_size_(size), + total_bytes_read_(size), + overflow_bytes_(0), + last_tag_(0), + legitimate_message_end_(false), + aliasing_enabled_(false), + current_limit_(size), + buffer_size_after_limit_(0), + total_bytes_limit_(kDefaultTotalBytesLimit), + total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), + recursion_depth_(0), + recursion_limit_(kDefaultRecursionLimit) { + // Note that setting current_limit_ == size is important to prevent some + // code paths from trying to access input_ and segfaulting. } CodedInputStream::~CodedInputStream() { + if (input_ != NULL) { + BackUpInputToCurrentPosition(); + } +} + + +void CodedInputStream::BackUpInputToCurrentPosition() { int backup_bytes = buffer_size_ + buffer_size_after_limit_ + overflow_bytes_; if (backup_bytes > 0) { - // We still have bytes left over from the last buffer. Back up over - // them. input_->BackUp(backup_bytes); + + // total_bytes_read_ doesn't include overflow_bytes_. + total_bytes_read_ -= buffer_size_ + buffer_size_after_limit_; + buffer_size_ = 0; + buffer_size_after_limit_ = 0; + overflow_bytes_ = 0; } } - inline void CodedInputStream::RecomputeBufferLimits() { buffer_size_ += buffer_size_after_limit_; int closest_limit = min(current_limit_, total_bytes_limit_); @@ -193,8 +224,10 @@ bool CodedInputStream::Skip(int count) { int bytes_until_limit = closest_limit - total_bytes_read_; if (bytes_until_limit < count) { // We hit the limit. Skip up to it then fail. - total_bytes_read_ = closest_limit; - input_->Skip(bytes_until_limit); + if (bytes_until_limit > 0) { + total_bytes_read_ = closest_limit; + input_->Skip(bytes_until_limit); + } return false; } @@ -216,6 +249,7 @@ bool CodedInputStream::ReadRaw(void* buffer, int size) { memcpy(buffer, buffer_, buffer_size_); buffer = reinterpret_cast(buffer) + buffer_size_; size -= buffer_size_; + Advance(buffer_size_); if (!Refresh()) return false; } @@ -247,6 +281,7 @@ bool CodedInputStream::ReadString(string* buffer, int size) { buffer->append(reinterpret_cast(buffer_), buffer_size_); } size -= buffer_size_; + Advance(buffer_size_); if (!Refresh()) return false; } @@ -441,11 +476,11 @@ bool CodedInputStream::ReadVarint64(uint64* value) { } bool CodedInputStream::Refresh() { - if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0) { - // We've hit a limit. Stop. - buffer_ += buffer_size_; - buffer_size_ = 0; + GOOGLE_DCHECK_EQ(buffer_size_, 0); + if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 || + total_bytes_read_ == current_limit_) { + // We've hit a limit. Stop. int current_position = total_bytes_read_ - buffer_size_after_limit_; if (current_position >= total_bytes_limit_ && @@ -570,10 +605,7 @@ void CodedOutputStream::WriteLittleEndian32(uint32 value) { bool use_fast = buffer_size_ >= sizeof(value); uint8* ptr = use_fast ? buffer_ : bytes; - ptr[0] = static_cast(value ); - ptr[1] = static_cast(value >> 8); - ptr[2] = static_cast(value >> 16); - ptr[3] = static_cast(value >> 24); + WriteLittleEndian32ToArray(value, ptr); if (use_fast) { Advance(sizeof(value)); @@ -582,32 +614,13 @@ void CodedOutputStream::WriteLittleEndian32(uint32 value) { } } -uint8* CodedOutputStream::WriteLittleEndian32ToArray( - uint32 value, uint8* target) { - target[0] = static_cast(value ); - target[1] = static_cast(value >> 8); - target[2] = static_cast(value >> 16); - target[3] = static_cast(value >> 24); - return target + sizeof(value); -} - void CodedOutputStream::WriteLittleEndian64(uint64 value) { uint8 bytes[sizeof(value)]; - uint32 part0 = static_cast(value); - uint32 part1 = static_cast(value >> 32); - bool use_fast = buffer_size_ >= sizeof(value); uint8* ptr = use_fast ? buffer_ : bytes; - ptr[0] = static_cast(part0 ); - ptr[1] = static_cast(part0 >> 8); - ptr[2] = static_cast(part0 >> 16); - ptr[3] = static_cast(part0 >> 24); - ptr[4] = static_cast(part1 ); - ptr[5] = static_cast(part1 >> 8); - ptr[6] = static_cast(part1 >> 16); - ptr[7] = static_cast(part1 >> 24); + WriteLittleEndian64ToArray(value, ptr); if (use_fast) { Advance(sizeof(value)); @@ -616,23 +629,6 @@ void CodedOutputStream::WriteLittleEndian64(uint64 value) { } } -uint8* CodedOutputStream::WriteLittleEndian64ToArray( - uint64 value, uint8* target) { - uint32 part0 = static_cast(value); - uint32 part1 = static_cast(value >> 32); - - target[0] = static_cast(part0 ); - target[1] = static_cast(part0 >> 8); - target[2] = static_cast(part0 >> 16); - target[3] = static_cast(part0 >> 24); - target[4] = static_cast(part1 ); - target[5] = static_cast(part1 >> 8); - target[6] = static_cast(part1 >> 16); - target[7] = static_cast(part1 >> 24); - - return target + sizeof(value); -} - inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline( uint32 value, uint8* target) { target[0] = static_cast(value | 0x80); diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h index 9e450216..fa023f35 100644 --- a/src/google/protobuf/io/coded_stream.h +++ b/src/google/protobuf/io/coded_stream.h @@ -110,6 +110,9 @@ #define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ #include +#ifndef _MSC_VER +#include +#endif // !_MSC_VER #include namespace google { @@ -137,6 +140,11 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // Create a CodedInputStream that reads from the given ZeroCopyInputStream. explicit CodedInputStream(ZeroCopyInputStream* input); + // Create a CodedInputStream that reads from the given flat array. This is + // faster than using an ArrayInputStream. PushLimit(size) is implied by + // this constructor. + explicit CodedInputStream(const uint8* buffer, int size); + // Destroy the CodedInputStream and position the underlying // ZeroCopyInputStream at the first unread byte. If an error occurred while // reading (causing a method to return false), then the exact position of @@ -360,6 +368,9 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // Advance the buffer by a given number of bytes. void Advance(int amount); + // Back up input_ to the current buffer position. + void BackUpInputToCurrentPosition(); + // Recomputes the value of buffer_size_after_limit_. Must be called after // current_limit_ or total_bytes_limit_ changes. void RecomputeBufferLimits(); @@ -664,6 +675,41 @@ inline uint8* CodedOutputStream::WriteVarint32SignExtendedToArray( } } +inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value, + uint8* target) { +#if !defined(PROTOBUF_TEST_NOT_LITTLE_ENDIAN) && \ + defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN + memcpy(target, &value, sizeof(value)); +#else + target[0] = static_cast(value ); + target[1] = static_cast(value >> 8); + target[2] = static_cast(value >> 16); + target[3] = static_cast(value >> 24); +#endif + return target + sizeof(value); +} + +inline uint8* CodedOutputStream::WriteLittleEndian64ToArray(uint64 value, + uint8* target) { +#if !defined(PROTOBUF_TEST_NOT_LITTLE_ENDIAN) && \ + defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN + memcpy(target, &value, sizeof(value)); +#else + uint32 part0 = static_cast(value); + uint32 part1 = static_cast(value >> 32); + + target[0] = static_cast(part0 ); + target[1] = static_cast(part0 >> 8); + target[2] = static_cast(part0 >> 16); + target[3] = static_cast(part0 >> 24); + target[4] = static_cast(part1 ); + target[5] = static_cast(part1 >> 8); + target[6] = static_cast(part1 >> 16); + target[7] = static_cast(part1 >> 24); +#endif + return target + sizeof(value); +} + inline void CodedOutputStream::WriteTag(uint32 value) { WriteVarint32(value); } diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc index d8d0e70d..243b3e32 100644 --- a/src/google/protobuf/io/gzip_stream.cc +++ b/src/google/protobuf/io/gzip_stream.cc @@ -1,5 +1,5 @@ // Protocol Buffers - Google's data interchange format -// Copyright 2009 Google Inc. All rights reserved. +// Copyright 2008 Google Inc. All rights reserved. // http://code.google.com/p/protobuf/ // // Redistribution and use in source and binary forms, with or without @@ -29,8 +29,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: brianolson@google.com (Brian Olson) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. // // This file contains the implementation of classes GzipInputStream and // GzipOutputStream. @@ -39,6 +37,7 @@ #if HAVE_ZLIB #include + #include namespace google { @@ -291,6 +290,6 @@ bool GzipOutputStream::Close() { } // namespace io } // namespace protobuf -} // namespace google #endif // HAVE_ZLIB +} // namespace google diff --git a/src/google/protobuf/io/gzip_stream.h b/src/google/protobuf/io/gzip_stream.h index 4f29499a..50a2ad70 100644 --- a/src/google/protobuf/io/gzip_stream.h +++ b/src/google/protobuf/io/gzip_stream.h @@ -1,5 +1,5 @@ // Protocol Buffers - Google's data interchange format -// Copyright 2009 Google Inc. All rights reserved. +// Copyright 2008 Google Inc. All rights reserved. // http://code.google.com/p/protobuf/ // // Redistribution and use in source and binary forms, with or without @@ -29,8 +29,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: brianolson@google.com (Brian Olson) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. // // This file contains the definition for classes GzipInputStream and // GzipOutputStream. @@ -173,6 +171,6 @@ class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream { } // namespace io } // namespace protobuf -} // namespace google +} // namespace google #endif // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc index 4823912a..0bda451b 100644 --- a/src/google/protobuf/io/tokenizer.cc +++ b/src/google/protobuf/io/tokenizer.cc @@ -571,7 +571,7 @@ bool Tokenizer::ParseInteger(const string& text, uint64 max_value, const char* ptr = text.c_str(); int base = 10; if (ptr[0] == '0') { - if (ptr[1] == 'x') { + if (ptr[1] == 'x' || ptr[1] == 'X') { // This is hex. base = 16; ptr += 2; diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc index dd7ed5c8..eac1455d 100644 --- a/src/google/protobuf/io/tokenizer_unittest.cc +++ b/src/google/protobuf/io/tokenizer_unittest.cc @@ -487,6 +487,7 @@ TEST_F(TokenizerTest, ParseInteger) { EXPECT_EQ(0xabcdef12u, ParseInteger("0xABCDEF12")); EXPECT_EQ(kuint64max, ParseInteger("0xFFFFFFFFFFFFFFFF")); EXPECT_EQ(01234567, ParseInteger("01234567")); + EXPECT_EQ(0X123, ParseInteger("0X123")); // Test invalid integers that may still be tokenized as integers. EXPECT_EQ(0, ParseInteger("0x")); diff --git a/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/google/protobuf/io/zero_copy_stream_impl.cc index 0b4516ef..1384c746 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl.cc @@ -60,7 +60,6 @@ namespace io { namespace { - // EINTR sucks. int close_no_eintr(int fd) { int result; @@ -70,352 +69,8 @@ int close_no_eintr(int fd) { return result; } -// Default block size for Copying{In,Out}putStreamAdaptor. -static const int kDefaultBlockSize = 8192; - } // namespace -// =================================================================== - -ArrayInputStream::ArrayInputStream(const void* data, int size, - int block_size) - : data_(reinterpret_cast(data)), - size_(size), - block_size_(block_size > 0 ? block_size : size), - position_(0), - last_returned_size_(0) { -} - -ArrayInputStream::~ArrayInputStream() { -} - -bool ArrayInputStream::Next(const void** data, int* size) { - if (position_ < size_) { - last_returned_size_ = min(block_size_, size_ - position_); - *data = data_ + position_; - *size = last_returned_size_; - position_ += last_returned_size_; - return true; - } else { - // We're at the end of the array. - last_returned_size_ = 0; // Don't let caller back up. - return false; - } -} - -void ArrayInputStream::BackUp(int count) { - GOOGLE_CHECK_GT(last_returned_size_, 0) - << "BackUp() can only be called after a successful Next()."; - GOOGLE_CHECK_LE(count, last_returned_size_); - GOOGLE_CHECK_GE(count, 0); - position_ -= count; - last_returned_size_ = 0; // Don't let caller back up further. -} - -bool ArrayInputStream::Skip(int count) { - GOOGLE_CHECK_GE(count, 0); - last_returned_size_ = 0; // Don't let caller back up. - if (count > size_ - position_) { - position_ = size_; - return false; - } else { - position_ += count; - return true; - } -} - -int64 ArrayInputStream::ByteCount() const { - return position_; -} - - -// =================================================================== - -ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size) - : data_(reinterpret_cast(data)), - size_(size), - block_size_(block_size > 0 ? block_size : size), - position_(0), - last_returned_size_(0) { -} - -ArrayOutputStream::~ArrayOutputStream() { -} - -bool ArrayOutputStream::Next(void** data, int* size) { - if (position_ < size_) { - last_returned_size_ = min(block_size_, size_ - position_); - *data = data_ + position_; - *size = last_returned_size_; - position_ += last_returned_size_; - return true; - } else { - // We're at the end of the array. - last_returned_size_ = 0; // Don't let caller back up. - return false; - } -} - -void ArrayOutputStream::BackUp(int count) { - GOOGLE_CHECK_GT(last_returned_size_, 0) - << "BackUp() can only be called after a successful Next()."; - GOOGLE_CHECK_LE(count, last_returned_size_); - GOOGLE_CHECK_GE(count, 0); - position_ -= count; - last_returned_size_ = 0; // Don't let caller back up further. -} - -int64 ArrayOutputStream::ByteCount() const { - return position_; -} - -// =================================================================== - -StringOutputStream::StringOutputStream(string* target) - : target_(target) { -} - -StringOutputStream::~StringOutputStream() { -} - -bool StringOutputStream::Next(void** data, int* size) { - int old_size = target_->size(); - - // Grow the string. - if (old_size < target_->capacity()) { - // Resize the string to match its capacity, since we can get away - // without a memory allocation this way. - STLStringResizeUninitialized(target_, target_->capacity()); - } else { - // Size has reached capacity, so double the size. Also make sure - // that the new size is at least kMinimumSize. - STLStringResizeUninitialized( - target_, - max(old_size * 2, - kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness. - } - - *data = string_as_array(target_) + old_size; - *size = target_->size() - old_size; - return true; -} - -void StringOutputStream::BackUp(int count) { - GOOGLE_CHECK_GE(count, 0); - GOOGLE_CHECK_LE(count, target_->size()); - target_->resize(target_->size() - count); -} - -int64 StringOutputStream::ByteCount() const { - return target_->size(); -} - -// =================================================================== - - -// =================================================================== - -CopyingInputStream::~CopyingInputStream() {} - -int CopyingInputStream::Skip(int count) { - char junk[4096]; - int skipped = 0; - while (skipped < count) { - int bytes = Read(junk, min(count - skipped, - implicit_cast(sizeof(junk)))); - if (bytes <= 0) { - // EOF or read error. - return skipped; - } - skipped += bytes; - } - return skipped; -} - -CopyingInputStreamAdaptor::CopyingInputStreamAdaptor( - CopyingInputStream* copying_stream, int block_size) - : copying_stream_(copying_stream), - owns_copying_stream_(false), - failed_(false), - position_(0), - buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), - buffer_used_(0), - backup_bytes_(0) { -} - -CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() { - if (owns_copying_stream_) { - delete copying_stream_; - } -} - -bool CopyingInputStreamAdaptor::Next(const void** data, int* size) { - if (failed_) { - // Already failed on a previous read. - return false; - } - - AllocateBufferIfNeeded(); - - if (backup_bytes_ > 0) { - // We have data left over from a previous BackUp(), so just return that. - *data = buffer_.get() + buffer_used_ - backup_bytes_; - *size = backup_bytes_; - backup_bytes_ = 0; - return true; - } - - // Read new data into the buffer. - buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_); - if (buffer_used_ <= 0) { - // EOF or read error. We don't need the buffer anymore. - if (buffer_used_ < 0) { - // Read error (not EOF). - failed_ = true; - } - FreeBuffer(); - return false; - } - position_ += buffer_used_; - - *size = buffer_used_; - *data = buffer_.get(); - return true; -} - -void CopyingInputStreamAdaptor::BackUp(int count) { - GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL) - << " BackUp() can only be called after Next()."; - GOOGLE_CHECK_LE(count, buffer_used_) - << " Can't back up over more bytes than were returned by the last call" - " to Next()."; - GOOGLE_CHECK_GE(count, 0) - << " Parameter to BackUp() can't be negative."; - - backup_bytes_ = count; -} - -bool CopyingInputStreamAdaptor::Skip(int count) { - GOOGLE_CHECK_GE(count, 0); - - if (failed_) { - // Already failed on a previous read. - return false; - } - - // First skip any bytes left over from a previous BackUp(). - if (backup_bytes_ >= count) { - // We have more data left over than we're trying to skip. Just chop it. - backup_bytes_ -= count; - return true; - } - - count -= backup_bytes_; - backup_bytes_ = 0; - - int skipped = copying_stream_->Skip(count); - position_ += skipped; - return skipped == count; -} - -int64 CopyingInputStreamAdaptor::ByteCount() const { - return position_ - backup_bytes_; -} - -void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() { - if (buffer_.get() == NULL) { - buffer_.reset(new uint8[buffer_size_]); - } -} - -void CopyingInputStreamAdaptor::FreeBuffer() { - GOOGLE_CHECK_EQ(backup_bytes_, 0); - buffer_used_ = 0; - buffer_.reset(); -} - -// =================================================================== - -CopyingOutputStream::~CopyingOutputStream() {} - -CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor( - CopyingOutputStream* copying_stream, int block_size) - : copying_stream_(copying_stream), - owns_copying_stream_(false), - failed_(false), - position_(0), - buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), - buffer_used_(0) { -} - -CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() { - WriteBuffer(); - if (owns_copying_stream_) { - delete copying_stream_; - } -} - -bool CopyingOutputStreamAdaptor::Flush() { - return WriteBuffer(); -} - -bool CopyingOutputStreamAdaptor::Next(void** data, int* size) { - if (buffer_used_ == buffer_size_) { - if (!WriteBuffer()) return false; - } - - AllocateBufferIfNeeded(); - - *data = buffer_.get() + buffer_used_; - *size = buffer_size_ - buffer_used_; - buffer_used_ = buffer_size_; - return true; -} - -void CopyingOutputStreamAdaptor::BackUp(int count) { - GOOGLE_CHECK_GE(count, 0); - GOOGLE_CHECK_EQ(buffer_used_, buffer_size_) - << " BackUp() can only be called after Next()."; - GOOGLE_CHECK_LE(count, buffer_used_) - << " Can't back up over more bytes than were returned by the last call" - " to Next()."; - - buffer_used_ -= count; -} - -int64 CopyingOutputStreamAdaptor::ByteCount() const { - return position_ + buffer_used_; -} - -bool CopyingOutputStreamAdaptor::WriteBuffer() { - if (failed_) { - // Already failed on a previous write. - return false; - } - - if (buffer_used_ == 0) return true; - - if (copying_stream_->Write(buffer_.get(), buffer_used_)) { - position_ += buffer_used_; - buffer_used_ = 0; - return true; - } else { - failed_ = true; - FreeBuffer(); - return false; - } -} - -void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() { - if (buffer_ == NULL) { - buffer_.reset(new uint8[buffer_size_]); - } -} - -void CopyingOutputStreamAdaptor::FreeBuffer() { - buffer_used_ = 0; - buffer_.reset(); -} // =================================================================== diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h index 448aa216..d7cf73ff 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.h +++ b/src/google/protobuf/io/zero_copy_stream_impl.h @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -52,285 +53,6 @@ namespace google { namespace protobuf { namespace io { -// =================================================================== - -// A ZeroCopyInputStream backed by an in-memory array of bytes. -class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream { - public: - // Create an InputStream that returns the bytes pointed to by "data". - // "data" remains the property of the caller but must remain valid until - // the stream is destroyed. If a block_size is given, calls to Next() - // will return data blocks no larger than the given size. Otherwise, the - // first call to Next() returns the entire array. block_size is mainly - // useful for testing; in production you would probably never want to set - // it. - ArrayInputStream(const void* data, int size, int block_size = -1); - ~ArrayInputStream(); - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - - private: - const uint8* const data_; // The byte array. - const int size_; // Total size of the array. - const int block_size_; // How many bytes to return at a time. - - int position_; - int last_returned_size_; // How many bytes we returned last time Next() - // was called (used for error checking only). - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream); -}; - -// =================================================================== - -// A ZeroCopyOutputStream backed by an in-memory array of bytes. -class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream { - public: - // Create an OutputStream that writes to the bytes pointed to by "data". - // "data" remains the property of the caller but must remain valid until - // the stream is destroyed. If a block_size is given, calls to Next() - // will return data blocks no larger than the given size. Otherwise, the - // first call to Next() returns the entire array. block_size is mainly - // useful for testing; in production you would probably never want to set - // it. - ArrayOutputStream(void* data, int size, int block_size = -1); - ~ArrayOutputStream(); - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - uint8* const data_; // The byte array. - const int size_; // Total size of the array. - const int block_size_; // How many bytes to return at a time. - - int position_; - int last_returned_size_; // How many bytes we returned last time Next() - // was called (used for error checking only). - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream); -}; - -// =================================================================== - -// A ZeroCopyOutputStream which appends bytes to a string. -class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream { - public: - // Create a StringOutputStream which appends bytes to the given string. - // The string remains property of the caller, but it MUST NOT be accessed - // in any way until the stream is destroyed. - // - // Hint: If you call target->reserve(n) before creating the stream, - // the first call to Next() will return at least n bytes of buffer - // space. - explicit StringOutputStream(string* target); - ~StringOutputStream(); - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - static const int kMinimumSize = 16; - - string* target_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream); -}; - -// Note: There is no StringInputStream. Instead, just create an -// ArrayInputStream as follows: -// ArrayInputStream input(str.data(), str.size()); - -// =================================================================== - - -// =================================================================== - -// A generic traditional input stream interface. -// -// Lots of traditional input streams (e.g. file descriptors, C stdio -// streams, and C++ iostreams) expose an interface where every read -// involves copying bytes into a buffer. If you want to take such an -// interface and make a ZeroCopyInputStream based on it, simply implement -// CopyingInputStream and then use CopyingInputStreamAdaptor. -// -// CopyingInputStream implementations should avoid buffering if possible. -// CopyingInputStreamAdaptor does its own buffering and will read data -// in large blocks. -class LIBPROTOBUF_EXPORT CopyingInputStream { - public: - virtual ~CopyingInputStream(); - - // Reads up to "size" bytes into the given buffer. Returns the number of - // bytes read. Read() waits until at least one byte is available, or - // returns zero if no bytes will ever become available (EOF), or -1 if a - // permanent read error occurred. - virtual int Read(void* buffer, int size) = 0; - - // Skips the next "count" bytes of input. Returns the number of bytes - // actually skipped. This will always be exactly equal to "count" unless - // EOF was reached or a permanent read error occurred. - // - // The default implementation just repeatedly calls Read() into a scratch - // buffer. - virtual int Skip(int count); -}; - -// A ZeroCopyInputStream which reads from a CopyingInputStream. This is -// useful for implementing ZeroCopyInputStreams that read from traditional -// streams. Note that this class is not really zero-copy. -// -// If you want to read from file descriptors or C++ istreams, this is -// already implemented for you: use FileInputStream or IstreamInputStream -// respectively. -class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream { - public: - // Creates a stream that reads from the given CopyingInputStream. - // If a block_size is given, it specifies the number of bytes that - // should be read and returned with each call to Next(). Otherwise, - // a reasonable default is used. The caller retains ownership of - // copying_stream unless SetOwnsCopyingStream(true) is called. - explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream, - int block_size = -1); - ~CopyingInputStreamAdaptor(); - - // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to - // delete the underlying CopyingInputStream when it is destroyed. - void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - private: - // Insures that buffer_ is not NULL. - void AllocateBufferIfNeeded(); - // Frees the buffer and resets buffer_used_. - void FreeBuffer(); - - // The underlying copying stream. - CopyingInputStream* copying_stream_; - bool owns_copying_stream_; - - // True if we have seen a permenant error from the underlying stream. - bool failed_; - - // The current position of copying_stream_, relative to the point where - // we started reading. - int64 position_; - - // Data is read into this buffer. It may be NULL if no buffer is currently - // in use. Otherwise, it points to an array of size buffer_size_. - scoped_array buffer_; - const int buffer_size_; - - // Number of valid bytes currently in the buffer (i.e. the size last - // returned by Next()). 0 <= buffer_used_ <= buffer_size_. - int buffer_used_; - - // Number of bytes in the buffer which were backed up over by a call to - // BackUp(). These need to be returned again. - // 0 <= backup_bytes_ <= buffer_used_ - int backup_bytes_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor); -}; - -// =================================================================== - -// A generic traditional output stream interface. -// -// Lots of traditional output streams (e.g. file descriptors, C stdio -// streams, and C++ iostreams) expose an interface where every write -// involves copying bytes from a buffer. If you want to take such an -// interface and make a ZeroCopyOutputStream based on it, simply implement -// CopyingOutputStream and then use CopyingOutputStreamAdaptor. -// -// CopyingOutputStream implementations should avoid buffering if possible. -// CopyingOutputStreamAdaptor does its own buffering and will write data -// in large blocks. -class LIBPROTOBUF_EXPORT CopyingOutputStream { - public: - virtual ~CopyingOutputStream(); - - // Writes "size" bytes from the given buffer to the output. Returns true - // if successful, false on a write error. - virtual bool Write(const void* buffer, int size) = 0; -}; - -// A ZeroCopyOutputStream which writes to a CopyingOutputStream. This is -// useful for implementing ZeroCopyOutputStreams that write to traditional -// streams. Note that this class is not really zero-copy. -// -// If you want to write to file descriptors or C++ ostreams, this is -// already implemented for you: use FileOutputStream or OstreamOutputStream -// respectively. -class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream { - public: - // Creates a stream that writes to the given Unix file descriptor. - // If a block_size is given, it specifies the size of the buffers - // that should be returned by Next(). Otherwise, a reasonable default - // is used. - explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream, - int block_size = -1); - ~CopyingOutputStreamAdaptor(); - - // Writes all pending data to the underlying stream. Returns false if a - // write error occurred on the underlying stream. (The underlying - // stream itself is not necessarily flushed.) - bool Flush(); - - // Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to - // delete the underlying CopyingOutputStream when it is destroyed. - void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - // Write the current buffer, if it is present. - bool WriteBuffer(); - // Insures that buffer_ is not NULL. - void AllocateBufferIfNeeded(); - // Frees the buffer. - void FreeBuffer(); - - // The underlying copying stream. - CopyingOutputStream* copying_stream_; - bool owns_copying_stream_; - - // True if we have seen a permenant error from the underlying stream. - bool failed_; - - // The current position of copying_stream_, relative to the point where - // we started writing. - int64 position_; - - // Data is written from this buffer. It may be NULL if no buffer is - // currently in use. Otherwise, it points to an array of size buffer_size_. - scoped_array buffer_; - const int buffer_size_; - - // Number of valid bytes currently in the buffer (i.e. the size last - // returned by Next()). When BackUp() is called, we just reduce this. - // 0 <= buffer_used_ <= buffer_size_. - int buffer_used_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor); -}; // =================================================================== diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc new file mode 100644 index 00000000..e8012510 --- /dev/null +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc @@ -0,0 +1,393 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { + +namespace { + +// Default block size for Copying{In,Out}putStreamAdaptor. +static const int kDefaultBlockSize = 8192; + +} // namespace + +// =================================================================== + +ArrayInputStream::ArrayInputStream(const void* data, int size, + int block_size) + : data_(reinterpret_cast(data)), + size_(size), + block_size_(block_size > 0 ? block_size : size), + position_(0), + last_returned_size_(0) { +} + +ArrayInputStream::~ArrayInputStream() { +} + +bool ArrayInputStream::Next(const void** data, int* size) { + if (position_ < size_) { + last_returned_size_ = min(block_size_, size_ - position_); + *data = data_ + position_; + *size = last_returned_size_; + position_ += last_returned_size_; + return true; + } else { + // We're at the end of the array. + last_returned_size_ = 0; // Don't let caller back up. + return false; + } +} + +void ArrayInputStream::BackUp(int count) { + GOOGLE_CHECK_GT(last_returned_size_, 0) + << "BackUp() can only be called after a successful Next()."; + GOOGLE_CHECK_LE(count, last_returned_size_); + GOOGLE_CHECK_GE(count, 0); + position_ -= count; + last_returned_size_ = 0; // Don't let caller back up further. +} + +bool ArrayInputStream::Skip(int count) { + GOOGLE_CHECK_GE(count, 0); + last_returned_size_ = 0; // Don't let caller back up. + if (count > size_ - position_) { + position_ = size_; + return false; + } else { + position_ += count; + return true; + } +} + +int64 ArrayInputStream::ByteCount() const { + return position_; +} + + +// =================================================================== + +ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size) + : data_(reinterpret_cast(data)), + size_(size), + block_size_(block_size > 0 ? block_size : size), + position_(0), + last_returned_size_(0) { +} + +ArrayOutputStream::~ArrayOutputStream() { +} + +bool ArrayOutputStream::Next(void** data, int* size) { + if (position_ < size_) { + last_returned_size_ = min(block_size_, size_ - position_); + *data = data_ + position_; + *size = last_returned_size_; + position_ += last_returned_size_; + return true; + } else { + // We're at the end of the array. + last_returned_size_ = 0; // Don't let caller back up. + return false; + } +} + +void ArrayOutputStream::BackUp(int count) { + GOOGLE_CHECK_GT(last_returned_size_, 0) + << "BackUp() can only be called after a successful Next()."; + GOOGLE_CHECK_LE(count, last_returned_size_); + GOOGLE_CHECK_GE(count, 0); + position_ -= count; + last_returned_size_ = 0; // Don't let caller back up further. +} + +int64 ArrayOutputStream::ByteCount() const { + return position_; +} + +// =================================================================== + +StringOutputStream::StringOutputStream(string* target) + : target_(target) { +} + +StringOutputStream::~StringOutputStream() { +} + +bool StringOutputStream::Next(void** data, int* size) { + int old_size = target_->size(); + + // Grow the string. + if (old_size < target_->capacity()) { + // Resize the string to match its capacity, since we can get away + // without a memory allocation this way. + STLStringResizeUninitialized(target_, target_->capacity()); + } else { + // Size has reached capacity, so double the size. Also make sure + // that the new size is at least kMinimumSize. + STLStringResizeUninitialized( + target_, + max(old_size * 2, + kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness. + } + + *data = string_as_array(target_) + old_size; + *size = target_->size() - old_size; + return true; +} + +void StringOutputStream::BackUp(int count) { + GOOGLE_CHECK_GE(count, 0); + GOOGLE_CHECK_LE(count, target_->size()); + target_->resize(target_->size() - count); +} + +int64 StringOutputStream::ByteCount() const { + return target_->size(); +} + +// =================================================================== + +CopyingInputStream::~CopyingInputStream() {} + +int CopyingInputStream::Skip(int count) { + char junk[4096]; + int skipped = 0; + while (skipped < count) { + int bytes = Read(junk, min(count - skipped, + implicit_cast(sizeof(junk)))); + if (bytes <= 0) { + // EOF or read error. + return skipped; + } + skipped += bytes; + } + return skipped; +} + +CopyingInputStreamAdaptor::CopyingInputStreamAdaptor( + CopyingInputStream* copying_stream, int block_size) + : copying_stream_(copying_stream), + owns_copying_stream_(false), + failed_(false), + position_(0), + buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), + buffer_used_(0), + backup_bytes_(0) { +} + +CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() { + if (owns_copying_stream_) { + delete copying_stream_; + } +} + +bool CopyingInputStreamAdaptor::Next(const void** data, int* size) { + if (failed_) { + // Already failed on a previous read. + return false; + } + + AllocateBufferIfNeeded(); + + if (backup_bytes_ > 0) { + // We have data left over from a previous BackUp(), so just return that. + *data = buffer_.get() + buffer_used_ - backup_bytes_; + *size = backup_bytes_; + backup_bytes_ = 0; + return true; + } + + // Read new data into the buffer. + buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_); + if (buffer_used_ <= 0) { + // EOF or read error. We don't need the buffer anymore. + if (buffer_used_ < 0) { + // Read error (not EOF). + failed_ = true; + } + FreeBuffer(); + return false; + } + position_ += buffer_used_; + + *size = buffer_used_; + *data = buffer_.get(); + return true; +} + +void CopyingInputStreamAdaptor::BackUp(int count) { + GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL) + << " BackUp() can only be called after Next()."; + GOOGLE_CHECK_LE(count, buffer_used_) + << " Can't back up over more bytes than were returned by the last call" + " to Next()."; + GOOGLE_CHECK_GE(count, 0) + << " Parameter to BackUp() can't be negative."; + + backup_bytes_ = count; +} + +bool CopyingInputStreamAdaptor::Skip(int count) { + GOOGLE_CHECK_GE(count, 0); + + if (failed_) { + // Already failed on a previous read. + return false; + } + + // First skip any bytes left over from a previous BackUp(). + if (backup_bytes_ >= count) { + // We have more data left over than we're trying to skip. Just chop it. + backup_bytes_ -= count; + return true; + } + + count -= backup_bytes_; + backup_bytes_ = 0; + + int skipped = copying_stream_->Skip(count); + position_ += skipped; + return skipped == count; +} + +int64 CopyingInputStreamAdaptor::ByteCount() const { + return position_ - backup_bytes_; +} + +void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() { + if (buffer_.get() == NULL) { + buffer_.reset(new uint8[buffer_size_]); + } +} + +void CopyingInputStreamAdaptor::FreeBuffer() { + GOOGLE_CHECK_EQ(backup_bytes_, 0); + buffer_used_ = 0; + buffer_.reset(); +} + +// =================================================================== + +CopyingOutputStream::~CopyingOutputStream() {} + +CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor( + CopyingOutputStream* copying_stream, int block_size) + : copying_stream_(copying_stream), + owns_copying_stream_(false), + failed_(false), + position_(0), + buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), + buffer_used_(0) { +} + +CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() { + WriteBuffer(); + if (owns_copying_stream_) { + delete copying_stream_; + } +} + +bool CopyingOutputStreamAdaptor::Flush() { + return WriteBuffer(); +} + +bool CopyingOutputStreamAdaptor::Next(void** data, int* size) { + if (buffer_used_ == buffer_size_) { + if (!WriteBuffer()) return false; + } + + AllocateBufferIfNeeded(); + + *data = buffer_.get() + buffer_used_; + *size = buffer_size_ - buffer_used_; + buffer_used_ = buffer_size_; + return true; +} + +void CopyingOutputStreamAdaptor::BackUp(int count) { + GOOGLE_CHECK_GE(count, 0); + GOOGLE_CHECK_EQ(buffer_used_, buffer_size_) + << " BackUp() can only be called after Next()."; + GOOGLE_CHECK_LE(count, buffer_used_) + << " Can't back up over more bytes than were returned by the last call" + " to Next()."; + + buffer_used_ -= count; +} + +int64 CopyingOutputStreamAdaptor::ByteCount() const { + return position_ + buffer_used_; +} + +bool CopyingOutputStreamAdaptor::WriteBuffer() { + if (failed_) { + // Already failed on a previous write. + return false; + } + + if (buffer_used_ == 0) return true; + + if (copying_stream_->Write(buffer_.get(), buffer_used_)) { + position_ += buffer_used_; + buffer_used_ = 0; + return true; + } else { + failed_ = true; + FreeBuffer(); + return false; + } +} + +void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() { + if (buffer_ == NULL) { + buffer_.reset(new uint8[buffer_size_]); + } +} + +void CopyingOutputStreamAdaptor::FreeBuffer() { + buffer_used_ = 0; + buffer_.reset(); +} + +// =================================================================== + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h new file mode 100644 index 00000000..59f18258 --- /dev/null +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h @@ -0,0 +1,338 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains common implementations of the interfaces defined in +// zero_copy_stream.h. These implementations cover I/O on raw arrays, +// strings, and file descriptors. Of course, many users will probably +// want to write their own implementations of these interfaces specific +// to the particular I/O abstractions they prefer to use, but these +// should cover the most common cases. + +#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ +#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ + +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace io { + +// =================================================================== + +// A ZeroCopyInputStream backed by an in-memory array of bytes. +class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream { + public: + // Create an InputStream that returns the bytes pointed to by "data". + // "data" remains the property of the caller but must remain valid until + // the stream is destroyed. If a block_size is given, calls to Next() + // will return data blocks no larger than the given size. Otherwise, the + // first call to Next() returns the entire array. block_size is mainly + // useful for testing; in production you would probably never want to set + // it. + ArrayInputStream(const void* data, int size, int block_size = -1); + ~ArrayInputStream(); + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + + private: + const uint8* const data_; // The byte array. + const int size_; // Total size of the array. + const int block_size_; // How many bytes to return at a time. + + int position_; + int last_returned_size_; // How many bytes we returned last time Next() + // was called (used for error checking only). + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream backed by an in-memory array of bytes. +class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream { + public: + // Create an OutputStream that writes to the bytes pointed to by "data". + // "data" remains the property of the caller but must remain valid until + // the stream is destroyed. If a block_size is given, calls to Next() + // will return data blocks no larger than the given size. Otherwise, the + // first call to Next() returns the entire array. block_size is mainly + // useful for testing; in production you would probably never want to set + // it. + ArrayOutputStream(void* data, int size, int block_size = -1); + ~ArrayOutputStream(); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + uint8* const data_; // The byte array. + const int size_; // Total size of the array. + const int block_size_; // How many bytes to return at a time. + + int position_; + int last_returned_size_; // How many bytes we returned last time Next() + // was called (used for error checking only). + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream which appends bytes to a string. +class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream { + public: + // Create a StringOutputStream which appends bytes to the given string. + // The string remains property of the caller, but it MUST NOT be accessed + // in any way until the stream is destroyed. + // + // Hint: If you call target->reserve(n) before creating the stream, + // the first call to Next() will return at least n bytes of buffer + // space. + explicit StringOutputStream(string* target); + ~StringOutputStream(); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + static const int kMinimumSize = 16; + + string* target_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream); +}; + +// Note: There is no StringInputStream. Instead, just create an +// ArrayInputStream as follows: +// ArrayInputStream input(str.data(), str.size()); + +// =================================================================== + +// A generic traditional input stream interface. +// +// Lots of traditional input streams (e.g. file descriptors, C stdio +// streams, and C++ iostreams) expose an interface where every read +// involves copying bytes into a buffer. If you want to take such an +// interface and make a ZeroCopyInputStream based on it, simply implement +// CopyingInputStream and then use CopyingInputStreamAdaptor. +// +// CopyingInputStream implementations should avoid buffering if possible. +// CopyingInputStreamAdaptor does its own buffering and will read data +// in large blocks. +class LIBPROTOBUF_EXPORT CopyingInputStream { + public: + virtual ~CopyingInputStream(); + + // Reads up to "size" bytes into the given buffer. Returns the number of + // bytes read. Read() waits until at least one byte is available, or + // returns zero if no bytes will ever become available (EOF), or -1 if a + // permanent read error occurred. + virtual int Read(void* buffer, int size) = 0; + + // Skips the next "count" bytes of input. Returns the number of bytes + // actually skipped. This will always be exactly equal to "count" unless + // EOF was reached or a permanent read error occurred. + // + // The default implementation just repeatedly calls Read() into a scratch + // buffer. + virtual int Skip(int count); +}; + +// A ZeroCopyInputStream which reads from a CopyingInputStream. This is +// useful for implementing ZeroCopyInputStreams that read from traditional +// streams. Note that this class is not really zero-copy. +// +// If you want to read from file descriptors or C++ istreams, this is +// already implemented for you: use FileInputStream or IstreamInputStream +// respectively. +class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream { + public: + // Creates a stream that reads from the given CopyingInputStream. + // If a block_size is given, it specifies the number of bytes that + // should be read and returned with each call to Next(). Otherwise, + // a reasonable default is used. The caller retains ownership of + // copying_stream unless SetOwnsCopyingStream(true) is called. + explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream, + int block_size = -1); + ~CopyingInputStreamAdaptor(); + + // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to + // delete the underlying CopyingInputStream when it is destroyed. + void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + private: + // Insures that buffer_ is not NULL. + void AllocateBufferIfNeeded(); + // Frees the buffer and resets buffer_used_. + void FreeBuffer(); + + // The underlying copying stream. + CopyingInputStream* copying_stream_; + bool owns_copying_stream_; + + // True if we have seen a permenant error from the underlying stream. + bool failed_; + + // The current position of copying_stream_, relative to the point where + // we started reading. + int64 position_; + + // Data is read into this buffer. It may be NULL if no buffer is currently + // in use. Otherwise, it points to an array of size buffer_size_. + scoped_array buffer_; + const int buffer_size_; + + // Number of valid bytes currently in the buffer (i.e. the size last + // returned by Next()). 0 <= buffer_used_ <= buffer_size_. + int buffer_used_; + + // Number of bytes in the buffer which were backed up over by a call to + // BackUp(). These need to be returned again. + // 0 <= backup_bytes_ <= buffer_used_ + int backup_bytes_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor); +}; + +// =================================================================== + +// A generic traditional output stream interface. +// +// Lots of traditional output streams (e.g. file descriptors, C stdio +// streams, and C++ iostreams) expose an interface where every write +// involves copying bytes from a buffer. If you want to take such an +// interface and make a ZeroCopyOutputStream based on it, simply implement +// CopyingOutputStream and then use CopyingOutputStreamAdaptor. +// +// CopyingOutputStream implementations should avoid buffering if possible. +// CopyingOutputStreamAdaptor does its own buffering and will write data +// in large blocks. +class LIBPROTOBUF_EXPORT CopyingOutputStream { + public: + virtual ~CopyingOutputStream(); + + // Writes "size" bytes from the given buffer to the output. Returns true + // if successful, false on a write error. + virtual bool Write(const void* buffer, int size) = 0; +}; + +// A ZeroCopyOutputStream which writes to a CopyingOutputStream. This is +// useful for implementing ZeroCopyOutputStreams that write to traditional +// streams. Note that this class is not really zero-copy. +// +// If you want to write to file descriptors or C++ ostreams, this is +// already implemented for you: use FileOutputStream or OstreamOutputStream +// respectively. +class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream { + public: + // Creates a stream that writes to the given Unix file descriptor. + // If a block_size is given, it specifies the size of the buffers + // that should be returned by Next(). Otherwise, a reasonable default + // is used. + explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream, + int block_size = -1); + ~CopyingOutputStreamAdaptor(); + + // Writes all pending data to the underlying stream. Returns false if a + // write error occurred on the underlying stream. (The underlying + // stream itself is not necessarily flushed.) + bool Flush(); + + // Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to + // delete the underlying CopyingOutputStream when it is destroyed. + void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + // Write the current buffer, if it is present. + bool WriteBuffer(); + // Insures that buffer_ is not NULL. + void AllocateBufferIfNeeded(); + // Frees the buffer. + void FreeBuffer(); + + // The underlying copying stream. + CopyingOutputStream* copying_stream_; + bool owns_copying_stream_; + + // True if we have seen a permenant error from the underlying stream. + bool failed_; + + // The current position of copying_stream_, relative to the point where + // we started writing. + int64 position_; + + // Data is written from this buffer. It may be NULL if no buffer is + // currently in use. Otherwise, it points to an array of size buffer_size_. + scoped_array buffer_; + const int buffer_size_; + + // Number of valid bytes currently in the buffer (i.e. the size last + // returned by Next()). When BackUp() is called, we just reduce this. + // 0 <= buffer_used_ <= buffer_size_. + int buffer_used_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor); +}; + +// =================================================================== + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc index 9adef74d..5e3310ac 100644 --- a/src/google/protobuf/io/zero_copy_stream_unittest.cc +++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc @@ -61,6 +61,7 @@ #include #include + #if HAVE_ZLIB #include #endif diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc new file mode 100644 index 00000000..83932859 --- /dev/null +++ b/src/google/protobuf/lite_unittest.cc @@ -0,0 +1,112 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include +#include + +#include +#include + +using namespace std; + +int main(int argc, char* argv[]) { + string data, packed_data; + + { + protobuf_unittest::TestAllTypesLite message, message2, message3; + google::protobuf::TestUtilLite::ExpectClear(message); + google::protobuf::TestUtilLite::SetAllFields(&message); + message2.CopyFrom(message); + data = message.SerializeAsString(); + message3.ParseFromString(data); + google::protobuf::TestUtilLite::ExpectAllFieldsSet(message); + google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2); + google::protobuf::TestUtilLite::ExpectAllFieldsSet(message3); + google::protobuf::TestUtilLite::ModifyRepeatedFields(&message); + google::protobuf::TestUtilLite::ExpectRepeatedFieldsModified(message); + message.Clear(); + google::protobuf::TestUtilLite::ExpectClear(message); + } + + { + protobuf_unittest::TestAllExtensionsLite message, message2, message3; + google::protobuf::TestUtilLite::ExpectExtensionsClear(message); + google::protobuf::TestUtilLite::SetAllExtensions(&message); + message2.CopyFrom(message); + string extensions_data = message.SerializeAsString(); + GOOGLE_CHECK(extensions_data == data); + message3.ParseFromString(extensions_data); + google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message); + google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2); + google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message3); + google::protobuf::TestUtilLite::ModifyRepeatedExtensions(&message); + google::protobuf::TestUtilLite::ExpectRepeatedExtensionsModified(message); + message.Clear(); + google::protobuf::TestUtilLite::ExpectExtensionsClear(message); + } + + { + protobuf_unittest::TestPackedTypesLite message, message2, message3; + google::protobuf::TestUtilLite::ExpectPackedClear(message); + google::protobuf::TestUtilLite::SetPackedFields(&message); + message2.CopyFrom(message); + packed_data = message.SerializeAsString(); + message3.ParseFromString(packed_data); + google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message); + google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2); + google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message3); + google::protobuf::TestUtilLite::ModifyPackedFields(&message); + google::protobuf::TestUtilLite::ExpectPackedFieldsModified(message); + message.Clear(); + google::protobuf::TestUtilLite::ExpectPackedClear(message); + } + + { + protobuf_unittest::TestPackedExtensionsLite message, message2, message3; + google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); + google::protobuf::TestUtilLite::SetPackedExtensions(&message); + message2.CopyFrom(message); + string packed_extensions_data = message.SerializeAsString(); + GOOGLE_CHECK(packed_extensions_data == packed_data); + message3.ParseFromString(packed_extensions_data); + google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message); + google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2); + google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message3); + google::protobuf::TestUtilLite::ModifyPackedExtensions(&message); + google::protobuf::TestUtilLite::ExpectPackedExtensionsModified(message); + message.Clear(); + google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); + } + + cout << "PASS"; + return 0; +} diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index 9df3d394..f4519cd2 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -45,7 +45,6 @@ #include #include #include -#include #include #include @@ -55,15 +54,6 @@ namespace protobuf { using internal::WireFormat; using internal::ReflectionOps; -static string InitializationErrorMessage(const char* action, - const Message& message) { - return strings::Substitute( - "Can't $0 message of type \"$1\" because it is missing required " - "fields: $2", - action, message.GetDescriptor()->full_name(), - message.InitializationErrorString()); -} - Message::~Message() {} void Message::MergeFrom(const Message& from) { @@ -75,6 +65,10 @@ void Message::MergeFrom(const Message& from) { ReflectionOps::Merge(from, this); } +void Message::CheckTypeAndMergeFrom(const MessageLite& other) { + MergeFrom(*down_cast(&other)); +} + void Message::CopyFrom(const Message& from) { const Descriptor* descriptor = GetDescriptor(); GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor) @@ -84,6 +78,10 @@ void Message::CopyFrom(const Message& from) { ReflectionOps::Copy(from, this); } +string Message::GetTypeName() const { + return GetDescriptor()->full_name(); +} + void Message::Clear() { ReflectionOps::Clear(this); } @@ -116,74 +114,6 @@ bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) { return WireFormat::ParseAndMergePartial(input, this); } -bool Message::MergeFromCodedStream(io::CodedInputStream* input) { - if (!MergePartialFromCodedStream(input)) return false; - if (!IsInitialized()) { - GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *this); - return false; - } - return true; -} - -bool Message::ParseFromCodedStream(io::CodedInputStream* input) { - Clear(); - return MergeFromCodedStream(input); -} - -bool Message::ParsePartialFromCodedStream(io::CodedInputStream* input) { - Clear(); - return MergePartialFromCodedStream(input); -} - -bool Message::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { - io::CodedInputStream decoder(input); - return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage(); -} - -bool Message::ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input) { - io::CodedInputStream decoder(input); - return ParsePartialFromCodedStream(&decoder) && - decoder.ConsumedEntireMessage(); -} - -bool Message::ParseFromBoundedZeroCopyStream( - io::ZeroCopyInputStream* input, int size) { - io::CodedInputStream decoder(input); - decoder.PushLimit(size); - return ParseFromCodedStream(&decoder) && - decoder.ConsumedEntireMessage() && - decoder.BytesUntilLimit() == 0; -} - -bool Message::ParsePartialFromBoundedZeroCopyStream( - io::ZeroCopyInputStream* input, int size) { - io::CodedInputStream decoder(input); - decoder.PushLimit(size); - return ParsePartialFromCodedStream(&decoder) && - decoder.ConsumedEntireMessage() && - decoder.BytesUntilLimit() == 0; -} - -bool Message::ParseFromString(const string& data) { - io::ArrayInputStream input(data.data(), data.size()); - return ParseFromBoundedZeroCopyStream(&input, data.size()); -} - -bool Message::ParsePartialFromString(const string& data) { - io::ArrayInputStream input(data.data(), data.size()); - return ParsePartialFromBoundedZeroCopyStream(&input, data.size()); -} - -bool Message::ParseFromArray(const void* data, int size) { - io::ArrayInputStream input(data, size); - return ParseFromBoundedZeroCopyStream(&input, size); -} - -bool Message::ParsePartialFromArray(const void* data, int size) { - io::ArrayInputStream input(data, size); - return ParsePartialFromBoundedZeroCopyStream(&input, size); -} - bool Message::ParseFromFileDescriptor(int file_descriptor) { io::FileInputStream input(file_descriptor); return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0; @@ -205,22 +135,11 @@ bool Message::ParsePartialFromIstream(istream* input) { } - void Message::SerializeWithCachedSizes( io::CodedOutputStream* output) const { WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output); } -uint8* Message::SerializeWithCachedSizesToArray(uint8* target) const { - // We only optimize this when using optimize_for = SPEED. - int size = GetCachedSize(); - io::ArrayOutputStream out(target, size); - io::CodedOutputStream coded_out(&out); - SerializeWithCachedSizes(&coded_out); - GOOGLE_CHECK(!coded_out.HadError()); - return target + size; -} - int Message::ByteSize() const { int size = WireFormat::ByteSize(*this); SetCachedSize(size); @@ -237,69 +156,6 @@ int Message::SpaceUsed() const { return GetReflection()->SpaceUsed(*this); } -bool Message::SerializeToCodedStream(io::CodedOutputStream* output) const { - GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); - return SerializePartialToCodedStream(output); -} - -bool Message::SerializePartialToCodedStream( - io::CodedOutputStream* output) const { - ByteSize(); // Force size to be cached. - SerializeWithCachedSizes(output); - return !output->HadError(); -} - -bool Message::SerializeToZeroCopyStream( - io::ZeroCopyOutputStream* output) const { - io::CodedOutputStream encoder(output); - return SerializeToCodedStream(&encoder); -} - -bool Message::SerializePartialToZeroCopyStream( - io::ZeroCopyOutputStream* output) const { - io::CodedOutputStream encoder(output); - return SerializePartialToCodedStream(&encoder); -} - -bool Message::AppendToString(string* output) const { - GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); - return AppendPartialToString(output); -} - -bool Message::AppendPartialToString(string* output) const { - int old_size = output->size(); - int byte_size = ByteSize(); - STLStringResizeUninitialized(output, old_size + byte_size); - uint8* start = reinterpret_cast(string_as_array(output) + old_size); - uint8* end = SerializeWithCachedSizesToArray(start); - GOOGLE_CHECK_EQ(end, start + byte_size); - return true; -} - -bool Message::SerializeToString(string* output) const { - output->clear(); - return AppendToString(output); -} - -bool Message::SerializePartialToString(string* output) const { - output->clear(); - return AppendPartialToString(output); -} - -bool Message::SerializeToArray(void* data, int size) const { - GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); - return SerializePartialToArray(data, size); -} - -bool Message::SerializePartialToArray(void* data, int size) const { - int byte_size = ByteSize(); - if (size < byte_size) return false; - uint8* end = - SerializeWithCachedSizesToArray(reinterpret_cast(data)); - GOOGLE_CHECK_EQ(end, reinterpret_cast(data) + byte_size); - return true; -} - bool Message::SerializeToFileDescriptor(int file_descriptor) const { io::FileOutputStream output(file_descriptor); return SerializeToZeroCopyStream(&output); @@ -321,24 +177,6 @@ bool Message::SerializePartialToOstream(ostream* output) const { } -string Message::SerializeAsString() const { - // If the compiler implements the (Named) Return Value Optimization, - // the local variable 'result' will not actually reside on the stack - // of this function, but will be overlaid with the object that the - // caller supplied for the return value to be constructed in. - string output; - if (!AppendToString(&output)) - output.clear(); - return output; -} - -string Message::SerializePartialAsString() const { - string output; - if (!AppendPartialToString(&output)) - output.clear(); - return output; -} - Reflection::~Reflection() {} // =================================================================== @@ -355,7 +193,7 @@ class GeneratedMessageFactory : public MessageFactory { static GeneratedMessageFactory* singleton(); - typedef void RegistrationFunc(); + typedef void RegistrationFunc(const string&); void RegisterFile(const char* file, RegistrationFunc* registration_func); void RegisterType(const Descriptor* descriptor, const Message* prototype); @@ -378,8 +216,8 @@ GeneratedMessageFactory::~GeneratedMessageFactory() {} GeneratedMessageFactory* GeneratedMessageFactory::singleton() { // No need for thread-safety here because this will be called at static // initialization time. (And GCC4 makes this thread-safe anyway.) - static GeneratedMessageFactory singleton; - return &singleton; + static GeneratedMessageFactory* singleton = new GeneratedMessageFactory; + return singleton; } void GeneratedMessageFactory::RegisterFile( @@ -430,7 +268,7 @@ const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) { const Message* result = FindPtrOrNull(type_map_, type); if (result == NULL) { // Nope. OK, register everything. - registration_func(); + registration_func(type->file()->name()); // Should be here now. result = FindPtrOrNull(type_map_, type); } @@ -450,7 +288,7 @@ MessageFactory* MessageFactory::generated_factory() { } void MessageFactory::InternalRegisterGeneratedFile( - const char* filename, void (*register_messages)()) { + const char* filename, void (*register_messages)(const string&)) { GeneratedMessageFactory::singleton()->RegisterFile(filename, register_messages); } diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 41716057..eecd91a7 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -98,9 +98,9 @@ // const Reflection* reflection = foo->GetReflection(); // assert(reflection->GetString(foo, text_field) == "Hello World!"); // assert(reflection->FieldSize(foo, numbers_field) == 3); -// assert(reflection->GetInt32(foo, numbers_field, 0) == 1); -// assert(reflection->GetInt32(foo, numbers_field, 1) == 5); -// assert(reflection->GetInt32(foo, numbers_field, 2) == 42); +// assert(reflection->GetRepeatedInt32(foo, numbers_field, 0) == 1); +// assert(reflection->GetRepeatedInt32(foo, numbers_field, 1) == 5); +// assert(reflection->GetRepeatedInt32(foo, numbers_field, 2) == 42); // // delete foo; // } @@ -118,6 +118,10 @@ #include #endif +#include + +#include + #if defined(_WIN32) && defined(GetMessage) // windows.h defines GetMessage() as a macro. Let's re-define it as an inline // function. This is necessary because Reflection has a method called @@ -136,10 +140,8 @@ inline BOOL GetMessage( } #endif -#include namespace google { - namespace protobuf { // Defined in this file. @@ -149,6 +151,7 @@ class Reflection; // Defined in other files. class Descriptor; // descriptor.h class FieldDescriptor; // descriptor.h +class EnumDescriptor; // descriptor.h class EnumValueDescriptor; // descriptor.h namespace io { class ZeroCopyInputStream; // zero_copy_stream.h @@ -158,14 +161,28 @@ namespace io { } class UnknownFieldSet; // unknown_field_set.h +// A container to hold message metadata. +struct Metadata { + const Descriptor* descriptor; + const Reflection* reflection; +}; + +// Returns the EnumDescriptor for enum type E, which must be a +// proto-declared enum type. +template +const EnumDescriptor* GetEnumDescriptor(); + // Abstract interface for protocol messages. // +// See also MessageLite, which contains most every-day operations. Message +// adds descriptors and reflection on top of that. +// // The methods of this class that are virtual but not pure-virtual have // default implementations based on reflection. Message classes which are // optimized for speed will want to override these with faster implementations, // but classes optimized for code size may be happy with keeping them. See // the optimize_for option in descriptor.proto. -class LIBPROTOBUF_EXPORT Message { +class LIBPROTOBUF_EXPORT Message : public MessageLite { public: inline Message() {} virtual ~Message(); @@ -173,7 +190,8 @@ class LIBPROTOBUF_EXPORT Message { // Basic Operations ------------------------------------------------ // Construct a new instance of the same type. Ownership is passed to the - // caller. + // caller. (This is also defined in MessageLite, but is defined again here + // for return-type covariance.) virtual Message* New() const = 0; // Make this message into a copy of the given message. The given message @@ -187,16 +205,6 @@ class LIBPROTOBUF_EXPORT Message { // must be of the same type as this message (i.e. the exact same class). virtual void MergeFrom(const Message& from); - // Clear all fields of the message and set them to their default values. - // Clear() avoids freeing memory, assuming that any memory allocated - // to hold parts of the message will be needed again to hold the next - // message. If you actually want to free the memory used by a Message, - // you must delete it. - virtual void Clear(); - - // Quickly check if all required fields have values set. - virtual bool IsInitialized() const; - // Verifies that IsInitialized() returns true. GOOGLE_CHECK-fails otherwise, with // a nice error message. void CheckInitialized() const; @@ -238,41 +246,9 @@ class LIBPROTOBUF_EXPORT Message { // Convenience function useful in GDB. Prints DebugString() to stdout. void PrintDebugString() const; - // Parsing --------------------------------------------------------- - // Methods for parsing in protocol buffer format. Most of these are - // just simple wrappers around MergeFromCodedStream(). - - // Fill the message with a protocol buffer parsed from the given input - // stream. Returns false on a read error or if the input is in the - // wrong format. - bool ParseFromCodedStream(io::CodedInputStream* input); - // Like ParseFromCodedStream(), but accepts messages that are missing - // required fields. - bool ParsePartialFromCodedStream(io::CodedInputStream* input); - // Read a protocol buffer from the given zero-copy input stream. If - // successful, the entire input will be consumed. - bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); - // Like ParseFromZeroCopyStream(), but accepts messages that are missing - // required fields. - bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input); - // Read a protocol buffer from the given zero-copy input stream, expecting - // the message to be exactly "size" bytes long. If successful, exactly - // this many bytes will have been consumed from the input. - bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); - // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are - // missing required fields. - bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, - int size); - // Parse a protocol buffer contained in a string. - bool ParseFromString(const string& data); - // Like ParseFromString(), but accepts messages that are missing - // required fields. - bool ParsePartialFromString(const string& data); - // Parse a protocol buffer contained in an array of bytes. - bool ParseFromArray(const void* data, int size); - // Like ParseFromArray(), but accepts messages that are missing - // required fields. - bool ParsePartialFromArray(const void* data, int size); + // Heavy I/O ------------------------------------------------------- + // Additional parsing and serialization methods not implemented by + // MessageLite because they are not supported by the lite library. // Parse a protocol buffer from a file descriptor. If successful, the entire // input will be consumed. @@ -287,53 +263,6 @@ class LIBPROTOBUF_EXPORT Message { // required fields. bool ParsePartialFromIstream(istream* input); - - // Reads a protocol buffer from the stream and merges it into this - // Message. Singular fields read from the input overwrite what is - // already in the Message and repeated fields are appended to those - // already present. - // - // It is the responsibility of the caller to call input->LastTagWas() - // (for groups) or input->ConsumedEntireMessage() (for non-groups) after - // this returns to verify that the message's end was delimited correctly. - // - // ParsefromCodedStream() is implemented as Clear() followed by - // MergeFromCodedStream(). - bool MergeFromCodedStream(io::CodedInputStream* input); - - // Like MergeFromCodedStream(), but succeeds even if required fields are - // missing in the input. - // - // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream() - // followed by IsInitialized(). - virtual bool MergePartialFromCodedStream(io::CodedInputStream* input); - - // Serialization --------------------------------------------------- - // Methods for serializing in protocol buffer format. Most of these - // are just simple wrappers around ByteSize() and SerializeWithCachedSizes(). - - // Write a protocol buffer of this message to the given output. Returns - // false on a write error. If the message is missing required fields, - // this may GOOGLE_CHECK-fail. - bool SerializeToCodedStream(io::CodedOutputStream* output) const; - // Like SerializeToCodedStream(), but allows missing required fields. - bool SerializePartialToCodedStream(io::CodedOutputStream* output) const; - // Write the message to the given zero-copy output stream. All required - // fields must be set. - bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const; - // Like SerializeToZeroCopyStream(), but allows missing required fields. - bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const; - // Serialize the message and store it in the given string. All required - // fields must be set. - bool SerializeToString(string* output) const; - // Like SerializeToString(), but allows missing required fields. - bool SerializePartialToString(string* output) const; - // Serialize the message and store it in the given byte array. All required - // fields must be set. - bool SerializeToArray(void* data, int size) const; - // Like SerializeToArray(), but allows missing required fields. - bool SerializePartialToArray(void* data, int size) const; - // Serialize the message and write it to the given file descriptor. All // required fields must be set. bool SerializeToFileDescriptor(int file_descriptor) const; @@ -346,50 +275,18 @@ class LIBPROTOBUF_EXPORT Message { bool SerializePartialToOstream(ostream* output) const; - // Make a string encoding the message. Is equivalent to calling - // SerializeToString() on a string and using that. Returns the empty - // string if SerializeToString() would have returned an error. - // Note: If you intend to generate many such strings, you may - // reduce heap fragmentation by instead re-using the same string - // object with calls to SerializeToString(). - string SerializeAsString() const; - // Like SerializeAsString(), but allows missing required fields. - string SerializePartialAsString() const; - - // Like SerializeToString(), but appends to the data to the string's existing - // contents. All required fields must be set. - bool AppendToString(string* output) const; - // Like AppendToString(), but allows missing required fields. - bool AppendPartialToString(string* output) const; - - // Computes the serialized size of the message. This recursively calls - // ByteSize() on all embedded messages. If a subclass does not override - // this, it MUST override SetCachedSize(). - virtual int ByteSize() const; + // Reflection-based methods ---------------------------------------- + // These methods are pure-virtual in MessageLite, but Message provides + // reflection-based default implementations. - // Serializes the message without recomputing the size. The message must - // not have changed since the last call to ByteSize(); if it has, the results - // are undefined. + virtual string GetTypeName() const; + virtual void Clear(); + virtual bool IsInitialized() const; + virtual void CheckTypeAndMergeFrom(const MessageLite& other); + virtual bool MergePartialFromCodedStream(io::CodedInputStream* input); + virtual int ByteSize() const; virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const; - // Like SerializeWithCachedSizes, but writes directly to *target, returning - // a pointer to the byte immediately after the last byte written. "target" - // must point at a byte array of at least ByteSize() bytes. - virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const; - - // Returns the result of the last call to ByteSize(). An embedded message's - // size is needed both to serialize it (because embedded messages are - // length-delimited) and to compute the outer message's size. Caching - // the size avoids computing it multiple times. - // - // ByteSize() does not automatically use the cached size when available - // because this would require invalidating it every time the message was - // modified, which would be too hard and expensive. (E.g. if a deeply-nested - // sub-message is changed, all of its parents' cached sizes would need to be - // invalidated, which is too much work for an otherwise inlined setter - // method.) - virtual int GetCachedSize() const = 0; - private: // This is called only by the default implementation of ByteSize(), to // update the cached size. If you override ByteSize(), you do not need @@ -409,13 +306,24 @@ class LIBPROTOBUF_EXPORT Message { // Get a Descriptor for this message's type. This describes what // fields the message contains, the types of those fields, etc. - virtual const Descriptor* GetDescriptor() const = 0; + const Descriptor* GetDescriptor() const { return GetMetadata().descriptor; } // Get the Reflection interface for this Message, which can be used to // read and modify the fields of the Message dynamically (in other words, // without knowing the message type at compile time). This object remains // property of the Message. - virtual const Reflection* GetReflection() const = 0; + // + // This method remains virtual in case a subclass does not implement + // reflection and wants to override the default behavior. + virtual const Reflection* GetReflection() const { + return GetMetadata().reflection; + } + + protected: + // Get a struct containing the metadata for the Message. Most subclasses only + // need to implement this method, rather than the GetDescriptor() and + // GetReflection() wrappers. + virtual Metadata GetMetadata() const = 0; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); @@ -758,12 +666,13 @@ class LIBPROTOBUF_EXPORT MessageFactory { // For internal use only: Registers a .proto file at static initialization // time, to be placed in generated_factory. The first time GetPrototype() // is called with a descriptor from this file, |register_messages| will be - // called. It must call InternalRegisterGeneratedMessage() (below) to - // register each message type in the file. This strange mechanism is - // necessary because descriptors are built lazily, so we can't register - // types by their descriptor until we know that the descriptor exists. - static void InternalRegisterGeneratedFile(const char* filename, - void (*register_messages)()); + // called, with the file name as the parameter. It must call + // InternalRegisterGeneratedMessage() (below) to register each message type + // in the file. This strange mechanism is necessary because descriptors are + // built lazily, so we can't register types by their descriptor until we + // know that the descriptor exists. |filename| must be a permanent string. + static void InternalRegisterGeneratedFile( + const char* filename, void (*register_messages)(const string&)); // For internal use only: Registers a message type. Called only by the // functions which are registered with InternalRegisterGeneratedFile(), diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc new file mode 100644 index 00000000..5e156f25 --- /dev/null +++ b/src/google/protobuf/message_lite.cc @@ -0,0 +1,282 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Authors: wink@google.com (Wink Saville), +// kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + + +#include + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +MessageLite::~MessageLite() {} + +string MessageLite::InitializationErrorString() const { + return "(cannot determine missing fields for lite message)"; +} + +namespace { + +string InitializationErrorMessage(const char* action, + const MessageLite& message) { + return strings::Substitute( + "Can't $0 message of type \"$1\" because it is missing required " + "fields: $2", + action, message.GetTypeName(), + message.InitializationErrorString()); +} + +// Several of the Parse methods below just do one thing and then call another +// method. In a naive implementation, we might have ParseFromString() call +// ParseFromArray() which would call ParseFromZeroCopyStream() which would call +// ParseFromCodedStream() which would call MergeFromCodedStream() which would +// call MergePartialFromCodedStream(). However, when parsing very small +// messages, every function call introduces significant overhead. To avoid +// this without reproducing code, we use these forced-inline helpers. +// +// Note: GCC only allows GOOGLE_ATTRIBUTE_ALWAYS_INLINE on declarations, not +// definitions. +inline bool InlineMergeFromCodedStream(io::CodedInputStream* input, + MessageLite* message) + GOOGLE_ATTRIBUTE_ALWAYS_INLINE; +inline bool InlineParseFromCodedStream(io::CodedInputStream* input, + MessageLite* message) + GOOGLE_ATTRIBUTE_ALWAYS_INLINE; +inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input, + MessageLite* message) + GOOGLE_ATTRIBUTE_ALWAYS_INLINE; +inline bool InlineParseFromArray(const void* data, int size, + MessageLite* message) + GOOGLE_ATTRIBUTE_ALWAYS_INLINE; +inline bool InlineParsePartialFromArray(const void* data, int size, + MessageLite* message) + GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + +bool InlineMergeFromCodedStream(io::CodedInputStream* input, + MessageLite* message) { + if (!message->MergePartialFromCodedStream(input)) return false; + if (!message->IsInitialized()) { + GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message); + return false; + } + return true; +} + +bool InlineParseFromCodedStream(io::CodedInputStream* input, + MessageLite* message) { + message->Clear(); + return InlineMergeFromCodedStream(input, message); +} + +bool InlineParsePartialFromCodedStream(io::CodedInputStream* input, + MessageLite* message) { + message->Clear(); + return message->MergePartialFromCodedStream(input); +} + +bool InlineParseFromArray(const void* data, int size, MessageLite* message) { + io::CodedInputStream input(reinterpret_cast(data), size); + return InlineParseFromCodedStream(&input, message) && + input.ConsumedEntireMessage(); +} + +bool InlineParsePartialFromArray(const void* data, int size, + MessageLite* message) { + io::CodedInputStream input(reinterpret_cast(data), size); + return InlineParsePartialFromCodedStream(&input, message) && + input.ConsumedEntireMessage(); +} + +} // namespace + +bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) { + return InlineMergeFromCodedStream(input, this); +} + +bool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) { + return InlineParseFromCodedStream(input, this); +} + +bool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) { + return InlineParsePartialFromCodedStream(input, this); +} + +bool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { + io::CodedInputStream decoder(input); + return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage(); +} + +bool MessageLite::ParsePartialFromZeroCopyStream( + io::ZeroCopyInputStream* input) { + io::CodedInputStream decoder(input); + return ParsePartialFromCodedStream(&decoder) && + decoder.ConsumedEntireMessage(); +} + +bool MessageLite::ParseFromBoundedZeroCopyStream( + io::ZeroCopyInputStream* input, int size) { + io::CodedInputStream decoder(input); + decoder.PushLimit(size); + return ParseFromCodedStream(&decoder) && + decoder.ConsumedEntireMessage() && + decoder.BytesUntilLimit() == 0; +} + +bool MessageLite::ParsePartialFromBoundedZeroCopyStream( + io::ZeroCopyInputStream* input, int size) { + io::CodedInputStream decoder(input); + decoder.PushLimit(size); + return ParsePartialFromCodedStream(&decoder) && + decoder.ConsumedEntireMessage() && + decoder.BytesUntilLimit() == 0; +} + +bool MessageLite::ParseFromString(const string& data) { + return InlineParseFromArray(data.data(), data.size(), this); +} + +bool MessageLite::ParsePartialFromString(const string& data) { + return InlineParsePartialFromArray(data.data(), data.size(), this); +} + +bool MessageLite::ParseFromArray(const void* data, int size) { + return InlineParseFromArray(data, size, this); +} + +bool MessageLite::ParsePartialFromArray(const void* data, int size) { + return InlineParsePartialFromArray(data, size, this); +} + + +// =================================================================== + +uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const { + // We only optimize this when using optimize_for = SPEED. In other cases + // we just use the CodedOutputStream path. + int size = GetCachedSize(); + io::ArrayOutputStream out(target, size); + io::CodedOutputStream coded_out(&out); + SerializeWithCachedSizes(&coded_out); + GOOGLE_CHECK(!coded_out.HadError()); + return target + size; +} + +bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const { + GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); + return SerializePartialToCodedStream(output); +} + +bool MessageLite::SerializePartialToCodedStream( + io::CodedOutputStream* output) const { + ByteSize(); // Force size to be cached. + SerializeWithCachedSizes(output); + return !output->HadError(); +} + +bool MessageLite::SerializeToZeroCopyStream( + io::ZeroCopyOutputStream* output) const { + io::CodedOutputStream encoder(output); + return SerializeToCodedStream(&encoder); +} + +bool MessageLite::SerializePartialToZeroCopyStream( + io::ZeroCopyOutputStream* output) const { + io::CodedOutputStream encoder(output); + return SerializePartialToCodedStream(&encoder); +} + +bool MessageLite::AppendToString(string* output) const { + GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); + return AppendPartialToString(output); +} + +bool MessageLite::AppendPartialToString(string* output) const { + int old_size = output->size(); + int byte_size = ByteSize(); + STLStringResizeUninitialized(output, old_size + byte_size); + uint8* start = reinterpret_cast(string_as_array(output) + old_size); + uint8* end = SerializeWithCachedSizesToArray(start); + GOOGLE_CHECK_EQ(end - start, byte_size); + return true; +} + +bool MessageLite::SerializeToString(string* output) const { + output->clear(); + return AppendToString(output); +} + +bool MessageLite::SerializePartialToString(string* output) const { + output->clear(); + return AppendPartialToString(output); +} + +bool MessageLite::SerializeToArray(void* data, int size) const { + GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); + return SerializePartialToArray(data, size); +} + +bool MessageLite::SerializePartialToArray(void* data, int size) const { + int byte_size = ByteSize(); + if (size < byte_size) return false; + uint8* end = + SerializeWithCachedSizesToArray(reinterpret_cast(data)); + GOOGLE_CHECK_EQ(end, reinterpret_cast(data) + byte_size); + return true; +} + +string MessageLite::SerializeAsString() const { + // If the compiler implements the (Named) Return Value Optimization, + // the local variable 'result' will not actually reside on the stack + // of this function, but will be overlaid with the object that the + // caller supplied for the return value to be constructed in. + string output; + if (!AppendToString(&output)) + output.clear(); + return output; +} + +string MessageLite::SerializePartialAsString() const { + string output; + if (!AppendPartialToString(&output)) + output.clear(); + return output; +} + +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h new file mode 100644 index 00000000..d289d8c7 --- /dev/null +++ b/src/google/protobuf/message_lite.h @@ -0,0 +1,237 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Authors: wink@google.com (Wink Saville), +// kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// + +#ifndef GOOGLE_PROTOBUF_MESSAGE_LITE_H__ +#define GOOGLE_PROTOBUF_MESSAGE_LITE_H__ + +#include +#include + +namespace google { +namespace protobuf { + +// Interface to light weight protocol messages. +// +// This interface is implemented by all protocol message objects. Most +// users will be more interested in the Message interface, which is a +// subclass of MessageLite. Use MessageLite instead when you only need +// the subset of features which it supports -- namely, nothing that uses +// descriptors or reflection. You can instruct the protocol compiler +// to generate classes which implement only MessageLite, not the full +// Message interface, by adding the following line to the .proto file: +// +// option optimize_for = LITE_RUNTIME; +// +// This is particularly useful on resource-constrained systems where +// the full protocol buffers runtime library is too big. +// +// Note that on non-constrained systems (e.g. servers) when you need +// to link in lots of protocol definitions, a better way to reduce +// total code footprint is to use optimize_for = CODE_SIZE. This +// will make the generated code smaller while still supporting all the +// same features (at the expense of speed). optimize_for = LITE_RUNTIME +// is best when you only have a small number of message types linked +// into your binary, in which case the size of the protocol buffers +// runtime itself is the biggest problem. +class LIBPROTOBUF_EXPORT MessageLite { + public: + inline MessageLite() {} + virtual ~MessageLite(); + + // Basic Operations ------------------------------------------------ + + // Get the name of this message type, e.g. "foo.bar.BazProto". + virtual string GetTypeName() const = 0; + + // Construct a new instance of the same type. Ownership is passed to the + // caller. + virtual MessageLite* New() const = 0; + + // Clear all fields of the message and set them to their default values. + // Clear() avoids freeing memory, assuming that any memory allocated + // to hold parts of the message will be needed again to hold the next + // message. If you actually want to free the memory used by a Message, + // you must delete it. + virtual void Clear() = 0; + + // Quickly check if all required fields have values set. + virtual bool IsInitialized() const = 0; + + // This is not implemented for Lite messages -- it just returns "(cannot + // determine missing fields for lite message)". However, it is implemented + // for full messages. See message.h. + virtual string InitializationErrorString() const; + + // If |other| is the exact same class as this, calls MergeFrom(). Otherwise, + // results are undefined (probably crash). + virtual void CheckTypeAndMergeFrom(const MessageLite& other) = 0; + + // Parsing --------------------------------------------------------- + // Methods for parsing in protocol buffer format. Most of these are + // just simple wrappers around MergeFromCodedStream(). + + // Fill the message with a protocol buffer parsed from the given input + // stream. Returns false on a read error or if the input is in the + // wrong format. + bool ParseFromCodedStream(io::CodedInputStream* input); + // Like ParseFromCodedStream(), but accepts messages that are missing + // required fields. + bool ParsePartialFromCodedStream(io::CodedInputStream* input); + // Read a protocol buffer from the given zero-copy input stream. If + // successful, the entire input will be consumed. + bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); + // Like ParseFromZeroCopyStream(), but accepts messages that are missing + // required fields. + bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input); + // Read a protocol buffer from the given zero-copy input stream, expecting + // the message to be exactly "size" bytes long. If successful, exactly + // this many bytes will have been consumed from the input. + bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); + // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are + // missing required fields. + bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, + int size); + // Parse a protocol buffer contained in a string. + bool ParseFromString(const string& data); + // Like ParseFromString(), but accepts messages that are missing + // required fields. + bool ParsePartialFromString(const string& data); + // Parse a protocol buffer contained in an array of bytes. + bool ParseFromArray(const void* data, int size); + // Like ParseFromArray(), but accepts messages that are missing + // required fields. + bool ParsePartialFromArray(const void* data, int size); + + + // Reads a protocol buffer from the stream and merges it into this + // Message. Singular fields read from the input overwrite what is + // already in the Message and repeated fields are appended to those + // already present. + // + // It is the responsibility of the caller to call input->LastTagWas() + // (for groups) or input->ConsumedEntireMessage() (for non-groups) after + // this returns to verify that the message's end was delimited correctly. + // + // ParsefromCodedStream() is implemented as Clear() followed by + // MergeFromCodedStream(). + bool MergeFromCodedStream(io::CodedInputStream* input); + + // Like MergeFromCodedStream(), but succeeds even if required fields are + // missing in the input. + // + // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream() + // followed by IsInitialized(). + virtual bool MergePartialFromCodedStream(io::CodedInputStream* input) = 0; + + // Serialization --------------------------------------------------- + // Methods for serializing in protocol buffer format. Most of these + // are just simple wrappers around ByteSize() and SerializeWithCachedSizes(). + + // Write a protocol buffer of this message to the given output. Returns + // false on a write error. If the message is missing required fields, + // this may GOOGLE_CHECK-fail. + bool SerializeToCodedStream(io::CodedOutputStream* output) const; + // Like SerializeToCodedStream(), but allows missing required fields. + bool SerializePartialToCodedStream(io::CodedOutputStream* output) const; + // Write the message to the given zero-copy output stream. All required + // fields must be set. + bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const; + // Like SerializeToZeroCopyStream(), but allows missing required fields. + bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const; + // Serialize the message and store it in the given string. All required + // fields must be set. + bool SerializeToString(string* output) const; + // Like SerializeToString(), but allows missing required fields. + bool SerializePartialToString(string* output) const; + // Serialize the message and store it in the given byte array. All required + // fields must be set. + bool SerializeToArray(void* data, int size) const; + // Like SerializeToArray(), but allows missing required fields. + bool SerializePartialToArray(void* data, int size) const; + + // Make a string encoding the message. Is equivalent to calling + // SerializeToString() on a string and using that. Returns the empty + // string if SerializeToString() would have returned an error. + // Note: If you intend to generate many such strings, you may + // reduce heap fragmentation by instead re-using the same string + // object with calls to SerializeToString(). + string SerializeAsString() const; + // Like SerializeAsString(), but allows missing required fields. + string SerializePartialAsString() const; + + // Like SerializeToString(), but appends to the data to the string's existing + // contents. All required fields must be set. + bool AppendToString(string* output) const; + // Like AppendToString(), but allows missing required fields. + bool AppendPartialToString(string* output) const; + + // Computes the serialized size of the message. This recursively calls + // ByteSize() on all embedded messages. If a subclass does not override + // this, it MUST override SetCachedSize(). + virtual int ByteSize() const = 0; + + // Serializes the message without recomputing the size. The message must + // not have changed since the last call to ByteSize(); if it has, the results + // are undefined. + virtual void SerializeWithCachedSizes( + io::CodedOutputStream* output) const = 0; + + // Like SerializeWithCachedSizes, but writes directly to *target, returning + // a pointer to the byte immediately after the last byte written. "target" + // must point at a byte array of at least ByteSize() bytes. + virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const; + + // Returns the result of the last call to ByteSize(). An embedded message's + // size is needed both to serialize it (because embedded messages are + // length-delimited) and to compute the outer message's size. Caching + // the size avoids computing it multiple times. + // + // ByteSize() does not automatically use the cached size when available + // because this would require invalidating it every time the message was + // modified, which would be too hard and expensive. (E.g. if a deeply-nested + // sub-message is changed, all of its parents' cached sizes would need to be + // invalidated, which is too much work for an otherwise inlined setter + // method.) + virtual int GetCachedSize() const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite); +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_MESSAGE_LITE_H__ diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc index d0592de0..46e68446 100644 --- a/src/google/protobuf/message_unittest.cc +++ b/src/google/protobuf/message_unittest.cc @@ -248,36 +248,6 @@ TEST(MessageTest, ParseFailsOnInvalidMessageEnd) { EXPECT_FALSE(message.ParseFromArray("\014", 1)); } -TEST(MessageTest, FieldConstantValues) { - unittest::TestRequired message; - EXPECT_EQ(protobuf_unittest::TestAllTypes_NestedMessage::kBbFieldNumber, 1); - EXPECT_EQ(protobuf_unittest::TestAllTypes::kOptionalInt32FieldNumber, 1); - EXPECT_EQ(protobuf_unittest::TestAllTypes::kOptionalgroupFieldNumber, 16); - EXPECT_EQ(protobuf_unittest::TestAllTypes::kOptionalNestedMessageFieldNumber, - 18); - EXPECT_EQ(protobuf_unittest::TestAllTypes::kOptionalNestedEnumFieldNumber, - 21); - EXPECT_EQ(protobuf_unittest::TestAllTypes::kRepeatedInt32FieldNumber, 31); - EXPECT_EQ(protobuf_unittest::TestAllTypes::kRepeatedgroupFieldNumber, 46); - EXPECT_EQ(protobuf_unittest::TestAllTypes::kRepeatedNestedMessageFieldNumber, - 48); - EXPECT_EQ(protobuf_unittest::TestAllTypes::kRepeatedNestedEnumFieldNumber, - 51); -} - -TEST(MessageTest, ExtensionConstantValues) { - EXPECT_EQ(protobuf_unittest::TestRequired::kSingleFieldNumber, 1000); - EXPECT_EQ(protobuf_unittest::TestRequired::kMultiFieldNumber, 1001); - EXPECT_EQ(protobuf_unittest::kOptionalInt32ExtensionFieldNumber, 1); - EXPECT_EQ(protobuf_unittest::kOptionalgroupExtensionFieldNumber, 16); - EXPECT_EQ(protobuf_unittest::kOptionalNestedMessageExtensionFieldNumber, 18); - EXPECT_EQ(protobuf_unittest::kOptionalNestedEnumExtensionFieldNumber, 21); - EXPECT_EQ(protobuf_unittest::kRepeatedInt32ExtensionFieldNumber, 31); - EXPECT_EQ(protobuf_unittest::kRepeatedgroupExtensionFieldNumber, 46); - EXPECT_EQ(protobuf_unittest::kRepeatedNestedMessageExtensionFieldNumber, 48); - EXPECT_EQ(protobuf_unittest::kRepeatedNestedEnumExtensionFieldNumber, 51); -} - TEST(MessageFactoryTest, GeneratedFactoryLookup) { EXPECT_EQ( MessageFactory::generated_factory()->GetPrototype( diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc index 2d5cb0a4..270ef064 100644 --- a/src/google/protobuf/repeated_field.cc +++ b/src/google/protobuf/repeated_field.cc @@ -33,30 +33,51 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include +#include namespace google { namespace protobuf { - -// HP C++ on Tru64 can't handle the stuff below being defined out-of-line, so -// on that platform everything is defined in repeated_field.h. On other -// platforms, we want these to be out-of-line to avoid code bloat. -#if !defined(__DECCXX) || !defined(__osf__) - namespace internal { -GenericRepeatedField::~GenericRepeatedField() {} +void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) { + void** swap_elements = elements_; + int swap_current_size = current_size_; + int swap_allocated_size = allocated_size_; + int swap_total_size = total_size_; + // We may not be using initial_space_ but it's not worth checking. Just + // copy it anyway. + void* swap_initial_space[kInitialSize]; + memcpy(swap_initial_space, initial_space_, sizeof(initial_space_)); -} // namespace internal + elements_ = other->elements_; + current_size_ = other->current_size_; + allocated_size_ = other->allocated_size_; + total_size_ = other->total_size_; + memcpy(initial_space_, other->initial_space_, sizeof(initial_space_)); -template <> -void RepeatedPtrField::Clear() { - for (int i = 0; i < current_size_; i++) { - elements_[i]->clear(); + other->elements_ = swap_elements; + other->current_size_ = swap_current_size; + other->allocated_size_ = swap_allocated_size; + other->total_size_ = swap_total_size; + memcpy(other->initial_space_, swap_initial_space, sizeof(swap_initial_space)); + + if (elements_ == other->initial_space_) { + elements_ = initial_space_; + } + if (other->elements_ == initial_space_) { + other->elements_ = other->initial_space_; } - current_size_ = 0; } -#endif // !defined(__DECCXX) || !defined(__osf__) +string* StringTypeHandler::New() { + return new string; +} +void StringTypeHandler::Delete(string* value) { + delete value; +} + + +} // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 4446eaf7..cbe26521 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -49,51 +49,15 @@ #include #include #include -#include +#include namespace google { namespace protobuf { -namespace internal { +class Message; -// DO NOT USE GenericRepeatedField; it should be considered a private detail -// of RepeatedField/RepeatedPtrField that may be removed in the future. -// GeneratedMessageReflection needs to manipulate repeated fields in a -// generic way, so we have them implement this interface. This should ONLY -// be used by GeneratedMessageReflection. This would normally be very bad -// design but GeneratedMessageReflection is a big efficiency hack anyway. -// -// TODO(kenton): Implement something like Jeff's ProtoVoidPtrArray change. -// Then, get rid of GenericRepeatedField. -class LIBPROTOBUF_EXPORT GenericRepeatedField { - public: - inline GenericRepeatedField() {} -#if defined(__DECCXX) && defined(__osf__) - // HP C++ on Tru64 has trouble when this is not defined inline. - virtual ~GenericRepeatedField() {} -#else - virtual ~GenericRepeatedField(); -#endif - - private: - // We only want GeneratedMessageReflection to see and use these, so we - // make them private. Yes, it is valid C++ for a subclass to implement - // a virtual method which is private in the superclass. Crazy, huh? - friend class GeneratedMessageReflection; - - virtual const void* GenericGet(int index) const = 0; - virtual void* GenericMutable(int index) = 0; - virtual void* GenericAdd() = 0; - virtual void GenericClear() = 0; - virtual void GenericRemoveLast() = 0; - virtual void GenericSwap(GenericRepeatedField *other) = 0; - virtual void GenericSwapElements(int index1, int index2) = 0; - virtual int GenericSize() const = 0; - virtual int GenericSpaceUsedExcludingSelf() const = 0; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GenericRepeatedField); -}; +namespace internal { // We need this (from generated_message_reflection.cc). LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str); @@ -105,7 +69,7 @@ LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str); // not ever use a RepeatedField directly; they will use the get-by-index, // set-by-index, and add accessors that are generated for all repeated fields. template -class RepeatedField : public internal::GenericRepeatedField { +class RepeatedField { public: RepeatedField(); ~RepeatedField(); @@ -138,7 +102,7 @@ class RepeatedField : public internal::GenericRepeatedField { // Swap entire contents with "other". void Swap(RepeatedField* other); - // Swap two elements of a repeated field. + // Swap two elements. void SwapElements(int index1, int index2); // STL-like iterator support @@ -154,18 +118,6 @@ class RepeatedField : public internal::GenericRepeatedField { // sizeof(*this) int SpaceUsedExcludingSelf() const; - private: // See GenericRepeatedField for why this is private. - // implements GenericRepeatedField --------------------------------- - const void* GenericGet(int index) const; - void* GenericMutable(int index); - void* GenericAdd(); - void GenericClear(); - void GenericRemoveLast(); - void GenericSwap(GenericRepeatedField *other); - void GenericSwapElements(int index1, int index2); - int GenericSize() const; - int GenericSpaceUsedExcludingSelf() const; - private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedField); @@ -182,25 +134,158 @@ namespace internal { template class RepeatedPtrIterator; } // namespace internal +namespace internal { + +// This is the common base class for RepeatedPtrFields. It deals only in void* +// pointers. Users should not use this interface directly. +// +// The methods of this interface correspond to the methods of RepeatedPtrField, +// but may have a template argument called TypeHandler. Its signature is: +// class TypeHandler { +// public: +// typedef MyType Type; +// static Type* New(); +// static void Delete(Type*); +// static void Clear(Type*); +// static void Merge(const Type& from, Type* to); +// +// // Only needs to be implemented if SpaceUsedExcludingSelf() is called. +// static int SpaceUsed(const Type&); +// }; +class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { + protected: + // The reflection implementation needs to call protected methods directly, + // reinterpreting pointers as being to Message instead of a specific Message + // subclass. + friend class GeneratedMessageReflection; + + // ExtensionSet stores repeated message extensions as + // RepeatedPtrField, but non-lite ExtensionSets need to + // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf() + // reinterpreting MessageLite as Message. ExtensionSet also needs to make + // use of AddFromCleared(), which is not part of the public interface. + friend class ExtensionSet; + + RepeatedPtrFieldBase(); + + // Must be called from destructor. + template + void Destroy(); + + int size() const; + + template + const typename TypeHandler::Type& Get(int index) const; + template + typename TypeHandler::Type* Mutable(int index); + template + typename TypeHandler::Type* Add(); + template + void RemoveLast(); + template + void Clear(); + template + void MergeFrom(const RepeatedPtrFieldBase& other); + + void Reserve(int new_size); + + // Used for constructing iterators. + void* const* raw_data() const; + + template + typename TypeHandler::Type** mutable_data(); + template + const typename TypeHandler::Type* const* data() const; + + void Swap(RepeatedPtrFieldBase* other); + + void SwapElements(int index1, int index2); + + template + int SpaceUsedExcludingSelf() const; + + // Advanced memory management -------------------------------------- + + // Like Add(), but if there are no cleared objects to use, returns NULL. + template + typename TypeHandler::Type* AddFromCleared(); + + template + void AddAllocated(typename TypeHandler::Type* value); + template + typename TypeHandler::Type* ReleaseLast(); + + int ClearedCount(); + template + void AddCleared(typename TypeHandler::Type* value); + template + typename TypeHandler::Type* ReleaseCleared(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase); + + static const int kInitialSize = 4; + + void** elements_; + int current_size_; + int allocated_size_; + int total_size_; + + void* initial_space_[kInitialSize]; + + template + static inline typename TypeHandler::Type* cast(void* element) { + return reinterpret_cast(element); + } + template + static inline const typename TypeHandler::Type* cast(const void* element) { + return reinterpret_cast(element); + } +}; + +template +class GenericTypeHandler { + public: + typedef GenericType Type; + static GenericType* New() { return new GenericType; } + static void Delete(GenericType* value) { delete value; } + static void Clear(GenericType* value) { value->Clear(); } + static void Merge(const GenericType& from, GenericType* to) { + to->MergeFrom(from); + } + static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); } +}; + +template <> +inline void GenericTypeHandler::Merge( + const MessageLite& from, MessageLite* to) { + to->CheckTypeAndMergeFrom(from); +} + +class LIBPROTOBUF_EXPORT StringTypeHandler { + public: + typedef string Type; + static string* New(); + static void Delete(string* value); + static void Clear(string* value) { value->clear(); } + static void Merge(const string& from, string* to) { *to = from; } + static int SpaceUsed(const string& value) { + return sizeof(value) + StringSpaceUsedExcludingSelf(value); + } +}; + + +} // namespace internal + // RepeatedPtrField is like RepeatedField, but used for repeated strings or // Messages. template -class RepeatedPtrField : public internal::GenericRepeatedField { +class RepeatedPtrField : public internal::RepeatedPtrFieldBase { public: RepeatedPtrField(); - // This constructor is only defined for RepeatedPtrField. - // When a RepeatedPtrField is created using this constructor, - // prototype->New() will be called to allocate new elements, rather than - // just using the "new" operator. This is useful for the implementation - // of DynamicMessage, but is not used by normal generated messages. - explicit RepeatedPtrField(const Message* prototype); - ~RepeatedPtrField(); - // Returns the prototype if one was passed to the constructor. - const Message* prototype() const; - int size() const; const Element& Get(int index) const; @@ -223,12 +308,12 @@ class RepeatedPtrField : public internal::GenericRepeatedField { // Swap entire contents with "other". void Swap(RepeatedPtrField* other); - // Swap two elements of a repeated field. + // Swap two elements. void SwapElements(int index1, int index2); // STL-like iterator support - typedef internal::RepeatedPtrIterator iterator; - typedef internal::RepeatedPtrIterator const_iterator; + typedef internal::RepeatedPtrIterator iterator; + typedef internal::RepeatedPtrIterator const_iterator; iterator begin(); const_iterator begin() const; @@ -239,6 +324,11 @@ class RepeatedPtrField : public internal::GenericRepeatedField { // excluding sizeof(*this). int SpaceUsedExcludingSelf() const; + // The spaced used just by the pointer array, not counting the objects pointed + // at. Returns zero if the array is inlined (i.e. initial_space_ is being + // used). + int SpaceUsedByArray() const; + // Advanced memory management -------------------------------------- // When hardcore memory management becomes necessary -- as it often // does here at Google -- the following methods may be useful. @@ -272,38 +362,16 @@ class RepeatedPtrField : public internal::GenericRepeatedField { // Requires: ClearedCount() > 0 Element* ReleaseCleared(); - private: // See GenericRepeatedField for why this is private. - // implements GenericRepeatedField --------------------------------- - const void* GenericGet(int index) const; - void* GenericMutable(int index); - void* GenericAdd(); - void GenericClear(); - void GenericRemoveLast(); - void GenericSwap(GenericRepeatedField *other); - void GenericSwapElements(int index1, int index2); - int GenericSize() const; - int GenericSpaceUsedExcludingSelf() const; - private: - // Returns (an estimate of) the number of bytes used by an individual - // element. - int ElementSpaceUsed(Element* element) const; + class TypeHandler; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrField); - static const int kInitialSize = 4; - - // prototype_ is used for RepeatedPtrField only (see constructor). - const Message* prototype_; - - Element** elements_; - int current_size_; - int allocated_size_; - int total_size_; - - Element* initial_space_[kInitialSize]; - - Element* NewElement(); + // prototype_ is used for RepeatedPtrField and + // RepeatedPtrField only (see constructor). + // TODO(kenton): Can we use some template magic to avoid wasting space on + // this field when it isn't used? + const Element* prototype_; }; // implementation ==================================================== @@ -412,7 +480,7 @@ void RepeatedField::Swap(RepeatedField* other) { template void RepeatedField::SwapElements(int index1, int index2) { - swap(*Mutable(index1), *Mutable(index2)); + swap(elements_[index1], elements_[index2]); } template @@ -441,53 +509,6 @@ inline int RepeatedField::SpaceUsedExcludingSelf() const { return (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0; } -template -const void* RepeatedField::GenericGet(int index) const { - GOOGLE_DCHECK_LT(index, size()); - return elements_ + index; -} - -template -void* RepeatedField::GenericMutable(int index) { - return Mutable(index); -} - -template -void* RepeatedField::GenericAdd() { - Add(Element()); - return Mutable(current_size_ - 1); -} - -template -void RepeatedField::GenericClear() { - Clear(); -} - -template -void RepeatedField::GenericRemoveLast() { - RemoveLast(); -} - -template -void RepeatedField::GenericSwap(GenericRepeatedField *other) { - Swap(down_cast*>(other)); -} - -template -void RepeatedField::GenericSwapElements(int index1, int index2) { - SwapElements(index1, index2); -} - -template -int RepeatedField::GenericSize() const { - return size(); -} - -template -int RepeatedField::GenericSpaceUsedExcludingSelf() const { - return SpaceUsedExcludingSelf(); -} - template inline void RepeatedField::Reserve(int new_size) { if (total_size_ >= new_size) return; @@ -503,188 +524,123 @@ inline void RepeatedField::Reserve(int new_size) { // ------------------------------------------------------------------- -template -inline RepeatedPtrField::RepeatedPtrField() - : prototype_(NULL), - elements_(initial_space_), - current_size_(0), - allocated_size_(0), - total_size_(kInitialSize) { -} +namespace internal { -template <> -inline RepeatedPtrField::RepeatedPtrField(const Message* prototype) - : prototype_(prototype), - elements_(initial_space_), +inline RepeatedPtrFieldBase::RepeatedPtrFieldBase() + : elements_(initial_space_), current_size_(0), allocated_size_(0), total_size_(kInitialSize) { } -template -RepeatedPtrField::~RepeatedPtrField() { +template +void RepeatedPtrFieldBase::Destroy() { for (int i = 0; i < allocated_size_; i++) { - delete elements_[i]; + TypeHandler::Delete(cast(elements_[i])); } if (elements_ != initial_space_) { delete [] elements_; } } -template <> -inline const Message* RepeatedPtrField::prototype() const { - return prototype_; -} - - -template -inline int RepeatedPtrField::size() const { +inline int RepeatedPtrFieldBase::size() const { return current_size_; } -template -inline const Element& RepeatedPtrField::Get(int index) const { +template +inline const typename TypeHandler::Type& +RepeatedPtrFieldBase::Get(int index) const { GOOGLE_DCHECK_LT(index, size()); - return *elements_[index]; + return *cast(elements_[index]); } -template -inline Element* RepeatedPtrField::Mutable(int index) { +template +inline typename TypeHandler::Type* +RepeatedPtrFieldBase::Mutable(int index) { GOOGLE_DCHECK_LT(index, size()); - return elements_[index]; + return cast(elements_[index]); } -template -inline Element* RepeatedPtrField::Add() { - if (current_size_ < allocated_size_) return elements_[current_size_++]; +template +inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() { + if (current_size_ < allocated_size_) { + return cast(elements_[current_size_++]); + } if (allocated_size_ == total_size_) Reserve(total_size_ + 1); ++allocated_size_; - return elements_[current_size_++] = NewElement(); -} - -template -inline void RepeatedPtrField::RemoveLast() { - GOOGLE_DCHECK_GT(current_size_, 0); - elements_[--current_size_]->Clear(); + typename TypeHandler::Type* result = TypeHandler::New(); + elements_[current_size_++] = result; + return result; } -template <> -inline void RepeatedPtrField::RemoveLast() { +template +inline void RepeatedPtrFieldBase::RemoveLast() { GOOGLE_DCHECK_GT(current_size_, 0); - elements_[--current_size_]->clear(); + TypeHandler::Clear(cast(elements_[--current_size_])); } -template -void RepeatedPtrField::Clear() { +template +void RepeatedPtrFieldBase::Clear() { for (int i = 0; i < current_size_; i++) { - elements_[i]->Clear(); + TypeHandler::Clear(cast(elements_[i])); } current_size_ = 0; } -#if defined(__DECCXX) && defined(__osf__) -// HP C++ on Tru64 has trouble when this is not defined inline. -template <> -inline void RepeatedPtrField::Clear() { - for (int i = 0; i < current_size_; i++) { - elements_[i]->clear(); - } - current_size_ = 0; -} -#else -// Specialization defined in repeated_field.cc. -template <> -void LIBPROTOBUF_EXPORT RepeatedPtrField::Clear(); -#endif - -template -void RepeatedPtrField::MergeFrom(const RepeatedPtrField& other) { +template +void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) { Reserve(current_size_ + other.current_size_); for (int i = 0; i < other.current_size_; i++) { - Add()->MergeFrom(other.Get(i)); + TypeHandler::Merge(other.Get(i), Add()); } } -template <> -inline void RepeatedPtrField::MergeFrom(const RepeatedPtrField& other) { - Reserve(current_size_ + other.current_size_); - for (int i = 0; i < other.current_size_; i++) { - Add()->assign(other.Get(i)); - } -} - - -template -inline Element** RepeatedPtrField::mutable_data() { +inline void* const* RepeatedPtrFieldBase::raw_data() const { return elements_; } -template -inline const Element* const* RepeatedPtrField::data() const { - return elements_; +template +inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() { + // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this + // method entirely. + return reinterpret_cast(elements_); } - -template -void RepeatedPtrField::Swap(RepeatedPtrField* other) { - Element** swap_elements = elements_; - int swap_current_size = current_size_; - int swap_allocated_size = allocated_size_; - int swap_total_size = total_size_; - // We may not be using initial_space_ but it's not worth checking. Just - // copy it anyway. - Element* swap_initial_space[kInitialSize]; - memcpy(swap_initial_space, initial_space_, sizeof(initial_space_)); - - elements_ = other->elements_; - current_size_ = other->current_size_; - allocated_size_ = other->allocated_size_; - total_size_ = other->total_size_; - memcpy(initial_space_, other->initial_space_, sizeof(initial_space_)); - - other->elements_ = swap_elements; - other->current_size_ = swap_current_size; - other->allocated_size_ = swap_allocated_size; - other->total_size_ = swap_total_size; - memcpy(other->initial_space_, swap_initial_space, sizeof(swap_initial_space)); - - if (elements_ == other->initial_space_) { - elements_ = initial_space_; - } - if (other->elements_ == initial_space_) { - other->elements_ = other->initial_space_; - } +template +inline const typename TypeHandler::Type* const* +RepeatedPtrFieldBase::data() const { + // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this + // method entirely. + return reinterpret_cast(elements_); } -template -void RepeatedPtrField::SwapElements(int index1, int index2) { +inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) { swap(elements_[index1], elements_[index2]); } -template -inline int RepeatedPtrField::SpaceUsedExcludingSelf() const { +template +inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const { int allocated_bytes = (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0; for (int i = 0; i < allocated_size_; ++i) { - allocated_bytes += ElementSpaceUsed(elements_[i]); + allocated_bytes += TypeHandler::SpaceUsed(*cast(elements_[i])); } return allocated_bytes; } -template -inline int RepeatedPtrField::ElementSpaceUsed(Element* e) const { - return e->SpaceUsed(); -} - -template <> -inline int RepeatedPtrField::ElementSpaceUsed(string* s) const { - return sizeof(*s) + internal::StringSpaceUsedExcludingSelf(*s); +template +inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() { + if (current_size_ < allocated_size_) { + return cast(elements_[current_size_++]); + } else { + return NULL; + } } - -template -inline void RepeatedPtrField::AddAllocated(Element* value) { +template +inline void RepeatedPtrFieldBase::AddAllocated( + typename TypeHandler::Type* value) { if (allocated_size_ == total_size_) Reserve(total_size_ + 1); // We don't care about the order of cleared elements, so if there's one // in the way, just move it to the back of the array. @@ -695,10 +651,11 @@ inline void RepeatedPtrField::AddAllocated(Element* value) { elements_[current_size_++] = value; } -template -inline Element* RepeatedPtrField::ReleaseLast() { +template +inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() { GOOGLE_DCHECK_GT(current_size_, 0); - Element* result = elements_[--current_size_]; + typename TypeHandler::Type* result = + cast(elements_[--current_size_]); --allocated_size_; if (current_size_ < allocated_size_) { // There are cleared elements on the end; replace the removed element @@ -709,93 +666,148 @@ inline Element* RepeatedPtrField::ReleaseLast() { } -template -inline int RepeatedPtrField::ClearedCount() { +inline int RepeatedPtrFieldBase::ClearedCount() { return allocated_size_ - current_size_; } -template -inline void RepeatedPtrField::AddCleared(Element* value) { +template +inline void RepeatedPtrFieldBase::AddCleared( + typename TypeHandler::Type* value) { if (allocated_size_ == total_size_) Reserve(total_size_ + 1); elements_[allocated_size_++] = value; } -template -inline Element* RepeatedPtrField::ReleaseCleared() { +template +inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() { GOOGLE_DCHECK_GT(allocated_size_, current_size_); - return elements_[--allocated_size_]; + return cast(elements_[--allocated_size_]); +} + +inline void RepeatedPtrFieldBase::Reserve(int new_size) { + if (total_size_ >= new_size) return; + + void** old_elements = elements_; + total_size_ = max(total_size_ * 2, new_size); + elements_ = new void*[total_size_]; + memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0])); + if (old_elements != initial_space_) { + delete [] old_elements; + } } +} // namespace internal + +// ------------------------------------------------------------------- template -const void* RepeatedPtrField::GenericGet(int index) const { - return &Get(index); +class RepeatedPtrField::TypeHandler + : public internal::GenericTypeHandler {}; + +template <> +class RepeatedPtrField::TypeHandler + : public internal::StringTypeHandler {}; + + +template +inline RepeatedPtrField::RepeatedPtrField() + : prototype_(NULL) { } template -void* RepeatedPtrField::GenericMutable(int index) { - return Mutable(index); +RepeatedPtrField::~RepeatedPtrField() { + Destroy(); } template -void* RepeatedPtrField::GenericAdd() { - return Add(); +inline int RepeatedPtrField::size() const { + return RepeatedPtrFieldBase::size(); } template -void RepeatedPtrField::GenericClear() { - Clear(); +inline const Element& RepeatedPtrField::Get(int index) const { + return RepeatedPtrFieldBase::Get(index); } template -void RepeatedPtrField::GenericRemoveLast() { - RemoveLast(); +inline Element* RepeatedPtrField::Mutable(int index) { + return RepeatedPtrFieldBase::Mutable(index); } template -void RepeatedPtrField::GenericSwap(GenericRepeatedField *other) { - Swap(down_cast*>(other)); +inline Element* RepeatedPtrField::Add() { + return RepeatedPtrFieldBase::Add(); } template -void RepeatedPtrField::GenericSwapElements(int index1, int index2) { - SwapElements(index1, index2); +inline void RepeatedPtrField::RemoveLast() { + RepeatedPtrFieldBase::RemoveLast(); } template -int RepeatedPtrField::GenericSize() const { - return size(); +inline void RepeatedPtrField::Clear() { + RepeatedPtrFieldBase::Clear(); } template -int RepeatedPtrField::GenericSpaceUsedExcludingSelf() const { - return SpaceUsedExcludingSelf(); +inline void RepeatedPtrField::MergeFrom( + const RepeatedPtrField& other) { + RepeatedPtrFieldBase::MergeFrom(other); } +template +inline Element** RepeatedPtrField::mutable_data() { + return RepeatedPtrFieldBase::mutable_data(); +} template -inline void RepeatedPtrField::Reserve(int new_size) { - if (total_size_ >= new_size) return; +inline const Element* const* RepeatedPtrField::data() const { + return RepeatedPtrFieldBase::data(); +} - Element** old_elements = elements_; - total_size_ = max(total_size_ * 2, new_size); - elements_ = new Element*[total_size_]; - memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0])); - if (old_elements != initial_space_) { - delete [] old_elements; - } +template +void RepeatedPtrField::Swap(RepeatedPtrField* other) { + RepeatedPtrFieldBase::Swap(other); } template -inline Element* RepeatedPtrField::NewElement() { - return new Element; +void RepeatedPtrField::SwapElements(int index1, int index2) { + RepeatedPtrFieldBase::SwapElements(index1, index2); } -// RepeatedPtrField is allowed but requires a prototype since Message -// is abstract. -template <> -inline Message* RepeatedPtrField::NewElement() { - return prototype_->New(); +template +inline int RepeatedPtrField::SpaceUsedExcludingSelf() const { + return RepeatedPtrFieldBase::SpaceUsedExcludingSelf(); +} + +template +inline void RepeatedPtrField::AddAllocated(Element* value) { + RepeatedPtrFieldBase::AddAllocated(value); +} + +template +inline Element* RepeatedPtrField::ReleaseLast() { + return RepeatedPtrFieldBase::ReleaseLast(); +} + + +template +inline int RepeatedPtrField::ClearedCount() { + return RepeatedPtrFieldBase::ClearedCount(); +} + +template +inline void RepeatedPtrField::AddCleared(Element* value) { + return RepeatedPtrFieldBase::AddCleared(value); +} + +template +inline Element* RepeatedPtrField::ReleaseCleared() { + return RepeatedPtrFieldBase::ReleaseCleared(); +} + +template +inline void RepeatedPtrField::Reserve(int new_size) { + return RepeatedPtrFieldBase::Reserve(new_size); } // ------------------------------------------------------------------- @@ -805,26 +817,22 @@ namespace internal { // STL-like iterator implementation for RepeatedPtrField. You should not // refer to this class directly; use RepeatedPtrField::iterator instead. // -// The iterator for RepeatedPtrField, RepeatedPtrIterator, is -// very similar to iterator_ptr<> in util/gtl/iterator_adaptors-inl.h, -// but adds random-access operators and is slightly more specialized -// for using T** as its base type. I didn't re-use the other class to -// avoid an extra dependency. +// The iterator for RepeatedPtrField, RepeatedPtrIterator, is +// very similar to iterator_ptr in util/gtl/iterator_adaptors-inl.h, +// but adds random-access operators and is modified to wrap a void** base +// iterator (since RepeatedPtrField stores its array as a void* array and +// casting void** to T** would violate C++ aliasing rules). // -// This code stolen from net/proto/proto-array-internal.h by Jeffrey Yasskin +// This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin // (jyasskin@google.com). -template +template class RepeatedPtrIterator : public std::iterator< - std::random_access_iterator_tag, - typename internal::remove_pointer< - typename internal::remove_pointer::type>::type> { + std::random_access_iterator_tag, Element> { public: - typedef RepeatedPtrIterator iterator; + typedef RepeatedPtrIterator iterator; typedef std::iterator< - std::random_access_iterator_tag, - typename internal::remove_pointer< - typename internal::remove_pointer::type>::type> superclass; + std::random_access_iterator_tag, Element> superclass; // Let the compiler know that these are type names, so we don't have to // write "typename" in front of them everywhere. @@ -833,19 +841,21 @@ class RepeatedPtrIterator typedef typename superclass::difference_type difference_type; RepeatedPtrIterator() : it_(NULL) {} - explicit RepeatedPtrIterator(const It& it) : it_(it) {} + explicit RepeatedPtrIterator(void* const* it) : it_(it) {} // Allow "upcasting" from RepeatedPtrIterator to // RepeatedPtrIterator. - template - RepeatedPtrIterator(const RepeatedPtrIterator& other) - : it_(other.base()) {} - - // Provide access to the wrapped iterator. - const It& base() const { return it_; } + template + RepeatedPtrIterator(const RepeatedPtrIterator& other) + : it_(other.it_) { + // Force a compiler error if the other type is not convertable to ours. + if (false) { + implicit_cast(0); + } + } // dereferenceable - reference operator*() const { return **it_; } + reference operator*() const { return *reinterpret_cast(*it_); } pointer operator->() const { return &(operator*()); } // {inc,dec}rementable @@ -893,8 +903,11 @@ class RepeatedPtrIterator difference_type operator-(const iterator& x) const { return it_ - x.it_; } private: + template + friend class RepeatedPtrIterator; + // The internal iterator. - It it_; + void* const* it_; }; } // namespace internal @@ -902,22 +915,22 @@ class RepeatedPtrIterator template inline typename RepeatedPtrField::iterator RepeatedPtrField::begin() { - return iterator(elements_); + return iterator(raw_data()); } template inline typename RepeatedPtrField::const_iterator RepeatedPtrField::begin() const { - return iterator(elements_); + return iterator(raw_data()); } template inline typename RepeatedPtrField::iterator RepeatedPtrField::end() { - return iterator(elements_ + current_size_); + return iterator(raw_data() + size()); } template inline typename RepeatedPtrField::const_iterator RepeatedPtrField::end() const { - return iterator(elements_ + current_size_); + return iterator(raw_data() + size()); } // Iterators and helper functions that follow the spirit of the STL diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index ace1077d..069f33e2 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -181,6 +181,14 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); #define GOOGLE_ATTRIBUTE_ALWAYS_INLINE #endif +#undef GOOGLE_ATTRIBUTE_DEPRECATED +#ifdef __GNUC__ +// If the method/variable/type is used anywhere, produce a warning. +#define GOOGLE_ATTRIBUTE_DEPRECATED __attribute__((deprecated)) +#else +#define GOOGLE_ATTRIBUTE_DEPRECATED +#endif + // =================================================================== // from google3/base/basictypes.h @@ -642,24 +650,24 @@ class LIBPROTOBUF_EXPORT LogFinisher { #define GOOGLE_CHECK(EXPRESSION) \ GOOGLE_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": " -#define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK(A == B) -#define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK(A != B) -#define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK(A < B) -#define GOOGLE_CHECK_LE(A, B) GOOGLE_CHECK(A <= B) -#define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK(A > B) -#define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK(A >= B) +#define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK((A) == (B)) +#define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK((A) != (B)) +#define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK((A) < (B)) +#define GOOGLE_CHECK_LE(A, B) GOOGLE_CHECK((A) <= (B)) +#define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK((A) > (B)) +#define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK((A) >= (B)) #ifdef NDEBUG #define GOOGLE_DLOG GOOGLE_LOG_IF(false, INFO) #define GOOGLE_DCHECK(EXPRESSION) while(false) GOOGLE_CHECK(EXPRESSION) -#define GOOGLE_DCHECK_EQ(A, B) GOOGLE_DCHECK(A == B) -#define GOOGLE_DCHECK_NE(A, B) GOOGLE_DCHECK(A != B) -#define GOOGLE_DCHECK_LT(A, B) GOOGLE_DCHECK(A < B) -#define GOOGLE_DCHECK_LE(A, B) GOOGLE_DCHECK(A <= B) -#define GOOGLE_DCHECK_GT(A, B) GOOGLE_DCHECK(A > B) -#define GOOGLE_DCHECK_GE(A, B) GOOGLE_DCHECK(A >= B) +#define GOOGLE_DCHECK_EQ(A, B) GOOGLE_DCHECK((A) == (B)) +#define GOOGLE_DCHECK_NE(A, B) GOOGLE_DCHECK((A) != (B)) +#define GOOGLE_DCHECK_LT(A, B) GOOGLE_DCHECK((A) < (B)) +#define GOOGLE_DCHECK_LE(A, B) GOOGLE_DCHECK((A) <= (B)) +#define GOOGLE_DCHECK_GT(A, B) GOOGLE_DCHECK((A) > (B)) +#define GOOGLE_DCHECK_GE(A, B) GOOGLE_DCHECK((A) >= (B)) #else // NDEBUG diff --git a/src/google/protobuf/test_util.cc b/src/google/protobuf/test_util.cc index e3e67f67..0637c0a5 100644 --- a/src/google/protobuf/test_util.cc +++ b/src/google/protobuf/test_util.cc @@ -33,7 +33,7 @@ // Sanjay Ghemawat, Jeff Dean, and others. #ifdef _WIN32 -// Verify that #icnluding windows.h does not break anything (e.g. because +// Verify that #including windows.h does not break anything (e.g. because // windows.h #defines GetMessage() as a macro). #include #endif @@ -86,7 +86,7 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) { message, message->GetDescriptor()->FindFieldByName("optional_cord"), "125"); -#endif +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS // ----------------------------------------------------------------- @@ -124,7 +124,7 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) { message, message->GetDescriptor()->FindFieldByName("repeated_cord"), "225"); -#endif +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS // Add a second one of each field. message->add_repeated_int32 (301); @@ -161,7 +161,7 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) { message, message->GetDescriptor()->FindFieldByName("repeated_cord"), "325"); -#endif +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS // ----------------------------------------------------------------- @@ -194,7 +194,7 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) { message, message->GetDescriptor()->FindFieldByName("default_cord"), "425"); -#endif +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS } // ------------------------------------------------------------------- @@ -234,7 +234,7 @@ void TestUtil::ModifyRepeatedFields(unittest::TestAllTypes* message) { message, message->GetDescriptor()->FindFieldByName("repeated_cord"), 1, "425"); -#endif +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS } // ------------------------------------------------------------------- diff --git a/src/google/protobuf/test_util.h b/src/google/protobuf/test_util.h index e581f419..5a6ec88f 100644 --- a/src/google/protobuf/test_util.h +++ b/src/google/protobuf/test_util.h @@ -102,7 +102,8 @@ class TestUtil { static void ExpectLastRepeatedExtensionsRemoved( const unittest::TestAllExtensions& message); - // Check that all repeated fields have had their first and last elements swapped. + // Check that all repeated fields have had their first and last elements + // swapped. static void ExpectRepeatedsSwapped(const unittest::TestAllTypes& message); static void ExpectRepeatedExtensionsSwapped( const unittest::TestAllExtensions& message); diff --git a/src/google/protobuf/test_util_lite.cc b/src/google/protobuf/test_util_lite.cc new file mode 100644 index 00000000..d7140e0c --- /dev/null +++ b/src/google/protobuf/test_util_lite.cc @@ -0,0 +1,1502 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include + + +#define EXPECT_TRUE GOOGLE_CHECK +#define ASSERT_TRUE GOOGLE_CHECK +#define EXPECT_FALSE(COND) GOOGLE_CHECK(!(COND)) +#define EXPECT_EQ GOOGLE_CHECK_EQ +#define ASSERT_EQ GOOGLE_CHECK_EQ + +namespace google { +namespace protobuf { + +void TestUtilLite::SetAllFields(unittest::TestAllTypesLite* message) { + message->set_optional_int32 (101); + message->set_optional_int64 (102); + message->set_optional_uint32 (103); + message->set_optional_uint64 (104); + message->set_optional_sint32 (105); + message->set_optional_sint64 (106); + message->set_optional_fixed32 (107); + message->set_optional_fixed64 (108); + message->set_optional_sfixed32(109); + message->set_optional_sfixed64(110); + message->set_optional_float (111); + message->set_optional_double (112); + message->set_optional_bool (true); + message->set_optional_string ("115"); + message->set_optional_bytes ("116"); + + message->mutable_optionalgroup ()->set_a(117); + message->mutable_optional_nested_message ()->set_bb(118); + message->mutable_optional_foreign_message()->set_c(119); + message->mutable_optional_import_message ()->set_d(120); + + message->set_optional_nested_enum (unittest::TestAllTypesLite::BAZ ); + message->set_optional_foreign_enum(unittest::FOREIGN_LITE_BAZ ); + message->set_optional_import_enum (unittest_import::IMPORT_LITE_BAZ); + + + // ----------------------------------------------------------------- + + message->add_repeated_int32 (201); + message->add_repeated_int64 (202); + message->add_repeated_uint32 (203); + message->add_repeated_uint64 (204); + message->add_repeated_sint32 (205); + message->add_repeated_sint64 (206); + message->add_repeated_fixed32 (207); + message->add_repeated_fixed64 (208); + message->add_repeated_sfixed32(209); + message->add_repeated_sfixed64(210); + message->add_repeated_float (211); + message->add_repeated_double (212); + message->add_repeated_bool (true); + message->add_repeated_string ("215"); + message->add_repeated_bytes ("216"); + + message->add_repeatedgroup ()->set_a(217); + message->add_repeated_nested_message ()->set_bb(218); + message->add_repeated_foreign_message()->set_c(219); + message->add_repeated_import_message ()->set_d(220); + + message->add_repeated_nested_enum (unittest::TestAllTypesLite::BAR ); + message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAR ); + message->add_repeated_import_enum (unittest_import::IMPORT_LITE_BAR); + + + // Add a second one of each field. + message->add_repeated_int32 (301); + message->add_repeated_int64 (302); + message->add_repeated_uint32 (303); + message->add_repeated_uint64 (304); + message->add_repeated_sint32 (305); + message->add_repeated_sint64 (306); + message->add_repeated_fixed32 (307); + message->add_repeated_fixed64 (308); + message->add_repeated_sfixed32(309); + message->add_repeated_sfixed64(310); + message->add_repeated_float (311); + message->add_repeated_double (312); + message->add_repeated_bool (false); + message->add_repeated_string ("315"); + message->add_repeated_bytes ("316"); + + message->add_repeatedgroup ()->set_a(317); + message->add_repeated_nested_message ()->set_bb(318); + message->add_repeated_foreign_message()->set_c(319); + message->add_repeated_import_message ()->set_d(320); + + message->add_repeated_nested_enum (unittest::TestAllTypesLite::BAZ ); + message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAZ ); + message->add_repeated_import_enum (unittest_import::IMPORT_LITE_BAZ); + + + // ----------------------------------------------------------------- + + message->set_default_int32 (401); + message->set_default_int64 (402); + message->set_default_uint32 (403); + message->set_default_uint64 (404); + message->set_default_sint32 (405); + message->set_default_sint64 (406); + message->set_default_fixed32 (407); + message->set_default_fixed64 (408); + message->set_default_sfixed32(409); + message->set_default_sfixed64(410); + message->set_default_float (411); + message->set_default_double (412); + message->set_default_bool (false); + message->set_default_string ("415"); + message->set_default_bytes ("416"); + + message->set_default_nested_enum (unittest::TestAllTypesLite::FOO ); + message->set_default_foreign_enum(unittest::FOREIGN_LITE_FOO ); + message->set_default_import_enum (unittest_import::IMPORT_LITE_FOO); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ModifyRepeatedFields(unittest::TestAllTypesLite* message) { + message->set_repeated_int32 (1, 501); + message->set_repeated_int64 (1, 502); + message->set_repeated_uint32 (1, 503); + message->set_repeated_uint64 (1, 504); + message->set_repeated_sint32 (1, 505); + message->set_repeated_sint64 (1, 506); + message->set_repeated_fixed32 (1, 507); + message->set_repeated_fixed64 (1, 508); + message->set_repeated_sfixed32(1, 509); + message->set_repeated_sfixed64(1, 510); + message->set_repeated_float (1, 511); + message->set_repeated_double (1, 512); + message->set_repeated_bool (1, true); + message->set_repeated_string (1, "515"); + message->set_repeated_bytes (1, "516"); + + message->mutable_repeatedgroup (1)->set_a(517); + message->mutable_repeated_nested_message (1)->set_bb(518); + message->mutable_repeated_foreign_message(1)->set_c(519); + message->mutable_repeated_import_message (1)->set_d(520); + + message->set_repeated_nested_enum (1, unittest::TestAllTypesLite::FOO ); + message->set_repeated_foreign_enum(1, unittest::FOREIGN_LITE_FOO ); + message->set_repeated_import_enum (1, unittest_import::IMPORT_LITE_FOO); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectAllFieldsSet( + const unittest::TestAllTypesLite& message) { + EXPECT_TRUE(message.has_optional_int32 ()); + EXPECT_TRUE(message.has_optional_int64 ()); + EXPECT_TRUE(message.has_optional_uint32 ()); + EXPECT_TRUE(message.has_optional_uint64 ()); + EXPECT_TRUE(message.has_optional_sint32 ()); + EXPECT_TRUE(message.has_optional_sint64 ()); + EXPECT_TRUE(message.has_optional_fixed32 ()); + EXPECT_TRUE(message.has_optional_fixed64 ()); + EXPECT_TRUE(message.has_optional_sfixed32()); + EXPECT_TRUE(message.has_optional_sfixed64()); + EXPECT_TRUE(message.has_optional_float ()); + EXPECT_TRUE(message.has_optional_double ()); + EXPECT_TRUE(message.has_optional_bool ()); + EXPECT_TRUE(message.has_optional_string ()); + EXPECT_TRUE(message.has_optional_bytes ()); + + EXPECT_TRUE(message.has_optionalgroup ()); + EXPECT_TRUE(message.has_optional_nested_message ()); + EXPECT_TRUE(message.has_optional_foreign_message()); + EXPECT_TRUE(message.has_optional_import_message ()); + + EXPECT_TRUE(message.optionalgroup ().has_a()); + EXPECT_TRUE(message.optional_nested_message ().has_bb()); + EXPECT_TRUE(message.optional_foreign_message().has_c()); + EXPECT_TRUE(message.optional_import_message ().has_d()); + + EXPECT_TRUE(message.has_optional_nested_enum ()); + EXPECT_TRUE(message.has_optional_foreign_enum()); + EXPECT_TRUE(message.has_optional_import_enum ()); + + + EXPECT_EQ(101 , message.optional_int32 ()); + EXPECT_EQ(102 , message.optional_int64 ()); + EXPECT_EQ(103 , message.optional_uint32 ()); + EXPECT_EQ(104 , message.optional_uint64 ()); + EXPECT_EQ(105 , message.optional_sint32 ()); + EXPECT_EQ(106 , message.optional_sint64 ()); + EXPECT_EQ(107 , message.optional_fixed32 ()); + EXPECT_EQ(108 , message.optional_fixed64 ()); + EXPECT_EQ(109 , message.optional_sfixed32()); + EXPECT_EQ(110 , message.optional_sfixed64()); + EXPECT_EQ(111 , message.optional_float ()); + EXPECT_EQ(112 , message.optional_double ()); + EXPECT_EQ(true , message.optional_bool ()); + EXPECT_EQ("115", message.optional_string ()); + EXPECT_EQ("116", message.optional_bytes ()); + + EXPECT_EQ(117, message.optionalgroup ().a()); + EXPECT_EQ(118, message.optional_nested_message ().bb()); + EXPECT_EQ(119, message.optional_foreign_message().c()); + EXPECT_EQ(120, message.optional_import_message ().d()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.optional_nested_enum ()); + EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.optional_foreign_enum()); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.optional_import_enum ()); + + + // ----------------------------------------------------------------- + + ASSERT_EQ(2, message.repeated_int32_size ()); + ASSERT_EQ(2, message.repeated_int64_size ()); + ASSERT_EQ(2, message.repeated_uint32_size ()); + ASSERT_EQ(2, message.repeated_uint64_size ()); + ASSERT_EQ(2, message.repeated_sint32_size ()); + ASSERT_EQ(2, message.repeated_sint64_size ()); + ASSERT_EQ(2, message.repeated_fixed32_size ()); + ASSERT_EQ(2, message.repeated_fixed64_size ()); + ASSERT_EQ(2, message.repeated_sfixed32_size()); + ASSERT_EQ(2, message.repeated_sfixed64_size()); + ASSERT_EQ(2, message.repeated_float_size ()); + ASSERT_EQ(2, message.repeated_double_size ()); + ASSERT_EQ(2, message.repeated_bool_size ()); + ASSERT_EQ(2, message.repeated_string_size ()); + ASSERT_EQ(2, message.repeated_bytes_size ()); + + ASSERT_EQ(2, message.repeatedgroup_size ()); + ASSERT_EQ(2, message.repeated_nested_message_size ()); + ASSERT_EQ(2, message.repeated_foreign_message_size()); + ASSERT_EQ(2, message.repeated_import_message_size ()); + ASSERT_EQ(2, message.repeated_nested_enum_size ()); + ASSERT_EQ(2, message.repeated_foreign_enum_size ()); + ASSERT_EQ(2, message.repeated_import_enum_size ()); + + + EXPECT_EQ(201 , message.repeated_int32 (0)); + EXPECT_EQ(202 , message.repeated_int64 (0)); + EXPECT_EQ(203 , message.repeated_uint32 (0)); + EXPECT_EQ(204 , message.repeated_uint64 (0)); + EXPECT_EQ(205 , message.repeated_sint32 (0)); + EXPECT_EQ(206 , message.repeated_sint64 (0)); + EXPECT_EQ(207 , message.repeated_fixed32 (0)); + EXPECT_EQ(208 , message.repeated_fixed64 (0)); + EXPECT_EQ(209 , message.repeated_sfixed32(0)); + EXPECT_EQ(210 , message.repeated_sfixed64(0)); + EXPECT_EQ(211 , message.repeated_float (0)); + EXPECT_EQ(212 , message.repeated_double (0)); + EXPECT_EQ(true , message.repeated_bool (0)); + EXPECT_EQ("215", message.repeated_string (0)); + EXPECT_EQ("216", message.repeated_bytes (0)); + + EXPECT_EQ(217, message.repeatedgroup (0).a()); + EXPECT_EQ(218, message.repeated_nested_message (0).bb()); + EXPECT_EQ(219, message.repeated_foreign_message(0).c()); + EXPECT_EQ(220, message.repeated_import_message (0).d()); + + + EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.repeated_nested_enum (0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.repeated_foreign_enum(0)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.repeated_import_enum (0)); + + EXPECT_EQ(301 , message.repeated_int32 (1)); + EXPECT_EQ(302 , message.repeated_int64 (1)); + EXPECT_EQ(303 , message.repeated_uint32 (1)); + EXPECT_EQ(304 , message.repeated_uint64 (1)); + EXPECT_EQ(305 , message.repeated_sint32 (1)); + EXPECT_EQ(306 , message.repeated_sint64 (1)); + EXPECT_EQ(307 , message.repeated_fixed32 (1)); + EXPECT_EQ(308 , message.repeated_fixed64 (1)); + EXPECT_EQ(309 , message.repeated_sfixed32(1)); + EXPECT_EQ(310 , message.repeated_sfixed64(1)); + EXPECT_EQ(311 , message.repeated_float (1)); + EXPECT_EQ(312 , message.repeated_double (1)); + EXPECT_EQ(false, message.repeated_bool (1)); + EXPECT_EQ("315", message.repeated_string (1)); + EXPECT_EQ("316", message.repeated_bytes (1)); + + EXPECT_EQ(317, message.repeatedgroup (1).a()); + EXPECT_EQ(318, message.repeated_nested_message (1).bb()); + EXPECT_EQ(319, message.repeated_foreign_message(1).c()); + EXPECT_EQ(320, message.repeated_import_message (1).d()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.repeated_nested_enum (1)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.repeated_foreign_enum(1)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.repeated_import_enum (1)); + + + // ----------------------------------------------------------------- + + EXPECT_TRUE(message.has_default_int32 ()); + EXPECT_TRUE(message.has_default_int64 ()); + EXPECT_TRUE(message.has_default_uint32 ()); + EXPECT_TRUE(message.has_default_uint64 ()); + EXPECT_TRUE(message.has_default_sint32 ()); + EXPECT_TRUE(message.has_default_sint64 ()); + EXPECT_TRUE(message.has_default_fixed32 ()); + EXPECT_TRUE(message.has_default_fixed64 ()); + EXPECT_TRUE(message.has_default_sfixed32()); + EXPECT_TRUE(message.has_default_sfixed64()); + EXPECT_TRUE(message.has_default_float ()); + EXPECT_TRUE(message.has_default_double ()); + EXPECT_TRUE(message.has_default_bool ()); + EXPECT_TRUE(message.has_default_string ()); + EXPECT_TRUE(message.has_default_bytes ()); + + EXPECT_TRUE(message.has_default_nested_enum ()); + EXPECT_TRUE(message.has_default_foreign_enum()); + EXPECT_TRUE(message.has_default_import_enum ()); + + + EXPECT_EQ(401 , message.default_int32 ()); + EXPECT_EQ(402 , message.default_int64 ()); + EXPECT_EQ(403 , message.default_uint32 ()); + EXPECT_EQ(404 , message.default_uint64 ()); + EXPECT_EQ(405 , message.default_sint32 ()); + EXPECT_EQ(406 , message.default_sint64 ()); + EXPECT_EQ(407 , message.default_fixed32 ()); + EXPECT_EQ(408 , message.default_fixed64 ()); + EXPECT_EQ(409 , message.default_sfixed32()); + EXPECT_EQ(410 , message.default_sfixed64()); + EXPECT_EQ(411 , message.default_float ()); + EXPECT_EQ(412 , message.default_double ()); + EXPECT_EQ(false, message.default_bool ()); + EXPECT_EQ("415", message.default_string ()); + EXPECT_EQ("416", message.default_bytes ()); + + EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.default_nested_enum ()); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.default_foreign_enum()); + EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.default_import_enum ()); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectClear(const unittest::TestAllTypesLite& message) { + // has_blah() should initially be false for all optional fields. + EXPECT_FALSE(message.has_optional_int32 ()); + EXPECT_FALSE(message.has_optional_int64 ()); + EXPECT_FALSE(message.has_optional_uint32 ()); + EXPECT_FALSE(message.has_optional_uint64 ()); + EXPECT_FALSE(message.has_optional_sint32 ()); + EXPECT_FALSE(message.has_optional_sint64 ()); + EXPECT_FALSE(message.has_optional_fixed32 ()); + EXPECT_FALSE(message.has_optional_fixed64 ()); + EXPECT_FALSE(message.has_optional_sfixed32()); + EXPECT_FALSE(message.has_optional_sfixed64()); + EXPECT_FALSE(message.has_optional_float ()); + EXPECT_FALSE(message.has_optional_double ()); + EXPECT_FALSE(message.has_optional_bool ()); + EXPECT_FALSE(message.has_optional_string ()); + EXPECT_FALSE(message.has_optional_bytes ()); + + EXPECT_FALSE(message.has_optionalgroup ()); + EXPECT_FALSE(message.has_optional_nested_message ()); + EXPECT_FALSE(message.has_optional_foreign_message()); + EXPECT_FALSE(message.has_optional_import_message ()); + + EXPECT_FALSE(message.has_optional_nested_enum ()); + EXPECT_FALSE(message.has_optional_foreign_enum()); + EXPECT_FALSE(message.has_optional_import_enum ()); + + + // Optional fields without defaults are set to zero or something like it. + EXPECT_EQ(0 , message.optional_int32 ()); + EXPECT_EQ(0 , message.optional_int64 ()); + EXPECT_EQ(0 , message.optional_uint32 ()); + EXPECT_EQ(0 , message.optional_uint64 ()); + EXPECT_EQ(0 , message.optional_sint32 ()); + EXPECT_EQ(0 , message.optional_sint64 ()); + EXPECT_EQ(0 , message.optional_fixed32 ()); + EXPECT_EQ(0 , message.optional_fixed64 ()); + EXPECT_EQ(0 , message.optional_sfixed32()); + EXPECT_EQ(0 , message.optional_sfixed64()); + EXPECT_EQ(0 , message.optional_float ()); + EXPECT_EQ(0 , message.optional_double ()); + EXPECT_EQ(false, message.optional_bool ()); + EXPECT_EQ("" , message.optional_string ()); + EXPECT_EQ("" , message.optional_bytes ()); + + // Embedded messages should also be clear. + EXPECT_FALSE(message.optionalgroup ().has_a()); + EXPECT_FALSE(message.optional_nested_message ().has_bb()); + EXPECT_FALSE(message.optional_foreign_message().has_c()); + EXPECT_FALSE(message.optional_import_message ().has_d()); + + EXPECT_EQ(0, message.optionalgroup ().a()); + EXPECT_EQ(0, message.optional_nested_message ().bb()); + EXPECT_EQ(0, message.optional_foreign_message().c()); + EXPECT_EQ(0, message.optional_import_message ().d()); + + // Enums without defaults are set to the first value in the enum. + EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.optional_nested_enum ()); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.optional_foreign_enum()); + EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.optional_import_enum ()); + + + // Repeated fields are empty. + EXPECT_EQ(0, message.repeated_int32_size ()); + EXPECT_EQ(0, message.repeated_int64_size ()); + EXPECT_EQ(0, message.repeated_uint32_size ()); + EXPECT_EQ(0, message.repeated_uint64_size ()); + EXPECT_EQ(0, message.repeated_sint32_size ()); + EXPECT_EQ(0, message.repeated_sint64_size ()); + EXPECT_EQ(0, message.repeated_fixed32_size ()); + EXPECT_EQ(0, message.repeated_fixed64_size ()); + EXPECT_EQ(0, message.repeated_sfixed32_size()); + EXPECT_EQ(0, message.repeated_sfixed64_size()); + EXPECT_EQ(0, message.repeated_float_size ()); + EXPECT_EQ(0, message.repeated_double_size ()); + EXPECT_EQ(0, message.repeated_bool_size ()); + EXPECT_EQ(0, message.repeated_string_size ()); + EXPECT_EQ(0, message.repeated_bytes_size ()); + + EXPECT_EQ(0, message.repeatedgroup_size ()); + EXPECT_EQ(0, message.repeated_nested_message_size ()); + EXPECT_EQ(0, message.repeated_foreign_message_size()); + EXPECT_EQ(0, message.repeated_import_message_size ()); + EXPECT_EQ(0, message.repeated_nested_enum_size ()); + EXPECT_EQ(0, message.repeated_foreign_enum_size ()); + EXPECT_EQ(0, message.repeated_import_enum_size ()); + + + // has_blah() should also be false for all default fields. + EXPECT_FALSE(message.has_default_int32 ()); + EXPECT_FALSE(message.has_default_int64 ()); + EXPECT_FALSE(message.has_default_uint32 ()); + EXPECT_FALSE(message.has_default_uint64 ()); + EXPECT_FALSE(message.has_default_sint32 ()); + EXPECT_FALSE(message.has_default_sint64 ()); + EXPECT_FALSE(message.has_default_fixed32 ()); + EXPECT_FALSE(message.has_default_fixed64 ()); + EXPECT_FALSE(message.has_default_sfixed32()); + EXPECT_FALSE(message.has_default_sfixed64()); + EXPECT_FALSE(message.has_default_float ()); + EXPECT_FALSE(message.has_default_double ()); + EXPECT_FALSE(message.has_default_bool ()); + EXPECT_FALSE(message.has_default_string ()); + EXPECT_FALSE(message.has_default_bytes ()); + + EXPECT_FALSE(message.has_default_nested_enum ()); + EXPECT_FALSE(message.has_default_foreign_enum()); + EXPECT_FALSE(message.has_default_import_enum ()); + + + // Fields with defaults have their default values (duh). + EXPECT_EQ( 41 , message.default_int32 ()); + EXPECT_EQ( 42 , message.default_int64 ()); + EXPECT_EQ( 43 , message.default_uint32 ()); + EXPECT_EQ( 44 , message.default_uint64 ()); + EXPECT_EQ(-45 , message.default_sint32 ()); + EXPECT_EQ( 46 , message.default_sint64 ()); + EXPECT_EQ( 47 , message.default_fixed32 ()); + EXPECT_EQ( 48 , message.default_fixed64 ()); + EXPECT_EQ( 49 , message.default_sfixed32()); + EXPECT_EQ(-50 , message.default_sfixed64()); + EXPECT_EQ( 51.5 , message.default_float ()); + EXPECT_EQ( 52e3 , message.default_double ()); + EXPECT_EQ(true , message.default_bool ()); + EXPECT_EQ("hello", message.default_string ()); + EXPECT_EQ("world", message.default_bytes ()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.default_nested_enum ()); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.default_foreign_enum()); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.default_import_enum ()); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectRepeatedFieldsModified( + const unittest::TestAllTypesLite& message) { + // ModifyRepeatedFields only sets the second repeated element of each + // field. In addition to verifying this, we also verify that the first + // element and size were *not* modified. + ASSERT_EQ(2, message.repeated_int32_size ()); + ASSERT_EQ(2, message.repeated_int64_size ()); + ASSERT_EQ(2, message.repeated_uint32_size ()); + ASSERT_EQ(2, message.repeated_uint64_size ()); + ASSERT_EQ(2, message.repeated_sint32_size ()); + ASSERT_EQ(2, message.repeated_sint64_size ()); + ASSERT_EQ(2, message.repeated_fixed32_size ()); + ASSERT_EQ(2, message.repeated_fixed64_size ()); + ASSERT_EQ(2, message.repeated_sfixed32_size()); + ASSERT_EQ(2, message.repeated_sfixed64_size()); + ASSERT_EQ(2, message.repeated_float_size ()); + ASSERT_EQ(2, message.repeated_double_size ()); + ASSERT_EQ(2, message.repeated_bool_size ()); + ASSERT_EQ(2, message.repeated_string_size ()); + ASSERT_EQ(2, message.repeated_bytes_size ()); + + ASSERT_EQ(2, message.repeatedgroup_size ()); + ASSERT_EQ(2, message.repeated_nested_message_size ()); + ASSERT_EQ(2, message.repeated_foreign_message_size()); + ASSERT_EQ(2, message.repeated_import_message_size ()); + ASSERT_EQ(2, message.repeated_nested_enum_size ()); + ASSERT_EQ(2, message.repeated_foreign_enum_size ()); + ASSERT_EQ(2, message.repeated_import_enum_size ()); + + + EXPECT_EQ(201 , message.repeated_int32 (0)); + EXPECT_EQ(202 , message.repeated_int64 (0)); + EXPECT_EQ(203 , message.repeated_uint32 (0)); + EXPECT_EQ(204 , message.repeated_uint64 (0)); + EXPECT_EQ(205 , message.repeated_sint32 (0)); + EXPECT_EQ(206 , message.repeated_sint64 (0)); + EXPECT_EQ(207 , message.repeated_fixed32 (0)); + EXPECT_EQ(208 , message.repeated_fixed64 (0)); + EXPECT_EQ(209 , message.repeated_sfixed32(0)); + EXPECT_EQ(210 , message.repeated_sfixed64(0)); + EXPECT_EQ(211 , message.repeated_float (0)); + EXPECT_EQ(212 , message.repeated_double (0)); + EXPECT_EQ(true , message.repeated_bool (0)); + EXPECT_EQ("215", message.repeated_string (0)); + EXPECT_EQ("216", message.repeated_bytes (0)); + + EXPECT_EQ(217, message.repeatedgroup (0).a()); + EXPECT_EQ(218, message.repeated_nested_message (0).bb()); + EXPECT_EQ(219, message.repeated_foreign_message(0).c()); + EXPECT_EQ(220, message.repeated_import_message (0).d()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.repeated_nested_enum (0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.repeated_foreign_enum(0)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.repeated_import_enum (0)); + + + // Actually verify the second (modified) elements now. + EXPECT_EQ(501 , message.repeated_int32 (1)); + EXPECT_EQ(502 , message.repeated_int64 (1)); + EXPECT_EQ(503 , message.repeated_uint32 (1)); + EXPECT_EQ(504 , message.repeated_uint64 (1)); + EXPECT_EQ(505 , message.repeated_sint32 (1)); + EXPECT_EQ(506 , message.repeated_sint64 (1)); + EXPECT_EQ(507 , message.repeated_fixed32 (1)); + EXPECT_EQ(508 , message.repeated_fixed64 (1)); + EXPECT_EQ(509 , message.repeated_sfixed32(1)); + EXPECT_EQ(510 , message.repeated_sfixed64(1)); + EXPECT_EQ(511 , message.repeated_float (1)); + EXPECT_EQ(512 , message.repeated_double (1)); + EXPECT_EQ(true , message.repeated_bool (1)); + EXPECT_EQ("515", message.repeated_string (1)); + EXPECT_EQ("516", message.repeated_bytes (1)); + + EXPECT_EQ(517, message.repeatedgroup (1).a()); + EXPECT_EQ(518, message.repeated_nested_message (1).bb()); + EXPECT_EQ(519, message.repeated_foreign_message(1).c()); + EXPECT_EQ(520, message.repeated_import_message (1).d()); + + EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.repeated_nested_enum (1)); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.repeated_foreign_enum(1)); + EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.repeated_import_enum (1)); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::SetPackedFields(unittest::TestPackedTypesLite* message) { + message->add_packed_int32 (601); + message->add_packed_int64 (602); + message->add_packed_uint32 (603); + message->add_packed_uint64 (604); + message->add_packed_sint32 (605); + message->add_packed_sint64 (606); + message->add_packed_fixed32 (607); + message->add_packed_fixed64 (608); + message->add_packed_sfixed32(609); + message->add_packed_sfixed64(610); + message->add_packed_float (611); + message->add_packed_double (612); + message->add_packed_bool (true); + message->add_packed_enum (unittest::FOREIGN_LITE_BAR); + // add a second one of each field + message->add_packed_int32 (701); + message->add_packed_int64 (702); + message->add_packed_uint32 (703); + message->add_packed_uint64 (704); + message->add_packed_sint32 (705); + message->add_packed_sint64 (706); + message->add_packed_fixed32 (707); + message->add_packed_fixed64 (708); + message->add_packed_sfixed32(709); + message->add_packed_sfixed64(710); + message->add_packed_float (711); + message->add_packed_double (712); + message->add_packed_bool (false); + message->add_packed_enum (unittest::FOREIGN_LITE_BAZ); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ModifyPackedFields(unittest::TestPackedTypesLite* message) { + message->set_packed_int32 (1, 801); + message->set_packed_int64 (1, 802); + message->set_packed_uint32 (1, 803); + message->set_packed_uint64 (1, 804); + message->set_packed_sint32 (1, 805); + message->set_packed_sint64 (1, 806); + message->set_packed_fixed32 (1, 807); + message->set_packed_fixed64 (1, 808); + message->set_packed_sfixed32(1, 809); + message->set_packed_sfixed64(1, 810); + message->set_packed_float (1, 811); + message->set_packed_double (1, 812); + message->set_packed_bool (1, true); + message->set_packed_enum (1, unittest::FOREIGN_LITE_FOO); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectPackedFieldsSet( + const unittest::TestPackedTypesLite& message) { + ASSERT_EQ(2, message.packed_int32_size ()); + ASSERT_EQ(2, message.packed_int64_size ()); + ASSERT_EQ(2, message.packed_uint32_size ()); + ASSERT_EQ(2, message.packed_uint64_size ()); + ASSERT_EQ(2, message.packed_sint32_size ()); + ASSERT_EQ(2, message.packed_sint64_size ()); + ASSERT_EQ(2, message.packed_fixed32_size ()); + ASSERT_EQ(2, message.packed_fixed64_size ()); + ASSERT_EQ(2, message.packed_sfixed32_size()); + ASSERT_EQ(2, message.packed_sfixed64_size()); + ASSERT_EQ(2, message.packed_float_size ()); + ASSERT_EQ(2, message.packed_double_size ()); + ASSERT_EQ(2, message.packed_bool_size ()); + ASSERT_EQ(2, message.packed_enum_size ()); + + EXPECT_EQ(601 , message.packed_int32 (0)); + EXPECT_EQ(602 , message.packed_int64 (0)); + EXPECT_EQ(603 , message.packed_uint32 (0)); + EXPECT_EQ(604 , message.packed_uint64 (0)); + EXPECT_EQ(605 , message.packed_sint32 (0)); + EXPECT_EQ(606 , message.packed_sint64 (0)); + EXPECT_EQ(607 , message.packed_fixed32 (0)); + EXPECT_EQ(608 , message.packed_fixed64 (0)); + EXPECT_EQ(609 , message.packed_sfixed32(0)); + EXPECT_EQ(610 , message.packed_sfixed64(0)); + EXPECT_EQ(611 , message.packed_float (0)); + EXPECT_EQ(612 , message.packed_double (0)); + EXPECT_EQ(true , message.packed_bool (0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.packed_enum(0)); + + EXPECT_EQ(701 , message.packed_int32 (1)); + EXPECT_EQ(702 , message.packed_int64 (1)); + EXPECT_EQ(703 , message.packed_uint32 (1)); + EXPECT_EQ(704 , message.packed_uint64 (1)); + EXPECT_EQ(705 , message.packed_sint32 (1)); + EXPECT_EQ(706 , message.packed_sint64 (1)); + EXPECT_EQ(707 , message.packed_fixed32 (1)); + EXPECT_EQ(708 , message.packed_fixed64 (1)); + EXPECT_EQ(709 , message.packed_sfixed32(1)); + EXPECT_EQ(710 , message.packed_sfixed64(1)); + EXPECT_EQ(711 , message.packed_float (1)); + EXPECT_EQ(712 , message.packed_double (1)); + EXPECT_EQ(false, message.packed_bool (1)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAZ, message.packed_enum(1)); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectPackedClear( + const unittest::TestPackedTypesLite& message) { + // Packed repeated fields are empty. + EXPECT_EQ(0, message.packed_int32_size ()); + EXPECT_EQ(0, message.packed_int64_size ()); + EXPECT_EQ(0, message.packed_uint32_size ()); + EXPECT_EQ(0, message.packed_uint64_size ()); + EXPECT_EQ(0, message.packed_sint32_size ()); + EXPECT_EQ(0, message.packed_sint64_size ()); + EXPECT_EQ(0, message.packed_fixed32_size ()); + EXPECT_EQ(0, message.packed_fixed64_size ()); + EXPECT_EQ(0, message.packed_sfixed32_size()); + EXPECT_EQ(0, message.packed_sfixed64_size()); + EXPECT_EQ(0, message.packed_float_size ()); + EXPECT_EQ(0, message.packed_double_size ()); + EXPECT_EQ(0, message.packed_bool_size ()); + EXPECT_EQ(0, message.packed_enum_size ()); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectPackedFieldsModified( + const unittest::TestPackedTypesLite& message) { + // Do the same for packed repeated fields. + ASSERT_EQ(2, message.packed_int32_size ()); + ASSERT_EQ(2, message.packed_int64_size ()); + ASSERT_EQ(2, message.packed_uint32_size ()); + ASSERT_EQ(2, message.packed_uint64_size ()); + ASSERT_EQ(2, message.packed_sint32_size ()); + ASSERT_EQ(2, message.packed_sint64_size ()); + ASSERT_EQ(2, message.packed_fixed32_size ()); + ASSERT_EQ(2, message.packed_fixed64_size ()); + ASSERT_EQ(2, message.packed_sfixed32_size()); + ASSERT_EQ(2, message.packed_sfixed64_size()); + ASSERT_EQ(2, message.packed_float_size ()); + ASSERT_EQ(2, message.packed_double_size ()); + ASSERT_EQ(2, message.packed_bool_size ()); + ASSERT_EQ(2, message.packed_enum_size ()); + + EXPECT_EQ(601 , message.packed_int32 (0)); + EXPECT_EQ(602 , message.packed_int64 (0)); + EXPECT_EQ(603 , message.packed_uint32 (0)); + EXPECT_EQ(604 , message.packed_uint64 (0)); + EXPECT_EQ(605 , message.packed_sint32 (0)); + EXPECT_EQ(606 , message.packed_sint64 (0)); + EXPECT_EQ(607 , message.packed_fixed32 (0)); + EXPECT_EQ(608 , message.packed_fixed64 (0)); + EXPECT_EQ(609 , message.packed_sfixed32(0)); + EXPECT_EQ(610 , message.packed_sfixed64(0)); + EXPECT_EQ(611 , message.packed_float (0)); + EXPECT_EQ(612 , message.packed_double (0)); + EXPECT_EQ(true , message.packed_bool (0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.packed_enum(0)); + // Actually verify the second (modified) elements now. + EXPECT_EQ(801 , message.packed_int32 (1)); + EXPECT_EQ(802 , message.packed_int64 (1)); + EXPECT_EQ(803 , message.packed_uint32 (1)); + EXPECT_EQ(804 , message.packed_uint64 (1)); + EXPECT_EQ(805 , message.packed_sint32 (1)); + EXPECT_EQ(806 , message.packed_sint64 (1)); + EXPECT_EQ(807 , message.packed_fixed32 (1)); + EXPECT_EQ(808 , message.packed_fixed64 (1)); + EXPECT_EQ(809 , message.packed_sfixed32(1)); + EXPECT_EQ(810 , message.packed_sfixed64(1)); + EXPECT_EQ(811 , message.packed_float (1)); + EXPECT_EQ(812 , message.packed_double (1)); + EXPECT_EQ(true , message.packed_bool (1)); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO, message.packed_enum(1)); +} + +// =================================================================== +// Extensions +// +// All this code is exactly equivalent to the above code except that it's +// manipulating extension fields instead of normal ones. +// +// I gave up on the 80-char limit here. Sorry. + +void TestUtilLite::SetAllExtensions(unittest::TestAllExtensionsLite* message) { + message->SetExtension(unittest::optional_int32_extension_lite , 101); + message->SetExtension(unittest::optional_int64_extension_lite , 102); + message->SetExtension(unittest::optional_uint32_extension_lite , 103); + message->SetExtension(unittest::optional_uint64_extension_lite , 104); + message->SetExtension(unittest::optional_sint32_extension_lite , 105); + message->SetExtension(unittest::optional_sint64_extension_lite , 106); + message->SetExtension(unittest::optional_fixed32_extension_lite , 107); + message->SetExtension(unittest::optional_fixed64_extension_lite , 108); + message->SetExtension(unittest::optional_sfixed32_extension_lite, 109); + message->SetExtension(unittest::optional_sfixed64_extension_lite, 110); + message->SetExtension(unittest::optional_float_extension_lite , 111); + message->SetExtension(unittest::optional_double_extension_lite , 112); + message->SetExtension(unittest::optional_bool_extension_lite , true); + message->SetExtension(unittest::optional_string_extension_lite , "115"); + message->SetExtension(unittest::optional_bytes_extension_lite , "116"); + + message->MutableExtension(unittest::optionalgroup_extension_lite )->set_a(117); + message->MutableExtension(unittest::optional_nested_message_extension_lite )->set_bb(118); + message->MutableExtension(unittest::optional_foreign_message_extension_lite)->set_c(119); + message->MutableExtension(unittest::optional_import_message_extension_lite )->set_d(120); + + message->SetExtension(unittest::optional_nested_enum_extension_lite , unittest::TestAllTypesLite::BAZ ); + message->SetExtension(unittest::optional_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAZ ); + message->SetExtension(unittest::optional_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAZ); + + + // ----------------------------------------------------------------- + + message->AddExtension(unittest::repeated_int32_extension_lite , 201); + message->AddExtension(unittest::repeated_int64_extension_lite , 202); + message->AddExtension(unittest::repeated_uint32_extension_lite , 203); + message->AddExtension(unittest::repeated_uint64_extension_lite , 204); + message->AddExtension(unittest::repeated_sint32_extension_lite , 205); + message->AddExtension(unittest::repeated_sint64_extension_lite , 206); + message->AddExtension(unittest::repeated_fixed32_extension_lite , 207); + message->AddExtension(unittest::repeated_fixed64_extension_lite , 208); + message->AddExtension(unittest::repeated_sfixed32_extension_lite, 209); + message->AddExtension(unittest::repeated_sfixed64_extension_lite, 210); + message->AddExtension(unittest::repeated_float_extension_lite , 211); + message->AddExtension(unittest::repeated_double_extension_lite , 212); + message->AddExtension(unittest::repeated_bool_extension_lite , true); + message->AddExtension(unittest::repeated_string_extension_lite , "215"); + message->AddExtension(unittest::repeated_bytes_extension_lite , "216"); + + message->AddExtension(unittest::repeatedgroup_extension_lite )->set_a(217); + message->AddExtension(unittest::repeated_nested_message_extension_lite )->set_bb(218); + message->AddExtension(unittest::repeated_foreign_message_extension_lite)->set_c(219); + message->AddExtension(unittest::repeated_import_message_extension_lite )->set_d(220); + + message->AddExtension(unittest::repeated_nested_enum_extension_lite , unittest::TestAllTypesLite::BAR ); + message->AddExtension(unittest::repeated_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAR ); + message->AddExtension(unittest::repeated_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAR); + + + // Add a second one of each field. + message->AddExtension(unittest::repeated_int32_extension_lite , 301); + message->AddExtension(unittest::repeated_int64_extension_lite , 302); + message->AddExtension(unittest::repeated_uint32_extension_lite , 303); + message->AddExtension(unittest::repeated_uint64_extension_lite , 304); + message->AddExtension(unittest::repeated_sint32_extension_lite , 305); + message->AddExtension(unittest::repeated_sint64_extension_lite , 306); + message->AddExtension(unittest::repeated_fixed32_extension_lite , 307); + message->AddExtension(unittest::repeated_fixed64_extension_lite , 308); + message->AddExtension(unittest::repeated_sfixed32_extension_lite, 309); + message->AddExtension(unittest::repeated_sfixed64_extension_lite, 310); + message->AddExtension(unittest::repeated_float_extension_lite , 311); + message->AddExtension(unittest::repeated_double_extension_lite , 312); + message->AddExtension(unittest::repeated_bool_extension_lite , false); + message->AddExtension(unittest::repeated_string_extension_lite , "315"); + message->AddExtension(unittest::repeated_bytes_extension_lite , "316"); + + message->AddExtension(unittest::repeatedgroup_extension_lite )->set_a(317); + message->AddExtension(unittest::repeated_nested_message_extension_lite )->set_bb(318); + message->AddExtension(unittest::repeated_foreign_message_extension_lite)->set_c(319); + message->AddExtension(unittest::repeated_import_message_extension_lite )->set_d(320); + + message->AddExtension(unittest::repeated_nested_enum_extension_lite , unittest::TestAllTypesLite::BAZ ); + message->AddExtension(unittest::repeated_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAZ ); + message->AddExtension(unittest::repeated_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAZ); + + + // ----------------------------------------------------------------- + + message->SetExtension(unittest::default_int32_extension_lite , 401); + message->SetExtension(unittest::default_int64_extension_lite , 402); + message->SetExtension(unittest::default_uint32_extension_lite , 403); + message->SetExtension(unittest::default_uint64_extension_lite , 404); + message->SetExtension(unittest::default_sint32_extension_lite , 405); + message->SetExtension(unittest::default_sint64_extension_lite , 406); + message->SetExtension(unittest::default_fixed32_extension_lite , 407); + message->SetExtension(unittest::default_fixed64_extension_lite , 408); + message->SetExtension(unittest::default_sfixed32_extension_lite, 409); + message->SetExtension(unittest::default_sfixed64_extension_lite, 410); + message->SetExtension(unittest::default_float_extension_lite , 411); + message->SetExtension(unittest::default_double_extension_lite , 412); + message->SetExtension(unittest::default_bool_extension_lite , false); + message->SetExtension(unittest::default_string_extension_lite , "415"); + message->SetExtension(unittest::default_bytes_extension_lite , "416"); + + message->SetExtension(unittest::default_nested_enum_extension_lite , unittest::TestAllTypesLite::FOO ); + message->SetExtension(unittest::default_foreign_enum_extension_lite, unittest::FOREIGN_LITE_FOO ); + message->SetExtension(unittest::default_import_enum_extension_lite , unittest_import::IMPORT_LITE_FOO); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ModifyRepeatedExtensions( + unittest::TestAllExtensionsLite* message) { + message->SetExtension(unittest::repeated_int32_extension_lite , 1, 501); + message->SetExtension(unittest::repeated_int64_extension_lite , 1, 502); + message->SetExtension(unittest::repeated_uint32_extension_lite , 1, 503); + message->SetExtension(unittest::repeated_uint64_extension_lite , 1, 504); + message->SetExtension(unittest::repeated_sint32_extension_lite , 1, 505); + message->SetExtension(unittest::repeated_sint64_extension_lite , 1, 506); + message->SetExtension(unittest::repeated_fixed32_extension_lite , 1, 507); + message->SetExtension(unittest::repeated_fixed64_extension_lite , 1, 508); + message->SetExtension(unittest::repeated_sfixed32_extension_lite, 1, 509); + message->SetExtension(unittest::repeated_sfixed64_extension_lite, 1, 510); + message->SetExtension(unittest::repeated_float_extension_lite , 1, 511); + message->SetExtension(unittest::repeated_double_extension_lite , 1, 512); + message->SetExtension(unittest::repeated_bool_extension_lite , 1, true); + message->SetExtension(unittest::repeated_string_extension_lite , 1, "515"); + message->SetExtension(unittest::repeated_bytes_extension_lite , 1, "516"); + + message->MutableExtension(unittest::repeatedgroup_extension_lite , 1)->set_a(517); + message->MutableExtension(unittest::repeated_nested_message_extension_lite , 1)->set_bb(518); + message->MutableExtension(unittest::repeated_foreign_message_extension_lite, 1)->set_c(519); + message->MutableExtension(unittest::repeated_import_message_extension_lite , 1)->set_d(520); + + message->SetExtension(unittest::repeated_nested_enum_extension_lite , 1, unittest::TestAllTypesLite::FOO ); + message->SetExtension(unittest::repeated_foreign_enum_extension_lite, 1, unittest::FOREIGN_LITE_FOO ); + message->SetExtension(unittest::repeated_import_enum_extension_lite , 1, unittest_import::IMPORT_LITE_FOO); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectAllExtensionsSet( + const unittest::TestAllExtensionsLite& message) { + EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_int64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_uint64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_sint32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_sint64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_fixed32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_fixed64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed32_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed64_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::optional_float_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_double_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_bool_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension_lite )); + + EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension_lite )); + + EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension_lite ).has_a()); + EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension_lite ).has_bb()); + EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension_lite).has_c()); + EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension_lite ).has_d()); + + EXPECT_TRUE(message.HasExtension(unittest::optional_nested_enum_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_enum_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::optional_import_enum_extension_lite )); + + + EXPECT_EQ(101 , message.GetExtension(unittest::optional_int32_extension_lite )); + EXPECT_EQ(102 , message.GetExtension(unittest::optional_int64_extension_lite )); + EXPECT_EQ(103 , message.GetExtension(unittest::optional_uint32_extension_lite )); + EXPECT_EQ(104 , message.GetExtension(unittest::optional_uint64_extension_lite )); + EXPECT_EQ(105 , message.GetExtension(unittest::optional_sint32_extension_lite )); + EXPECT_EQ(106 , message.GetExtension(unittest::optional_sint64_extension_lite )); + EXPECT_EQ(107 , message.GetExtension(unittest::optional_fixed32_extension_lite )); + EXPECT_EQ(108 , message.GetExtension(unittest::optional_fixed64_extension_lite )); + EXPECT_EQ(109 , message.GetExtension(unittest::optional_sfixed32_extension_lite)); + EXPECT_EQ(110 , message.GetExtension(unittest::optional_sfixed64_extension_lite)); + EXPECT_EQ(111 , message.GetExtension(unittest::optional_float_extension_lite )); + EXPECT_EQ(112 , message.GetExtension(unittest::optional_double_extension_lite )); + EXPECT_EQ(true , message.GetExtension(unittest::optional_bool_extension_lite )); + EXPECT_EQ("115", message.GetExtension(unittest::optional_string_extension_lite )); + EXPECT_EQ("116", message.GetExtension(unittest::optional_bytes_extension_lite )); + + EXPECT_EQ(117, message.GetExtension(unittest::optionalgroup_extension_lite ).a()); + EXPECT_EQ(118, message.GetExtension(unittest::optional_nested_message_extension_lite ).bb()); + EXPECT_EQ(119, message.GetExtension(unittest::optional_foreign_message_extension_lite).c()); + EXPECT_EQ(120, message.GetExtension(unittest::optional_import_message_extension_lite ).d()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.GetExtension(unittest::optional_nested_enum_extension_lite )); + EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.GetExtension(unittest::optional_foreign_enum_extension_lite)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.GetExtension(unittest::optional_import_enum_extension_lite )); + + + // ----------------------------------------------------------------- + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension_lite )); + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite )); + + + EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension_lite , 0)); + EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension_lite , 0)); + EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension_lite , 0)); + EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension_lite , 0)); + EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension_lite , 0)); + EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension_lite , 0)); + EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 0)); + EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 0)); + EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 0)); + EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 0)); + EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension_lite , 0)); + EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension_lite , 0)); + EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite , 0)); + EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension_lite , 0)); + EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension_lite , 0)); + + EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension_lite , 0).a()); + EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension_lite , 0).bb()); + EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0).c()); + EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension_lite , 0).d()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::repeated_import_enum_extension_lite , 0)); + + + EXPECT_EQ(301 , message.GetExtension(unittest::repeated_int32_extension_lite , 1)); + EXPECT_EQ(302 , message.GetExtension(unittest::repeated_int64_extension_lite , 1)); + EXPECT_EQ(303 , message.GetExtension(unittest::repeated_uint32_extension_lite , 1)); + EXPECT_EQ(304 , message.GetExtension(unittest::repeated_uint64_extension_lite , 1)); + EXPECT_EQ(305 , message.GetExtension(unittest::repeated_sint32_extension_lite , 1)); + EXPECT_EQ(306 , message.GetExtension(unittest::repeated_sint64_extension_lite , 1)); + EXPECT_EQ(307 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 1)); + EXPECT_EQ(308 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 1)); + EXPECT_EQ(309 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 1)); + EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 1)); + EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension_lite , 1)); + EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension_lite , 1)); + EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension_lite , 1)); + EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension_lite , 1)); + EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension_lite , 1)); + + EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension_lite , 1).a()); + EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension_lite , 1).bb()); + EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1).c()); + EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension_lite , 1).d()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 1)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.GetExtension(unittest::repeated_import_enum_extension_lite , 1)); + + + // ----------------------------------------------------------------- + + EXPECT_TRUE(message.HasExtension(unittest::default_int32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_int64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_uint32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_uint64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_sint32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_sint64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_fixed32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_fixed64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_sfixed32_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::default_sfixed64_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::default_float_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_double_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_bool_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_string_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_bytes_extension_lite )); + + EXPECT_TRUE(message.HasExtension(unittest::default_nested_enum_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_foreign_enum_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::default_import_enum_extension_lite )); + + + EXPECT_EQ(401 , message.GetExtension(unittest::default_int32_extension_lite )); + EXPECT_EQ(402 , message.GetExtension(unittest::default_int64_extension_lite )); + EXPECT_EQ(403 , message.GetExtension(unittest::default_uint32_extension_lite )); + EXPECT_EQ(404 , message.GetExtension(unittest::default_uint64_extension_lite )); + EXPECT_EQ(405 , message.GetExtension(unittest::default_sint32_extension_lite )); + EXPECT_EQ(406 , message.GetExtension(unittest::default_sint64_extension_lite )); + EXPECT_EQ(407 , message.GetExtension(unittest::default_fixed32_extension_lite )); + EXPECT_EQ(408 , message.GetExtension(unittest::default_fixed64_extension_lite )); + EXPECT_EQ(409 , message.GetExtension(unittest::default_sfixed32_extension_lite)); + EXPECT_EQ(410 , message.GetExtension(unittest::default_sfixed64_extension_lite)); + EXPECT_EQ(411 , message.GetExtension(unittest::default_float_extension_lite )); + EXPECT_EQ(412 , message.GetExtension(unittest::default_double_extension_lite )); + EXPECT_EQ(false, message.GetExtension(unittest::default_bool_extension_lite )); + EXPECT_EQ("415", message.GetExtension(unittest::default_string_extension_lite )); + EXPECT_EQ("416", message.GetExtension(unittest::default_bytes_extension_lite )); + + EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::default_nested_enum_extension_lite )); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::default_foreign_enum_extension_lite)); + EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::default_import_enum_extension_lite )); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectExtensionsClear( + const unittest::TestAllExtensionsLite& message) { + string serialized; + ASSERT_TRUE(message.SerializeToString(&serialized)); + EXPECT_EQ("", serialized); + EXPECT_EQ(0, message.ByteSize()); + + // has_blah() should initially be false for all optional fields. + EXPECT_FALSE(message.HasExtension(unittest::optional_int32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_uint32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_uint64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_sint32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_sint64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_fixed32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_fixed64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed32_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed64_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::optional_float_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_double_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_bool_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension_lite )); + + EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension_lite )); + + EXPECT_FALSE(message.HasExtension(unittest::optional_nested_enum_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_enum_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::optional_import_enum_extension_lite )); + + + // Optional fields without defaults are set to zero or something like it. + EXPECT_EQ(0 , message.GetExtension(unittest::optional_int32_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_int64_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint32_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint64_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint32_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint64_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed32_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed64_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed32_extension_lite)); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed64_extension_lite)); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_float_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_double_extension_lite )); + EXPECT_EQ(false, message.GetExtension(unittest::optional_bool_extension_lite )); + EXPECT_EQ("" , message.GetExtension(unittest::optional_string_extension_lite )); + EXPECT_EQ("" , message.GetExtension(unittest::optional_bytes_extension_lite )); + + // Embedded messages should also be clear. + EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension_lite ).has_a()); + EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension_lite ).has_bb()); + EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension_lite).has_c()); + EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension_lite ).has_d()); + + EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension_lite ).a()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension_lite ).bb()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension_lite).c()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension_lite ).d()); + + // Enums without defaults are set to the first value in the enum. + EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::optional_nested_enum_extension_lite )); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::optional_foreign_enum_extension_lite)); + EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::optional_import_enum_extension_lite )); + + + // Repeated fields are empty. + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite)); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite)); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_float_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_double_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bool_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bytes_extension_lite )); + + EXPECT_EQ(0, message.ExtensionSize(unittest::repeatedgroup_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_message_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite)); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_message_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_enum_extension_lite )); + + + // has_blah() should also be false for all default fields. + EXPECT_FALSE(message.HasExtension(unittest::default_int32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_int64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_uint32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_uint64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_sint32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_sint64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_fixed32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_fixed64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_sfixed32_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::default_sfixed64_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::default_float_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_double_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_bool_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_string_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_bytes_extension_lite )); + + EXPECT_FALSE(message.HasExtension(unittest::default_nested_enum_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_foreign_enum_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::default_import_enum_extension_lite )); + + + // Fields with defaults have their default values (duh). + EXPECT_EQ( 41 , message.GetExtension(unittest::default_int32_extension_lite )); + EXPECT_EQ( 42 , message.GetExtension(unittest::default_int64_extension_lite )); + EXPECT_EQ( 43 , message.GetExtension(unittest::default_uint32_extension_lite )); + EXPECT_EQ( 44 , message.GetExtension(unittest::default_uint64_extension_lite )); + EXPECT_EQ(-45 , message.GetExtension(unittest::default_sint32_extension_lite )); + EXPECT_EQ( 46 , message.GetExtension(unittest::default_sint64_extension_lite )); + EXPECT_EQ( 47 , message.GetExtension(unittest::default_fixed32_extension_lite )); + EXPECT_EQ( 48 , message.GetExtension(unittest::default_fixed64_extension_lite )); + EXPECT_EQ( 49 , message.GetExtension(unittest::default_sfixed32_extension_lite)); + EXPECT_EQ(-50 , message.GetExtension(unittest::default_sfixed64_extension_lite)); + EXPECT_EQ( 51.5 , message.GetExtension(unittest::default_float_extension_lite )); + EXPECT_EQ( 52e3 , message.GetExtension(unittest::default_double_extension_lite )); + EXPECT_EQ(true , message.GetExtension(unittest::default_bool_extension_lite )); + EXPECT_EQ("hello", message.GetExtension(unittest::default_string_extension_lite )); + EXPECT_EQ("world", message.GetExtension(unittest::default_bytes_extension_lite )); + + EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::default_nested_enum_extension_lite )); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::default_foreign_enum_extension_lite)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::default_import_enum_extension_lite )); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectRepeatedExtensionsModified( + const unittest::TestAllExtensionsLite& message) { + // ModifyRepeatedFields only sets the second repeated element of each + // field. In addition to verifying this, we also verify that the first + // element and size were *not* modified. + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension_lite )); + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite )); + + + EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension_lite , 0)); + EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension_lite , 0)); + EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension_lite , 0)); + EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension_lite , 0)); + EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension_lite , 0)); + EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension_lite , 0)); + EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 0)); + EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 0)); + EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 0)); + EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 0)); + EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension_lite , 0)); + EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension_lite , 0)); + EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite , 0)); + EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension_lite , 0)); + EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension_lite , 0)); + + EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension_lite , 0).a()); + EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension_lite , 0).bb()); + EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0).c()); + EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension_lite , 0).d()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::repeated_import_enum_extension_lite , 0)); + + + // Actually verify the second (modified) elements now. + EXPECT_EQ(501 , message.GetExtension(unittest::repeated_int32_extension_lite , 1)); + EXPECT_EQ(502 , message.GetExtension(unittest::repeated_int64_extension_lite , 1)); + EXPECT_EQ(503 , message.GetExtension(unittest::repeated_uint32_extension_lite , 1)); + EXPECT_EQ(504 , message.GetExtension(unittest::repeated_uint64_extension_lite , 1)); + EXPECT_EQ(505 , message.GetExtension(unittest::repeated_sint32_extension_lite , 1)); + EXPECT_EQ(506 , message.GetExtension(unittest::repeated_sint64_extension_lite , 1)); + EXPECT_EQ(507 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 1)); + EXPECT_EQ(508 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 1)); + EXPECT_EQ(509 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 1)); + EXPECT_EQ(510 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 1)); + EXPECT_EQ(511 , message.GetExtension(unittest::repeated_float_extension_lite , 1)); + EXPECT_EQ(512 , message.GetExtension(unittest::repeated_double_extension_lite , 1)); + EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite , 1)); + EXPECT_EQ("515", message.GetExtension(unittest::repeated_string_extension_lite , 1)); + EXPECT_EQ("516", message.GetExtension(unittest::repeated_bytes_extension_lite , 1)); + + EXPECT_EQ(517, message.GetExtension(unittest::repeatedgroup_extension_lite , 1).a()); + EXPECT_EQ(518, message.GetExtension(unittest::repeated_nested_message_extension_lite , 1).bb()); + EXPECT_EQ(519, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1).c()); + EXPECT_EQ(520, message.GetExtension(unittest::repeated_import_message_extension_lite , 1).d()); + + EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 1)); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1)); + EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::repeated_import_enum_extension_lite , 1)); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::SetPackedExtensions( + unittest::TestPackedExtensionsLite* message) { + message->AddExtension(unittest::packed_int32_extension_lite , 601); + message->AddExtension(unittest::packed_int64_extension_lite , 602); + message->AddExtension(unittest::packed_uint32_extension_lite , 603); + message->AddExtension(unittest::packed_uint64_extension_lite , 604); + message->AddExtension(unittest::packed_sint32_extension_lite , 605); + message->AddExtension(unittest::packed_sint64_extension_lite , 606); + message->AddExtension(unittest::packed_fixed32_extension_lite , 607); + message->AddExtension(unittest::packed_fixed64_extension_lite , 608); + message->AddExtension(unittest::packed_sfixed32_extension_lite, 609); + message->AddExtension(unittest::packed_sfixed64_extension_lite, 610); + message->AddExtension(unittest::packed_float_extension_lite , 611); + message->AddExtension(unittest::packed_double_extension_lite , 612); + message->AddExtension(unittest::packed_bool_extension_lite , true); + message->AddExtension(unittest::packed_enum_extension_lite, unittest::FOREIGN_LITE_BAR); + // add a second one of each field + message->AddExtension(unittest::packed_int32_extension_lite , 701); + message->AddExtension(unittest::packed_int64_extension_lite , 702); + message->AddExtension(unittest::packed_uint32_extension_lite , 703); + message->AddExtension(unittest::packed_uint64_extension_lite , 704); + message->AddExtension(unittest::packed_sint32_extension_lite , 705); + message->AddExtension(unittest::packed_sint64_extension_lite , 706); + message->AddExtension(unittest::packed_fixed32_extension_lite , 707); + message->AddExtension(unittest::packed_fixed64_extension_lite , 708); + message->AddExtension(unittest::packed_sfixed32_extension_lite, 709); + message->AddExtension(unittest::packed_sfixed64_extension_lite, 710); + message->AddExtension(unittest::packed_float_extension_lite , 711); + message->AddExtension(unittest::packed_double_extension_lite , 712); + message->AddExtension(unittest::packed_bool_extension_lite , false); + message->AddExtension(unittest::packed_enum_extension_lite, unittest::FOREIGN_LITE_BAZ); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ModifyPackedExtensions( + unittest::TestPackedExtensionsLite* message) { + message->SetExtension(unittest::packed_int32_extension_lite , 1, 801); + message->SetExtension(unittest::packed_int64_extension_lite , 1, 802); + message->SetExtension(unittest::packed_uint32_extension_lite , 1, 803); + message->SetExtension(unittest::packed_uint64_extension_lite , 1, 804); + message->SetExtension(unittest::packed_sint32_extension_lite , 1, 805); + message->SetExtension(unittest::packed_sint64_extension_lite , 1, 806); + message->SetExtension(unittest::packed_fixed32_extension_lite , 1, 807); + message->SetExtension(unittest::packed_fixed64_extension_lite , 1, 808); + message->SetExtension(unittest::packed_sfixed32_extension_lite, 1, 809); + message->SetExtension(unittest::packed_sfixed64_extension_lite, 1, 810); + message->SetExtension(unittest::packed_float_extension_lite , 1, 811); + message->SetExtension(unittest::packed_double_extension_lite , 1, 812); + message->SetExtension(unittest::packed_bool_extension_lite , 1, true); + message->SetExtension(unittest::packed_enum_extension_lite , 1, + unittest::FOREIGN_LITE_FOO); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectPackedExtensionsSet( + const unittest::TestPackedExtensionsLite& message) { + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension_lite )); + + EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension_lite , 0)); + EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension_lite , 0)); + EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension_lite , 0)); + EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension_lite , 0)); + EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension_lite , 0)); + EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension_lite , 0)); + EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension_lite , 0)); + EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension_lite , 0)); + EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 0)); + EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 0)); + EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension_lite , 0)); + EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension_lite , 0)); + EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite , 0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR, + message.GetExtension(unittest::packed_enum_extension_lite, 0)); + EXPECT_EQ(701 , message.GetExtension(unittest::packed_int32_extension_lite , 1)); + EXPECT_EQ(702 , message.GetExtension(unittest::packed_int64_extension_lite , 1)); + EXPECT_EQ(703 , message.GetExtension(unittest::packed_uint32_extension_lite , 1)); + EXPECT_EQ(704 , message.GetExtension(unittest::packed_uint64_extension_lite , 1)); + EXPECT_EQ(705 , message.GetExtension(unittest::packed_sint32_extension_lite , 1)); + EXPECT_EQ(706 , message.GetExtension(unittest::packed_sint64_extension_lite , 1)); + EXPECT_EQ(707 , message.GetExtension(unittest::packed_fixed32_extension_lite , 1)); + EXPECT_EQ(708 , message.GetExtension(unittest::packed_fixed64_extension_lite , 1)); + EXPECT_EQ(709 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 1)); + EXPECT_EQ(710 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 1)); + EXPECT_EQ(711 , message.GetExtension(unittest::packed_float_extension_lite , 1)); + EXPECT_EQ(712 , message.GetExtension(unittest::packed_double_extension_lite , 1)); + EXPECT_EQ(false, message.GetExtension(unittest::packed_bool_extension_lite , 1)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAZ, + message.GetExtension(unittest::packed_enum_extension_lite, 1)); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectPackedExtensionsClear( + const unittest::TestPackedExtensionsLite& message) { + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed32_extension_lite)); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed64_extension_lite)); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_float_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_double_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_bool_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_enum_extension_lite )); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectPackedExtensionsModified( + const unittest::TestPackedExtensionsLite& message) { + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension_lite )); + EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension_lite , 0)); + EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension_lite , 0)); + EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension_lite , 0)); + EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension_lite , 0)); + EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension_lite , 0)); + EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension_lite , 0)); + EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension_lite , 0)); + EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension_lite , 0)); + EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 0)); + EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 0)); + EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension_lite , 0)); + EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension_lite , 0)); + EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite , 0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR, + message.GetExtension(unittest::packed_enum_extension_lite, 0)); + + // Actually verify the second (modified) elements now. + EXPECT_EQ(801 , message.GetExtension(unittest::packed_int32_extension_lite , 1)); + EXPECT_EQ(802 , message.GetExtension(unittest::packed_int64_extension_lite , 1)); + EXPECT_EQ(803 , message.GetExtension(unittest::packed_uint32_extension_lite , 1)); + EXPECT_EQ(804 , message.GetExtension(unittest::packed_uint64_extension_lite , 1)); + EXPECT_EQ(805 , message.GetExtension(unittest::packed_sint32_extension_lite , 1)); + EXPECT_EQ(806 , message.GetExtension(unittest::packed_sint64_extension_lite , 1)); + EXPECT_EQ(807 , message.GetExtension(unittest::packed_fixed32_extension_lite , 1)); + EXPECT_EQ(808 , message.GetExtension(unittest::packed_fixed64_extension_lite , 1)); + EXPECT_EQ(809 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 1)); + EXPECT_EQ(810 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 1)); + EXPECT_EQ(811 , message.GetExtension(unittest::packed_float_extension_lite , 1)); + EXPECT_EQ(812 , message.GetExtension(unittest::packed_double_extension_lite , 1)); + EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite , 1)); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO, + message.GetExtension(unittest::packed_enum_extension_lite, 1)); +} + +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/test_util_lite.h b/src/google/protobuf/test_util_lite.h new file mode 100644 index 00000000..ca35aaa4 --- /dev/null +++ b/src/google/protobuf/test_util_lite.h @@ -0,0 +1,101 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__ +#define GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__ + +#include + +namespace google { +namespace protobuf { + +namespace unittest = protobuf_unittest; +namespace unittest_import = protobuf_unittest_import; + +class TestUtilLite { + public: + // Set every field in the message to a unique value. + static void SetAllFields(unittest::TestAllTypesLite* message); + static void SetAllExtensions(unittest::TestAllExtensionsLite* message); + static void SetPackedFields(unittest::TestPackedTypesLite* message); + static void SetPackedExtensions(unittest::TestPackedExtensionsLite* message); + + // Use the repeated versions of the set_*() accessors to modify all the + // repeated fields of the messsage (which should already have been + // initialized with Set*Fields()). Set*Fields() itself only tests + // the add_*() accessors. + static void ModifyRepeatedFields(unittest::TestAllTypesLite* message); + static void ModifyRepeatedExtensions( + unittest::TestAllExtensionsLite* message); + static void ModifyPackedFields(unittest::TestPackedTypesLite* message); + static void ModifyPackedExtensions( + unittest::TestPackedExtensionsLite* message); + + // Check that all fields have the values that they should have after + // Set*Fields() is called. + static void ExpectAllFieldsSet(const unittest::TestAllTypesLite& message); + static void ExpectAllExtensionsSet( + const unittest::TestAllExtensionsLite& message); + static void ExpectPackedFieldsSet( + const unittest::TestPackedTypesLite& message); + static void ExpectPackedExtensionsSet( + const unittest::TestPackedExtensionsLite& message); + + // Expect that the message is modified as would be expected from + // Modify*Fields(). + static void ExpectRepeatedFieldsModified( + const unittest::TestAllTypesLite& message); + static void ExpectRepeatedExtensionsModified( + const unittest::TestAllExtensionsLite& message); + static void ExpectPackedFieldsModified( + const unittest::TestPackedTypesLite& message); + static void ExpectPackedExtensionsModified( + const unittest::TestPackedExtensionsLite& message); + + // Check that all fields have their default values. + static void ExpectClear(const unittest::TestAllTypesLite& message); + static void ExpectExtensionsClear( + const unittest::TestAllExtensionsLite& message); + static void ExpectPackedClear(const unittest::TestPackedTypesLite& message); + static void ExpectPackedExtensionsClear( + const unittest::TestPackedExtensionsLite& message); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TestUtilLite); +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__ diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index ae88cdff..cf754024 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -142,6 +142,16 @@ class TextFormat::Parser::ParserImpl { } } + bool ParseField(const FieldDescriptor* field, Message* output) { + bool suc; + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + suc = ConsumeFieldMessage(output, output->GetReflection(), field); + } else { + suc = ConsumeFieldValue(output, output->GetReflection(), field); + } + return suc && LookingAtType(io::Tokenizer::TYPE_END); + } + void ReportError(int line, int col, const string& message) { had_errors_ = true; if (error_collector_ == NULL) { @@ -252,24 +262,9 @@ class TextFormat::Parser::ParserImpl { // Perform special handling for embedded message types. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - string delimeter; - // ':' is optional here. TryConsume(":"); - - if (TryConsume("<")) { - delimeter = ">"; - } else { - DO(Consume("{")); - delimeter = "}"; - } - - if (field->is_repeated()) { - DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter)); - } else { - DO(ConsumeMessage(reflection->MutableMessage(message, field), - delimeter)); - } + DO(ConsumeFieldMessage(message, reflection, field)); } else { DO(Consume(":")); DO(ConsumeFieldValue(message, reflection, field)); @@ -278,6 +273,26 @@ class TextFormat::Parser::ParserImpl { return true; } + bool ConsumeFieldMessage(Message* message, + const Reflection* reflection, + const FieldDescriptor* field) { + string delimeter; + if (TryConsume("<")) { + delimeter = ">"; + } else { + DO(Consume("{")); + delimeter = "}"; + } + + if (field->is_repeated()) { + DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter)); + } else { + DO(ConsumeMessage(reflection->MutableMessage(message, field), + delimeter)); + } + return true; + } + bool ConsumeFieldValue(Message* message, const Reflection* reflection, const FieldDescriptor* field) { @@ -750,6 +765,16 @@ bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input, return true; } +bool TextFormat::Parser::ParseFieldValueFromString( + const string& input, + const FieldDescriptor* field, + Message* output) { + io::ArrayInputStream input_stream(input.data(), input.size()); + ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_, + ParserImpl::ALLOW_SINGULAR_OVERWRITES); + return parser.ParseField(field, output); +} + /* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input, Message* output) { return Parser().Parse(input, output); @@ -1008,6 +1033,13 @@ void TextFormat::Printer::PrintFieldValue( return Printer().PrintFieldValueToString(message, field, index, output); } +/* static */ bool TextFormat::ParseFieldValueFromString( + const string& input, + const FieldDescriptor* field, + Message* message) { + return Parser().ParseFieldValueFromString(input, field, message); +} + // Prints an integer as hex with a fixed number of digits dependent on the // integer type. template diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h index e2b27c68..39a039d9 100644 --- a/src/google/protobuf/text_format.h +++ b/src/google/protobuf/text_format.h @@ -165,6 +165,13 @@ class LIBPROTOBUF_EXPORT TextFormat { // Like Merge(), but reads directly from a string. static bool MergeFromString(const string& input, Message* output); + // Parse the given text as a single field value and store it into the + // given field of the given message. If the field is a repeated field, + // the new value will be added to the end + static bool ParseFieldValueFromString(const string& input, + const FieldDescriptor* field, + Message* message); + // For more control over parsing, use this class. class LIBPROTOBUF_EXPORT Parser { public: @@ -192,6 +199,11 @@ class LIBPROTOBUF_EXPORT TextFormat { allow_partial_ = allow; } + // Like TextFormat::ParseFieldValueFromString + bool ParseFieldValueFromString(const string& input, + const FieldDescriptor* field, + Message* output); + private: // Forward declaration of an internal class used to parse text // representations (see text_format.cc for implementation). diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index eaa278bc..7c31e80f 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -597,8 +597,8 @@ class TextFormatParserTest : public testing::Test { protected: void ExpectFailure(const string& input, const string& message, int line, int col) { - unittest::TestAllTypes proto; - ExpectFailure(input, message, line, col, &proto); + scoped_ptr proto(new unittest::TestAllTypes); + ExpectFailure(input, message, line, col, proto.get()); } void ExpectFailure(const string& input, const string& message, int line, @@ -628,6 +628,120 @@ class TextFormatParserTest : public testing::Test { }; }; +TEST_F(TextFormatParserTest, ParseFieldValueFromString) { + scoped_ptr message(new unittest::TestAllTypes); + const Descriptor* d = message->GetDescriptor(); + +#define EXPECT_FIELD(name, value, valuestring) \ + EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ + valuestring, d->FindFieldByName("optional_" #name), message.get())); \ + EXPECT_EQ(value, message->optional_##name()); \ + EXPECT_TRUE(message->has_optional_##name()); + +#define EXPECT_FLOAT_FIELD(name, value, valuestring) \ + EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ + valuestring, d->FindFieldByName("optional_" #name), message.get())); \ + EXPECT_FLOAT_EQ(value, message->optional_##name()); \ + EXPECT_TRUE(message->has_optional_##name()); + +#define EXPECT_DOUBLE_FIELD(name, value, valuestring) \ + EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ + valuestring, d->FindFieldByName("optional_" #name), message.get())); \ + EXPECT_DOUBLE_EQ(value, message->optional_##name()); \ + EXPECT_TRUE(message->has_optional_##name()); + +#define EXPECT_INVALID(name, valuestring) \ + EXPECT_FALSE(TextFormat::ParseFieldValueFromString( \ + valuestring, d->FindFieldByName("optional_" #name), message.get())); + + // int32 + EXPECT_FIELD(int32, 1, "1"); + EXPECT_FIELD(int32, -1, "-1"); + EXPECT_FIELD(int32, 0x1234, "0x1234"); + EXPECT_INVALID(int32, "a"); + EXPECT_INVALID(int32, "999999999999999999999999999999999999"); + EXPECT_INVALID(int32, "1,2"); + + // int64 + EXPECT_FIELD(int64, 1, "1"); + EXPECT_FIELD(int64, -1, "-1"); + EXPECT_FIELD(int64, 0x1234567812345678LL, "0x1234567812345678"); + EXPECT_INVALID(int64, "a"); + EXPECT_INVALID(int64, "999999999999999999999999999999999999"); + EXPECT_INVALID(int64, "1,2"); + + // uint64 + EXPECT_FIELD(uint64, 1, "1"); + EXPECT_FIELD(uint64, 0xf234567812345678ULL, "0xf234567812345678"); + EXPECT_INVALID(uint64, "-1"); + EXPECT_INVALID(uint64, "a"); + EXPECT_INVALID(uint64, "999999999999999999999999999999999999"); + EXPECT_INVALID(uint64, "1,2"); + + // fixed32 + EXPECT_FIELD(fixed32, 1, "1"); + EXPECT_FIELD(fixed32, 0x12345678, "0x12345678"); + EXPECT_INVALID(fixed32, "-1"); + EXPECT_INVALID(fixed32, "a"); + EXPECT_INVALID(fixed32, "999999999999999999999999999999999999"); + EXPECT_INVALID(fixed32, "1,2"); + + // fixed64 + EXPECT_FIELD(fixed64, 1, "1"); + EXPECT_FIELD(fixed64, 0x1234567812345678ULL, "0x1234567812345678"); + EXPECT_INVALID(fixed64, "-1"); + EXPECT_INVALID(fixed64, "a"); + EXPECT_INVALID(fixed64, "999999999999999999999999999999999999"); + EXPECT_INVALID(fixed64, "1,2"); + + // bool + EXPECT_FIELD(bool, true, "true"); + EXPECT_FIELD(bool, false, "false"); + EXPECT_INVALID(bool, "1"); + EXPECT_INVALID(bool, "on"); + EXPECT_INVALID(bool, "a"); + EXPECT_INVALID(bool, "True"); + + // float + EXPECT_FIELD(float, 1, "1"); + EXPECT_FLOAT_FIELD(float, 1.5, "1.5"); + EXPECT_FLOAT_FIELD(float, 1.5e3, "1.5e3"); + EXPECT_FLOAT_FIELD(float, -4.55, "-4.55"); + EXPECT_INVALID(float, "a"); + EXPECT_INVALID(float, "1,2"); + + // double + EXPECT_FIELD(double, 1, "1"); + EXPECT_FIELD(double, -1, "-1"); + EXPECT_DOUBLE_FIELD(double, 2.3, "2.3"); + EXPECT_DOUBLE_FIELD(double, 3e5, "3e5"); + EXPECT_INVALID(double, "a"); + EXPECT_INVALID(double, "1,2"); + + // string + EXPECT_FIELD(string, "hello", "\"hello\""); + EXPECT_FIELD(string, "-1.87", "'-1.87'"); + EXPECT_INVALID(string, "hello"); // without quote for value + + // enum + EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR"); + EXPECT_INVALID(nested_enum, "1"); // number not supported + EXPECT_INVALID(nested_enum, "FOOBAR"); + + // message + EXPECT_TRUE(TextFormat::ParseFieldValueFromString( + "", d->FindFieldByName("optional_nested_message"), message.get())); + EXPECT_EQ(12, message->optional_nested_message().bb()); \ + EXPECT_TRUE(message->has_optional_nested_message()); + EXPECT_INVALID(nested_message, "any"); + +#undef EXPECT_FIELD +#undef EXPECT_FLOAT_FIELD +#undef EXPECT_DOUBLE_FIELD +#undef EXPECT_INVALID +} + + TEST_F(TextFormatParserTest, InvalidToken) { ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.", 2, 1); @@ -735,7 +849,7 @@ TEST_F(TextFormatParserTest, InvalidFieldValues) { "Unknown enumeration value of \"grah\" for field " "\"optional_nested_enum\".", 2, 1); - ExpectFailure( + ExpectFailure( "optional_nested_enum {\n \n}\n", "Expected \":\", found \"{\".", 1, 22); } diff --git a/src/google/protobuf/unittest_custom_options.proto b/src/google/protobuf/unittest_custom_options.proto index 88f6f1f7..b6ee03da 100644 --- a/src/google/protobuf/unittest_custom_options.proto +++ b/src/google/protobuf/unittest_custom_options.proto @@ -204,6 +204,8 @@ message SettingRealsFromNegativeInts { message ComplexOptionType1 { optional int32 foo = 1; + optional int32 foo2 = 2; + optional int32 foo3 = 3; extensions 100 to max; } diff --git a/src/google/protobuf/unittest_import_lite.proto b/src/google/protobuf/unittest_import_lite.proto new file mode 100644 index 00000000..ebaab5c0 --- /dev/null +++ b/src/google/protobuf/unittest_import_lite.proto @@ -0,0 +1,49 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// This is like unittest_import.proto but with optimize_for = LITE_RUNTIME. + +package protobuf_unittest_import; + +option optimize_for = LITE_RUNTIME; + +option java_package = "com.google.protobuf"; + +message ImportMessageLite { + optional int32 d = 1; +} + +enum ImportEnumLite { + IMPORT_LITE_FOO = 7; + IMPORT_LITE_BAR = 8; + IMPORT_LITE_BAZ = 9; +} diff --git a/src/google/protobuf/unittest_lite.proto b/src/google/protobuf/unittest_lite.proto new file mode 100644 index 00000000..cca6b497 --- /dev/null +++ b/src/google/protobuf/unittest_lite.proto @@ -0,0 +1,312 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// This is like unittest.proto but with optimize_for = LITE_RUNTIME. + +package protobuf_unittest; + +import "google/protobuf/unittest_import_lite.proto"; + +option optimize_for = LITE_RUNTIME; + +option java_package = "com.google.protobuf"; + +// Same as TestAllTypes but with the lite runtime. +message TestAllTypesLite { + message NestedMessage { + optional int32 bb = 1; + } + + enum NestedEnum { + FOO = 1; + BAR = 2; + BAZ = 3; + } + + // Singular + optional int32 optional_int32 = 1; + optional int64 optional_int64 = 2; + optional uint32 optional_uint32 = 3; + optional uint64 optional_uint64 = 4; + optional sint32 optional_sint32 = 5; + optional sint64 optional_sint64 = 6; + optional fixed32 optional_fixed32 = 7; + optional fixed64 optional_fixed64 = 8; + optional sfixed32 optional_sfixed32 = 9; + optional sfixed64 optional_sfixed64 = 10; + optional float optional_float = 11; + optional double optional_double = 12; + optional bool optional_bool = 13; + optional string optional_string = 14; + optional bytes optional_bytes = 15; + + optional group OptionalGroup = 16 { + optional int32 a = 17; + } + + optional NestedMessage optional_nested_message = 18; + optional ForeignMessageLite optional_foreign_message = 19; + optional protobuf_unittest_import.ImportMessageLite + optional_import_message = 20; + + optional NestedEnum optional_nested_enum = 21; + optional ForeignEnumLite optional_foreign_enum = 22; + optional protobuf_unittest_import.ImportEnumLite optional_import_enum = 23; + + optional string optional_string_piece = 24 [ctype=STRING_PIECE]; + optional string optional_cord = 25 [ctype=CORD]; + + // Repeated + repeated int32 repeated_int32 = 31; + repeated int64 repeated_int64 = 32; + repeated uint32 repeated_uint32 = 33; + repeated uint64 repeated_uint64 = 34; + repeated sint32 repeated_sint32 = 35; + repeated sint64 repeated_sint64 = 36; + repeated fixed32 repeated_fixed32 = 37; + repeated fixed64 repeated_fixed64 = 38; + repeated sfixed32 repeated_sfixed32 = 39; + repeated sfixed64 repeated_sfixed64 = 40; + repeated float repeated_float = 41; + repeated double repeated_double = 42; + repeated bool repeated_bool = 43; + repeated string repeated_string = 44; + repeated bytes repeated_bytes = 45; + + repeated group RepeatedGroup = 46 { + optional int32 a = 47; + } + + repeated NestedMessage repeated_nested_message = 48; + repeated ForeignMessageLite repeated_foreign_message = 49; + repeated protobuf_unittest_import.ImportMessageLite + repeated_import_message = 50; + + repeated NestedEnum repeated_nested_enum = 51; + repeated ForeignEnumLite repeated_foreign_enum = 52; + repeated protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53; + + repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; + repeated string repeated_cord = 55 [ctype=CORD]; + + // Singular with defaults + optional int32 default_int32 = 61 [default = 41 ]; + optional int64 default_int64 = 62 [default = 42 ]; + optional uint32 default_uint32 = 63 [default = 43 ]; + optional uint64 default_uint64 = 64 [default = 44 ]; + optional sint32 default_sint32 = 65 [default = -45 ]; + optional sint64 default_sint64 = 66 [default = 46 ]; + optional fixed32 default_fixed32 = 67 [default = 47 ]; + optional fixed64 default_fixed64 = 68 [default = 48 ]; + optional sfixed32 default_sfixed32 = 69 [default = 49 ]; + optional sfixed64 default_sfixed64 = 70 [default = -50 ]; + optional float default_float = 71 [default = 51.5 ]; + optional double default_double = 72 [default = 52e3 ]; + optional bool default_bool = 73 [default = true ]; + optional string default_string = 74 [default = "hello"]; + optional bytes default_bytes = 75 [default = "world"]; + + optional NestedEnum default_nested_enum = 81 [default = BAR]; + optional ForeignEnumLite default_foreign_enum = 82 + [default = FOREIGN_LITE_BAR]; + optional protobuf_unittest_import.ImportEnumLite + default_import_enum = 83 [default = IMPORT_LITE_BAR]; + + optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"]; + optional string default_cord = 85 [ctype=CORD,default="123"]; +} + +message ForeignMessageLite { + optional int32 c = 1; +} + +enum ForeignEnumLite { + FOREIGN_LITE_FOO = 4; + FOREIGN_LITE_BAR = 5; + FOREIGN_LITE_BAZ = 6; +} + +message TestPackedTypesLite { + repeated int32 packed_int32 = 90 [packed = true]; + repeated int64 packed_int64 = 91 [packed = true]; + repeated uint32 packed_uint32 = 92 [packed = true]; + repeated uint64 packed_uint64 = 93 [packed = true]; + repeated sint32 packed_sint32 = 94 [packed = true]; + repeated sint64 packed_sint64 = 95 [packed = true]; + repeated fixed32 packed_fixed32 = 96 [packed = true]; + repeated fixed64 packed_fixed64 = 97 [packed = true]; + repeated sfixed32 packed_sfixed32 = 98 [packed = true]; + repeated sfixed64 packed_sfixed64 = 99 [packed = true]; + repeated float packed_float = 100 [packed = true]; + repeated double packed_double = 101 [packed = true]; + repeated bool packed_bool = 102 [packed = true]; + repeated ForeignEnumLite packed_enum = 103 [packed = true]; +} + +message TestAllExtensionsLite { + extensions 1 to max; +} + +extend TestAllExtensionsLite { + // Singular + optional int32 optional_int32_extension_lite = 1; + optional int64 optional_int64_extension_lite = 2; + optional uint32 optional_uint32_extension_lite = 3; + optional uint64 optional_uint64_extension_lite = 4; + optional sint32 optional_sint32_extension_lite = 5; + optional sint64 optional_sint64_extension_lite = 6; + optional fixed32 optional_fixed32_extension_lite = 7; + optional fixed64 optional_fixed64_extension_lite = 8; + optional sfixed32 optional_sfixed32_extension_lite = 9; + optional sfixed64 optional_sfixed64_extension_lite = 10; + optional float optional_float_extension_lite = 11; + optional double optional_double_extension_lite = 12; + optional bool optional_bool_extension_lite = 13; + optional string optional_string_extension_lite = 14; + optional bytes optional_bytes_extension_lite = 15; + + optional group OptionalGroup_extension_lite = 16 { + optional int32 a = 17; + } + + optional TestAllTypesLite.NestedMessage optional_nested_message_extension_lite + = 18; + optional ForeignMessageLite optional_foreign_message_extension_lite = 19; + optional protobuf_unittest_import.ImportMessageLite + optional_import_message_extension_lite = 20; + + optional TestAllTypesLite.NestedEnum optional_nested_enum_extension_lite = 21; + optional ForeignEnumLite optional_foreign_enum_extension_lite = 22; + optional protobuf_unittest_import.ImportEnumLite + optional_import_enum_extension_lite = 23; + + optional string optional_string_piece_extension_lite = 24 + [ctype=STRING_PIECE]; + optional string optional_cord_extension_lite = 25 [ctype=CORD]; + + // Repeated + repeated int32 repeated_int32_extension_lite = 31; + repeated int64 repeated_int64_extension_lite = 32; + repeated uint32 repeated_uint32_extension_lite = 33; + repeated uint64 repeated_uint64_extension_lite = 34; + repeated sint32 repeated_sint32_extension_lite = 35; + repeated sint64 repeated_sint64_extension_lite = 36; + repeated fixed32 repeated_fixed32_extension_lite = 37; + repeated fixed64 repeated_fixed64_extension_lite = 38; + repeated sfixed32 repeated_sfixed32_extension_lite = 39; + repeated sfixed64 repeated_sfixed64_extension_lite = 40; + repeated float repeated_float_extension_lite = 41; + repeated double repeated_double_extension_lite = 42; + repeated bool repeated_bool_extension_lite = 43; + repeated string repeated_string_extension_lite = 44; + repeated bytes repeated_bytes_extension_lite = 45; + + repeated group RepeatedGroup_extension_lite = 46 { + optional int32 a = 47; + } + + repeated TestAllTypesLite.NestedMessage repeated_nested_message_extension_lite + = 48; + repeated ForeignMessageLite repeated_foreign_message_extension_lite = 49; + repeated protobuf_unittest_import.ImportMessageLite + repeated_import_message_extension_lite = 50; + + repeated TestAllTypesLite.NestedEnum repeated_nested_enum_extension_lite = 51; + repeated ForeignEnumLite repeated_foreign_enum_extension_lite = 52; + repeated protobuf_unittest_import.ImportEnumLite + repeated_import_enum_extension_lite = 53; + + repeated string repeated_string_piece_extension_lite = 54 + [ctype=STRING_PIECE]; + repeated string repeated_cord_extension_lite = 55 [ctype=CORD]; + + // Singular with defaults + optional int32 default_int32_extension_lite = 61 [default = 41 ]; + optional int64 default_int64_extension_lite = 62 [default = 42 ]; + optional uint32 default_uint32_extension_lite = 63 [default = 43 ]; + optional uint64 default_uint64_extension_lite = 64 [default = 44 ]; + optional sint32 default_sint32_extension_lite = 65 [default = -45 ]; + optional sint64 default_sint64_extension_lite = 66 [default = 46 ]; + optional fixed32 default_fixed32_extension_lite = 67 [default = 47 ]; + optional fixed64 default_fixed64_extension_lite = 68 [default = 48 ]; + optional sfixed32 default_sfixed32_extension_lite = 69 [default = 49 ]; + optional sfixed64 default_sfixed64_extension_lite = 70 [default = -50 ]; + optional float default_float_extension_lite = 71 [default = 51.5 ]; + optional double default_double_extension_lite = 72 [default = 52e3 ]; + optional bool default_bool_extension_lite = 73 [default = true ]; + optional string default_string_extension_lite = 74 [default = "hello"]; + optional bytes default_bytes_extension_lite = 75 [default = "world"]; + + optional TestAllTypesLite.NestedEnum + default_nested_enum_extension_lite = 81 [default = BAR]; + optional ForeignEnumLite + default_foreign_enum_extension_lite = 82 [default = FOREIGN_LITE_BAR]; + optional protobuf_unittest_import.ImportEnumLite + default_import_enum_extension_lite = 83 [default = IMPORT_LITE_BAR]; + + optional string default_string_piece_extension_lite = 84 [ctype=STRING_PIECE, + default="abc"]; + optional string default_cord_extension_lite = 85 [ctype=CORD, default="123"]; +} + +message TestPackedExtensionsLite { + extensions 1 to max; +} + +extend TestPackedExtensionsLite { + repeated int32 packed_int32_extension_lite = 90 [packed = true]; + repeated int64 packed_int64_extension_lite = 91 [packed = true]; + repeated uint32 packed_uint32_extension_lite = 92 [packed = true]; + repeated uint64 packed_uint64_extension_lite = 93 [packed = true]; + repeated sint32 packed_sint32_extension_lite = 94 [packed = true]; + repeated sint64 packed_sint64_extension_lite = 95 [packed = true]; + repeated fixed32 packed_fixed32_extension_lite = 96 [packed = true]; + repeated fixed64 packed_fixed64_extension_lite = 97 [packed = true]; + repeated sfixed32 packed_sfixed32_extension_lite = 98 [packed = true]; + repeated sfixed64 packed_sfixed64_extension_lite = 99 [packed = true]; + repeated float packed_float_extension_lite = 100 [packed = true]; + repeated double packed_double_extension_lite = 101 [packed = true]; + repeated bool packed_bool_extension_lite = 102 [packed = true]; + repeated ForeignEnumLite packed_enum_extension_lite = 103 [packed = true]; +} + +message TestNestedExtensionLite { + extend TestAllExtensionsLite { + optional int32 nested_extension = 12345; + } +} + +// Test that deprecated fields work. We only verify that they compile (at one +// point this failed). +message TestDeprecatedLite { + optional int32 deprecated_field = 1 [deprecated = true]; +} diff --git a/src/google/protobuf/unittest_lite_imports_nonlite.proto b/src/google/protobuf/unittest_lite_imports_nonlite.proto new file mode 100644 index 00000000..d52cb8cc --- /dev/null +++ b/src/google/protobuf/unittest_lite_imports_nonlite.proto @@ -0,0 +1,43 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// Tests that a "lite" message can import a regular message. + +package protobuf_unittest; + +import "google/protobuf/unittest.proto"; + +option optimize_for = LITE_RUNTIME; + +message TestLiteImportsNonlite { + optional TestAllTypes message = 1; +} diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index dbd39b83..5aa67727 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -36,20 +36,24 @@ #include #include -#include +#include #include #include +#include #include #include #include #include #include + namespace google { namespace protobuf { namespace internal { +using internal::WireFormatLite; + namespace { // This function turns out to be convenient when using some macros later. @@ -57,74 +61,42 @@ inline int GetEnumNumber(const EnumValueDescriptor* descriptor) { return descriptor->number(); } -// These are the tags for the old MessageSet format, which was defined as: -// message MessageSet { -// repeated group Item = 1 { -// required int32 type_id = 2; -// required string message = 3; -// } -// } -const int kMessageSetItemStartTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(1, WireFormat::WIRETYPE_START_GROUP); -const int kMessageSetItemEndTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(1, WireFormat::WIRETYPE_END_GROUP); -const int kMessageSetTypeIdTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(2, WireFormat::WIRETYPE_VARINT); -const int kMessageSetMessageTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(3, WireFormat::WIRETYPE_LENGTH_DELIMITED); - -// Byte size of all tags of a MessageSet::Item combined. -static const int kMessageSetItemTagsSize = - io::CodedOutputStream::VarintSize32(kMessageSetItemStartTag) + - io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) + - io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) + - io::CodedOutputStream::VarintSize32(kMessageSetMessageTag); - } // anonymous namespace -const WireFormat::WireType -WireFormat::kWireTypeForFieldType[FieldDescriptor::MAX_TYPE + 1] = { - static_cast(-1), // invalid - WIRETYPE_FIXED64, // TYPE_DOUBLE - WIRETYPE_FIXED32, // TYPE_FLOAT - WIRETYPE_VARINT, // TYPE_INT64 - WIRETYPE_VARINT, // TYPE_UINT64 - WIRETYPE_VARINT, // TYPE_INT32 - WIRETYPE_FIXED64, // TYPE_FIXED64 - WIRETYPE_FIXED32, // TYPE_FIXED32 - WIRETYPE_VARINT, // TYPE_BOOL - WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING - WIRETYPE_START_GROUP, // TYPE_GROUP - WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE - WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES - WIRETYPE_VARINT, // TYPE_UINT32 - WIRETYPE_VARINT, // TYPE_ENUM - WIRETYPE_FIXED32, // TYPE_SFIXED32 - WIRETYPE_FIXED64, // TYPE_SFIXED64 - WIRETYPE_VARINT, // TYPE_SINT32 - WIRETYPE_VARINT, // TYPE_SINT64 -}; - // =================================================================== +bool UnknownFieldSetFieldSkipper::SkipField( + io::CodedInputStream* input, uint32 tag) { + return WireFormat::SkipField(input, tag, unknown_fields_); +} + +bool UnknownFieldSetFieldSkipper::SkipMessage(io::CodedInputStream* input) { + return WireFormat::SkipMessage(input, unknown_fields_); +} + +void UnknownFieldSetFieldSkipper::SkipUnknownEnum( + int field_number, int value) { + unknown_fields_->AddVarint(field_number, value); +} + bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag, UnknownFieldSet* unknown_fields) { - int number = GetTagFieldNumber(tag); + int number = WireFormatLite::GetTagFieldNumber(tag); - switch (GetTagWireType(tag)) { - case WIRETYPE_VARINT: { + switch (WireFormatLite::GetTagWireType(tag)) { + case WireFormatLite::WIRETYPE_VARINT: { uint64 value; if (!input->ReadVarint64(&value)) return false; if (unknown_fields != NULL) unknown_fields->AddVarint(number, value); return true; } - case WIRETYPE_FIXED64: { + case WireFormatLite::WIRETYPE_FIXED64: { uint64 value; if (!input->ReadLittleEndian64(&value)) return false; if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value); return true; } - case WIRETYPE_LENGTH_DELIMITED: { + case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { uint32 length; if (!input->ReadVarint32(&length)) return false; if (unknown_fields == NULL) { @@ -137,7 +109,7 @@ bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag, } return true; } - case WIRETYPE_START_GROUP: { + case WireFormatLite::WIRETYPE_START_GROUP: { if (!input->IncrementRecursionDepth()) return false; if (!SkipMessage(input, (unknown_fields == NULL) ? NULL : unknown_fields->AddGroup(number))) { @@ -145,16 +117,17 @@ bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag, } input->DecrementRecursionDepth(); // Check that the ending tag matched the starting tag. - if (!input->LastTagWas( - MakeTag(GetTagFieldNumber(tag), WIRETYPE_END_GROUP))) { + if (!input->LastTagWas(WireFormatLite::MakeTag( + WireFormatLite::GetTagFieldNumber(tag), + WireFormatLite::WIRETYPE_END_GROUP))) { return false; } return true; } - case WIRETYPE_END_GROUP: { + case WireFormatLite::WIRETYPE_END_GROUP: { return false; } - case WIRETYPE_FIXED32: { + case WireFormatLite::WIRETYPE_FIXED32: { uint32 value; if (!input->ReadLittleEndian32(&value)) return false; if (unknown_fields != NULL) unknown_fields->AddFixed32(number, value); @@ -175,9 +148,9 @@ bool WireFormat::SkipMessage(io::CodedInputStream* input, return true; } - WireType wire_type = GetTagWireType(tag); + WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); - if (wire_type == WIRETYPE_END_GROUP) { + if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { // Must be the end of the message. return true; } @@ -192,27 +165,32 @@ void WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields, const UnknownField& field = unknown_fields.field(i); switch (field.type()) { case UnknownField::TYPE_VARINT: - output->WriteVarint32(MakeTag(field.number(), WIRETYPE_VARINT)); + output->WriteVarint32(WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_VARINT)); output->WriteVarint64(field.varint()); break; case UnknownField::TYPE_FIXED32: - output->WriteVarint32(MakeTag(field.number(), WIRETYPE_FIXED32)); + output->WriteVarint32(WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_FIXED32)); output->WriteLittleEndian32(field.fixed32()); break; case UnknownField::TYPE_FIXED64: - output->WriteVarint32(MakeTag(field.number(), WIRETYPE_FIXED64)); + output->WriteVarint32(WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_FIXED64)); output->WriteLittleEndian64(field.fixed64()); break; case UnknownField::TYPE_LENGTH_DELIMITED: - output->WriteVarint32( - MakeTag(field.number(), WIRETYPE_LENGTH_DELIMITED)); + output->WriteVarint32(WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); output->WriteVarint32(field.length_delimited().size()); output->WriteString(field.length_delimited()); break; case UnknownField::TYPE_GROUP: - output->WriteVarint32(MakeTag(field.number(),WIRETYPE_START_GROUP)); + output->WriteVarint32(WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_START_GROUP)); SerializeUnknownFields(field.group(), output); - output->WriteVarint32(MakeTag(field.number(), WIRETYPE_END_GROUP)); + output->WriteVarint32(WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_END_GROUP)); break; } } @@ -226,22 +204,27 @@ uint8* WireFormat::SerializeUnknownFieldsToArray( switch (field.type()) { case UnknownField::TYPE_VARINT: - target = WriteInt64ToArray(field.number(), field.varint(), target); + target = WireFormatLite::WriteInt64ToArray( + field.number(), field.varint(), target); break; case UnknownField::TYPE_FIXED32: - target = WriteFixed32ToArray(field.number(), field.fixed32(), target); + target = WireFormatLite::WriteFixed32ToArray( + field.number(), field.fixed32(), target); break; case UnknownField::TYPE_FIXED64: - target = WriteFixed64ToArray(field.number(), field.fixed64(), target); + target = WireFormatLite::WriteFixed64ToArray( + field.number(), field.fixed64(), target); break; case UnknownField::TYPE_LENGTH_DELIMITED: - target = - WriteBytesToArray(field.number(), field.length_delimited(), target); + target = WireFormatLite::WriteBytesToArray( + field.number(), field.length_delimited(), target); break; case UnknownField::TYPE_GROUP: - target = WriteTagToArray(field.number(), WIRETYPE_START_GROUP, target); + target = WireFormatLite::WriteTagToArray( + field.number(), WireFormatLite::WIRETYPE_START_GROUP, target); target = SerializeUnknownFieldsToArray(field.group(), target); - target = WriteTagToArray(field.number(), WIRETYPE_END_GROUP, target); + target = WireFormatLite::WriteTagToArray( + field.number(), WireFormatLite::WIRETYPE_END_GROUP, target); break; } } @@ -259,19 +242,19 @@ void WireFormat::SerializeUnknownMessageSetItems( const string& data = field.length_delimited(); // Start group. - output->WriteVarint32(kMessageSetItemStartTag); + output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag); // Write type ID. - output->WriteVarint32(kMessageSetTypeIdTag); + output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag); output->WriteVarint32(field.number()); // Write message. - output->WriteVarint32(kMessageSetMessageTag); + output->WriteVarint32(WireFormatLite::kMessageSetMessageTag); output->WriteVarint32(data.size()); output->WriteString(data); // End group. - output->WriteVarint32(kMessageSetItemEndTag); + output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag); } } } @@ -288,24 +271,24 @@ uint8* WireFormat::SerializeUnknownMessageSetItemsToArray( const string& data = field.length_delimited(); // Start group. - target = - io::CodedOutputStream::WriteTagToArray(kMessageSetItemStartTag, target); + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemStartTag, target); // Write type ID. - target = - io::CodedOutputStream::WriteTagToArray(kMessageSetTypeIdTag, target); - target = - io::CodedOutputStream::WriteVarint32ToArray(field.number(), target); + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetTypeIdTag, target); + target = io::CodedOutputStream::WriteVarint32ToArray( + field.number(), target); // Write message. - target = - io::CodedOutputStream::WriteTagToArray(kMessageSetMessageTag, target); + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetMessageTag, target); target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target); target = io::CodedOutputStream::WriteStringToArray(data, target); // End group. - target = - io::CodedOutputStream::WriteTagToArray(kMessageSetItemEndTag, target); + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemEndTag, target); } } @@ -321,32 +304,38 @@ int WireFormat::ComputeUnknownFieldsSize( switch (field.type()) { case UnknownField::TYPE_VARINT: size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_VARINT)); + WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_VARINT)); size += io::CodedOutputStream::VarintSize64(field.varint()); break; case UnknownField::TYPE_FIXED32: size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_FIXED32)); + WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_FIXED32)); size += sizeof(int32); break; case UnknownField::TYPE_FIXED64: size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_FIXED64)); + WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_FIXED64)); size += sizeof(int64); break; case UnknownField::TYPE_LENGTH_DELIMITED: size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_LENGTH_DELIMITED)); + WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); size += io::CodedOutputStream::VarintSize32( - field.length_delimited().size()); + field.length_delimited().size()); size += field.length_delimited().size(); break; case UnknownField::TYPE_GROUP: size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_START_GROUP)); + WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_START_GROUP)); size += ComputeUnknownFieldsSize(field.group()); size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_END_GROUP)); + WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_END_GROUP)); break; } } @@ -363,7 +352,7 @@ int WireFormat::ComputeUnknownMessageSetItemsSize( // The only unknown fields that are allowed to exist in a MessageSet are // messages, which are length-delimited. if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { - size += kMessageSetItemTagsSize; + size += WireFormatLite::kMessageSetItemTagsSize; size += io::CodedOutputStream::VarintSize32(field.number()); size += io::CodedOutputStream::VarintSize32( field.length_delimited().size()); @@ -388,7 +377,8 @@ bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input, return true; } - if (GetTagWireType(tag) == WIRETYPE_END_GROUP) { + if (WireFormatLite::GetTagWireType(tag) == + WireFormatLite::WIRETYPE_END_GROUP) { // Must be the end of the message. return true; } @@ -396,7 +386,7 @@ bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input, const FieldDescriptor* field = NULL; if (descriptor != NULL) { - int field_number = GetTagFieldNumber(tag); + int field_number = WireFormatLite::GetTagFieldNumber(tag); field = descriptor->FindFieldByNumber(field_number); // If that failed, check if the field is an extension. @@ -408,7 +398,7 @@ bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input, // MessageSet item, then parse that. if (field == NULL && descriptor->options().message_set_wire_format() && - tag == kMessageSetItemStartTag) { + tag == WireFormatLite::kMessageSetItemStartTag) { if (!ParseAndMergeMessageSetItem(input, message)) { return false; } @@ -430,7 +420,7 @@ bool WireFormat::ParseAndMergeField( const Reflection* message_reflection = message->GetReflection(); if (field == NULL || - GetTagWireType(tag) != WireTypeForField(field)) { + WireFormatLite::GetTagWireType(tag) != WireTypeForField(field)) { // We don't recognize this field. Either the field number is unknown // or the wire type doesn't match. Put it in our unknown field set. return SkipField(input, tag, @@ -443,14 +433,14 @@ bool WireFormat::ParseAndMergeField( io::CodedInputStream::Limit limit = input->PushLimit(length); switch (field->type()) { -#define HANDLE_PACKED_TYPE(TYPE, TYPE_METHOD, CPPTYPE, CPPTYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: { \ - while (input->BytesUntilLimit() > 0) { \ - CPPTYPE value; \ - if (!Read##TYPE_METHOD(input, &value)) return false; \ - message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ - } \ - break; \ +#define HANDLE_PACKED_TYPE(TYPE, TYPE_METHOD, CPPTYPE, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + while (input->BytesUntilLimit() > 0) { \ + CPPTYPE value; \ + if (!WireFormatLite::Read##TYPE_METHOD(input, &value)) return false; \ + message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ + } \ + break; \ } HANDLE_PACKED_TYPE( INT32, Int32, int32, Int32) @@ -474,7 +464,7 @@ bool WireFormat::ParseAndMergeField( case FieldDescriptor::TYPE_ENUM: { while (input->BytesUntilLimit() > 0) { int value; - if (!ReadEnum(input, &value)) return false; + if (!WireFormatLite::ReadEnum(input, &value)) return false; const EnumValueDescriptor* enum_value = field->enum_type()->FindValueByNumber(value); if (enum_value != NULL) { @@ -498,16 +488,16 @@ bool WireFormat::ParseAndMergeField( input->PopLimit(limit); } else { switch (field->type()) { -#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE, CPPTYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: { \ - CPPTYPE value; \ - if (!Read##TYPE_METHOD(input, &value)) return false; \ - if (field->is_repeated()) { \ - message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ - } else { \ - message_reflection->Set##CPPTYPE_METHOD(message, field, value); \ - } \ - break; \ +#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + CPPTYPE value; \ + if (!WireFormatLite::Read##TYPE_METHOD(input, &value)) return false; \ + if (field->is_repeated()) { \ + message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ + } else { \ + message_reflection->Set##CPPTYPE_METHOD(message, field, value); \ + } \ + break; \ } HANDLE_TYPE( INT32, Int32, int32, Int32) @@ -534,7 +524,7 @@ bool WireFormat::ParseAndMergeField( case FieldDescriptor::TYPE_ENUM: { int value; - if (!ReadEnum(input, &value)) return false; + if (!WireFormatLite::ReadEnum(input, &value)) return false; const EnumValueDescriptor* enum_value = field->enum_type()->FindValueByNumber(value); if (enum_value != NULL) { @@ -548,7 +538,7 @@ bool WireFormat::ParseAndMergeField( // UnknownFieldSet. int64 sign_extended_value = static_cast(value); message_reflection->MutableUnknownFields(message) - ->AddVarint(GetTagFieldNumber(tag), + ->AddVarint(WireFormatLite::GetTagFieldNumber(tag), sign_extended_value); } break; @@ -563,7 +553,8 @@ bool WireFormat::ParseAndMergeField( sub_message = message_reflection->MutableMessage(message, field); } - if (!ReadGroup(GetTagFieldNumber(tag), input, sub_message)) + if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag), + input, sub_message)) return false; break; } @@ -576,7 +567,7 @@ bool WireFormat::ParseAndMergeField( sub_message = message_reflection->MutableMessage(message, field); } - if (!ReadMessage(input, sub_message)) return false; + if (!WireFormatLite::ReadMessage(input, sub_message)) return false; break; } } @@ -615,10 +606,11 @@ bool WireFormat::ParseAndMergeMessageSetItem( if (tag == 0) return false; switch (tag) { - case kMessageSetTypeIdTag: { + case WireFormatLite::kMessageSetTypeIdTag: { uint32 type_id; if (!input->ReadVarint32(&type_id)) return false; - fake_tag = MakeTag(type_id, WIRETYPE_LENGTH_DELIMITED); + fake_tag = WireFormatLite::MakeTag( + type_id, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); field = message_reflection->FindKnownExtensionByNumber(type_id); if (!message_data.empty()) { @@ -637,7 +629,7 @@ bool WireFormat::ParseAndMergeMessageSetItem( break; } - case kMessageSetMessageTag: { + case WireFormatLite::kMessageSetMessageTag: { if (fake_tag == 0) { // We haven't seen a type_id yet. Append this data to message_data. string temp; @@ -655,7 +647,7 @@ bool WireFormat::ParseAndMergeMessageSetItem( break; } - case kMessageSetItemEndTag: { + case WireFormatLite::kMessageSetItemEndTag: { return true; } @@ -719,7 +711,8 @@ void WireFormat::SerializeFieldWithCachedSizes( const bool is_packed = field->options().packed(); if (is_packed && count > 0) { - WriteTag(field->number(), WIRETYPE_LENGTH_DELIMITED, output); + WireFormatLite::WriteTag(field->number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); const int data_size = FieldDataOnlyByteSize(field, message); output->WriteVarint32(data_size); } @@ -734,9 +727,9 @@ void WireFormat::SerializeFieldWithCachedSizes( message_reflection->Get##CPPTYPE_METHOD( \ message, field); \ if (is_packed) { \ - Write##TYPE_METHOD##NoTag(value, output); \ + WireFormatLite::Write##TYPE_METHOD##NoTag(value, output); \ } else { \ - Write##TYPE_METHOD(field->number(), value, output); \ + WireFormatLite::Write##TYPE_METHOD(field->number(), value, output); \ } \ break; \ } @@ -761,7 +754,7 @@ void WireFormat::SerializeFieldWithCachedSizes( #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ case FieldDescriptor::TYPE_##TYPE: \ - Write##TYPE_METHOD( \ + WireFormatLite::Write##TYPE_METHOD( \ field->number(), \ field->is_repeated() ? \ message_reflection->GetRepeated##CPPTYPE_METHOD( \ @@ -779,9 +772,9 @@ void WireFormat::SerializeFieldWithCachedSizes( message_reflection->GetRepeatedEnum(message, field, j) : message_reflection->GetEnum(message, field); if (is_packed) { - WriteEnumNoTag(value->number(), output); + WireFormatLite::WriteEnumNoTag(value->number(), output); } else { - WriteEnum(field->number(), value->number(), output); + WireFormatLite::WriteEnum(field->number(), value->number(), output); } break; } @@ -794,7 +787,8 @@ void WireFormat::SerializeFieldWithCachedSizes( message_reflection->GetRepeatedStringReference( message, field, j, &scratch) : message_reflection->GetStringReference(message, field, &scratch); - WriteString(field->number(), value, output); + VerifyUTF8String(value.data(), value.length(), SERIALIZE); + WireFormatLite::WriteString(field->number(), value, output); break; } @@ -804,7 +798,7 @@ void WireFormat::SerializeFieldWithCachedSizes( message_reflection->GetRepeatedStringReference( message, field, j, &scratch) : message_reflection->GetStringReference(message, field, &scratch); - WriteBytes(field->number(), value, output); + WireFormatLite::WriteBytes(field->number(), value, output); break; } } @@ -818,21 +812,21 @@ void WireFormat::SerializeMessageSetItemWithCachedSizes( const Reflection* message_reflection = message.GetReflection(); // Start group. - output->WriteVarint32(kMessageSetItemStartTag); + output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag); // Write type ID. - output->WriteVarint32(kMessageSetTypeIdTag); + output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag); output->WriteVarint32(field->number()); // Write message. - output->WriteVarint32(kMessageSetMessageTag); + output->WriteVarint32(WireFormatLite::kMessageSetMessageTag); const Message& sub_message = message_reflection->GetMessage(message, field); output->WriteVarint32(sub_message.GetCachedSize()); sub_message.SerializeWithCachedSizes(output); // End group. - output->WriteVarint32(kMessageSetItemEndTag); + output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag); } // =================================================================== @@ -913,19 +907,19 @@ int WireFormat::FieldDataOnlyByteSize( case FieldDescriptor::TYPE_##TYPE: \ if (field->is_repeated()) { \ for (int j = 0; j < count; j++) { \ - data_size += TYPE_METHOD##Size( \ + data_size += WireFormatLite::TYPE_METHOD##Size( \ message_reflection->GetRepeated##CPPTYPE_METHOD( \ message, field, j)); \ } \ } else { \ - data_size += TYPE_METHOD##Size( \ + data_size += WireFormatLite::TYPE_METHOD##Size( \ message_reflection->Get##CPPTYPE_METHOD(message, field)); \ } \ break; #define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD) \ case FieldDescriptor::TYPE_##TYPE: \ - data_size += count * k##TYPE_METHOD##Size; \ + data_size += count * WireFormatLite::k##TYPE_METHOD##Size; \ break; HANDLE_TYPE( INT32, Int32, Int32) @@ -953,11 +947,11 @@ int WireFormat::FieldDataOnlyByteSize( case FieldDescriptor::TYPE_ENUM: { if (field->is_repeated()) { for (int j = 0; j < count; j++) { - data_size += EnumSize( + data_size += WireFormatLite::EnumSize( message_reflection->GetRepeatedEnum(message, field, j)->number()); } } else { - data_size += EnumSize( + data_size += WireFormatLite::EnumSize( message_reflection->GetEnum(message, field)->number()); } break; @@ -973,7 +967,7 @@ int WireFormat::FieldDataOnlyByteSize( message_reflection->GetRepeatedStringReference( message, field, j, &scratch) : message_reflection->GetStringReference(message, field, &scratch); - data_size += StringSize(value); + data_size += WireFormatLite::StringSize(value); } break; } @@ -986,7 +980,7 @@ int WireFormat::MessageSetItemByteSize( const Message& message) { const Reflection* message_reflection = message.GetReflection(); - int our_size = kMessageSetItemTagsSize; + int our_size = WireFormatLite::kMessageSetItemTagsSize; // type_id our_size += io::CodedOutputStream::VarintSize32(field->number()); @@ -1001,6 +995,28 @@ int WireFormat::MessageSetItemByteSize( return our_size; } +void WireFormat::VerifyUTF8StringFallback(const char* data, + int size, + Operation op) { + if (!IsStructurallyValidUTF8(data, size)) { + const char* operation_str = NULL; + switch (op) { + case PARSE: + operation_str = "parsing"; + break; + case SERIALIZE: + operation_str = "serializing"; + break; + // no default case: have the compiler warn if a case is not covered. + } + GOOGLE_LOG(ERROR) << "Encountered string containing invalid UTF-8 data while " + << operation_str + << " protocol buffer. Strings must contain only UTF-8; " + "use the 'bytes' type for raw bytes."; + } +} + + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h index 963f427a..c7539250 100644 --- a/src/google/protobuf/wire_format.h +++ b/src/google/protobuf/wire_format.h @@ -40,17 +40,23 @@ #define GOOGLE_PROTOBUF_WIRE_FORMAT_H__ #include -#include +#include #include +#include +#include -namespace google { +// Do UTF-8 validation on string type in Debug build only +#ifndef NDEBUG +#define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED +#endif +namespace google { namespace protobuf { namespace io { class CodedInputStream; // coded_stream.h class CodedOutputStream; // coded_stream.h } - class UnknownFieldSet; // unknown_field_set.h + class UnknownFieldSet; // unknown_field_set.h } namespace protobuf { @@ -60,13 +66,26 @@ namespace internal { // protocol-complier-generated message classes. It must not be called // directly by clients. // -// This class contains helpers for implementing the binary protocol buffer -// wire format. These helpers are called primarily by generated code. The -// class also contains reflection-based implementations of the wire format. +// This class contains code for implementing the binary protocol buffer +// wire format via reflection. The WireFormatLite class implements the +// non-reflection based routines. // -// This class is really a namespace that contains only static methods. +// This class is really a namespace that contains only static methods class LIBPROTOBUF_EXPORT WireFormat { public: + + // Given a field return its WireType + static inline WireFormatLite::WireType WireTypeForField( + const FieldDescriptor* field); + + // Given a FieldSescriptor::Type return its WireType + static inline WireFormatLite::WireType WireTypeForFieldType( + FieldDescriptor::Type type); + + // Compute the byte size of a tag. For groups, this includes both the start + // and end tags. + static inline int TagSize(int field_number, FieldDescriptor::Type type); + // These procedures can be used to implement the methods of Message which // handle parsing and serialization of the protocol buffer wire format // using only the Reflection interface. When you ask the protocol @@ -152,41 +171,6 @@ class LIBPROTOBUF_EXPORT WireFormat { static int ComputeUnknownMessageSetItemsSize( const UnknownFieldSet& unknown_fields); - // ----------------------------------------------------------------- - // Helper constants and functions related to the format. These are - // mostly meant for internal and generated code to use. - - // The wire format is composed of a sequence of tag/value pairs, each - // of which contains the value of one field (or one element of a repeated - // field). Each tag is encoded as a varint. The lower bits of the tag - // identify its wire type, which specifies the format of the data to follow. - // The rest of the bits contain the field number. Each type of field (as - // declared by FieldDescriptor::Type, in descriptor.h) maps to one of - // these wire types. Immediately following each tag is the field's value, - // encoded in the format specified by the wire type. Because the tag - // identifies the encoding of this data, it is possible to skip - // unrecognized fields for forwards compatibility. - - enum WireType { - WIRETYPE_VARINT = 0, - WIRETYPE_FIXED64 = 1, - WIRETYPE_LENGTH_DELIMITED = 2, - WIRETYPE_START_GROUP = 3, - WIRETYPE_END_GROUP = 4, - WIRETYPE_FIXED32 = 5, - }; - - static inline WireType WireTypeForFieldType(FieldDescriptor::Type type) { - return kWireTypeForFieldType[type]; - } - // This is different from WireTypeForFieldType(field->type()) in the case of - // packed repeated fields. - static inline WireType WireTypeForField(const FieldDescriptor* field); - - // Number of bits in a tag which identify the wire type. - static const int kTagTypeBits = 3; - // Mask for those bits. - static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1; // Helper functions for encoding and decoding tags. (Inlined below and in // _inl.h) @@ -194,28 +178,6 @@ class LIBPROTOBUF_EXPORT WireFormat { // This is different from MakeTag(field->number(), field->type()) in the case // of packed repeated fields. static uint32 MakeTag(const FieldDescriptor* field); - static uint32 MakeTag(int field_number, WireType type); - static WireType GetTagWireType(uint32 tag); - static int GetTagFieldNumber(uint32 tag); - - // Helper functions for converting between floats/doubles and IEEE-754 - // uint32s/uint64s so that they can be written. (Assumes your platform - // uses IEEE-754 floats.) - static uint32 EncodeFloat(float value); - static float DecodeFloat(uint32 value); - static uint64 EncodeDouble(double value); - static double DecodeDouble(uint64 value); - - // Helper functions for mapping signed integers to unsigned integers in - // such a way that numbers with small magnitudes will encode to smaller - // varints. If you simply static_cast a negative number to an unsigned - // number and varint-encode it, it will always take 10 bytes, defeating - // the purpose of varint. So, for the "sint32" and "sint64" field types, - // we ZigZag-encode the values. - static uint32 ZigZagEncode32(int32 n); - static int32 ZigZagDecode32(uint32 n); - static uint64 ZigZagEncode64(int64 n); - static int64 ZigZagDecode64(uint64 n); // Parse a single field. The input should start out positioned immidately // after the tag. @@ -238,223 +200,6 @@ class LIBPROTOBUF_EXPORT WireFormat { const FieldDescriptor* field, // Cannot be NULL const Message& message); - // ================================================================= - // Methods for reading/writing individual field. The implementations - // of these methods are defined in wire_format_inl.h; you must #include - // that file to use these. - -// Avoid ugly line wrapping -#define input io::CodedInputStream* input -#define output io::CodedOutputStream* output -#define field_number int field_number -#define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE - - // Read fields, not including tags. The assumption is that you already - // read the tag to determine what field to read. - static inline bool ReadInt32 (input, int32* value); - static inline bool ReadInt64 (input, int64* value); - static inline bool ReadUInt32 (input, uint32* value); - static inline bool ReadUInt64 (input, uint64* value); - static inline bool ReadSInt32 (input, int32* value); - static inline bool ReadSInt64 (input, int64* value); - static inline bool ReadFixed32 (input, uint32* value); - static inline bool ReadFixed64 (input, uint64* value); - static inline bool ReadSFixed32(input, int32* value); - static inline bool ReadSFixed64(input, int64* value); - static inline bool ReadFloat (input, float* value); - static inline bool ReadDouble (input, double* value); - static inline bool ReadBool (input, bool* value); - static inline bool ReadEnum (input, int* value); - - static inline bool ReadString(input, string* value); - static inline bool ReadBytes (input, string* value); - - static inline bool ReadGroup (field_number, input, Message* value); - static inline bool ReadMessage(input, Message* value); - - // Like above, but de-virtualize the call to MergePartialFromCodedStream(). - // The pointer must point at an instance of MessageType, *not* a subclass (or - // the subclass must not override MergePartialFromCodedStream()). - template - static inline bool ReadGroupNoVirtual(field_number, input, - MessageType* value); - template - static inline bool ReadMessageNoVirtual(input, MessageType* value); - - // Write a tag. The Write*() functions typically include the tag, so - // normally there's no need to call this unless using the Write*NoTag() - // variants. - static inline void WriteTag(field_number, WireType type, output) INL; - - // Write fields, without tags. - static inline void WriteInt32NoTag (int32 value, output) INL; - static inline void WriteInt64NoTag (int64 value, output) INL; - static inline void WriteUInt32NoTag (uint32 value, output) INL; - static inline void WriteUInt64NoTag (uint64 value, output) INL; - static inline void WriteSInt32NoTag (int32 value, output) INL; - static inline void WriteSInt64NoTag (int64 value, output) INL; - static inline void WriteFixed32NoTag (uint32 value, output) INL; - static inline void WriteFixed64NoTag (uint64 value, output) INL; - static inline void WriteSFixed32NoTag(int32 value, output) INL; - static inline void WriteSFixed64NoTag(int64 value, output) INL; - static inline void WriteFloatNoTag (float value, output) INL; - static inline void WriteDoubleNoTag (double value, output) INL; - static inline void WriteBoolNoTag (bool value, output) INL; - static inline void WriteEnumNoTag (int value, output) INL; - - // Write fields, including tags. - static inline void WriteInt32 (field_number, int32 value, output) INL; - static inline void WriteInt64 (field_number, int64 value, output) INL; - static inline void WriteUInt32 (field_number, uint32 value, output) INL; - static inline void WriteUInt64 (field_number, uint64 value, output) INL; - static inline void WriteSInt32 (field_number, int32 value, output) INL; - static inline void WriteSInt64 (field_number, int64 value, output) INL; - static inline void WriteFixed32 (field_number, uint32 value, output) INL; - static inline void WriteFixed64 (field_number, uint64 value, output) INL; - static inline void WriteSFixed32(field_number, int32 value, output) INL; - static inline void WriteSFixed64(field_number, int64 value, output) INL; - static inline void WriteFloat (field_number, float value, output) INL; - static inline void WriteDouble (field_number, double value, output) INL; - static inline void WriteBool (field_number, bool value, output) INL; - static inline void WriteEnum (field_number, int value, output) INL; - - static inline void WriteString(field_number, const string& value, output) INL; - static inline void WriteBytes (field_number, const string& value, output) INL; - - static inline void WriteGroup(field_number, const Message& value, output) INL; - static inline void WriteMessage( - field_number, const Message& value, output) INL; - - // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The - // pointer must point at an instance of MessageType, *not* a subclass (or - // the subclass must not override SerializeWithCachedSizes()). - template - static inline void WriteGroupNoVirtual( - field_number, const MessageType& value, output) INL; - template - static inline void WriteMessageNoVirtual( - field_number, const MessageType& value, output) INL; - -#undef output -#define output uint8* target - - // Like above, but use only *ToArray methods of CodedOutputStream. - static inline uint8* WriteTagToArray(field_number, WireType type, output) INL; - - // Write fields, without tags. - static inline uint8* WriteInt32NoTagToArray (int32 value, output) INL; - static inline uint8* WriteInt64NoTagToArray (int64 value, output) INL; - static inline uint8* WriteUInt32NoTagToArray (uint32 value, output) INL; - static inline uint8* WriteUInt64NoTagToArray (uint64 value, output) INL; - static inline uint8* WriteSInt32NoTagToArray (int32 value, output) INL; - static inline uint8* WriteSInt64NoTagToArray (int64 value, output) INL; - static inline uint8* WriteFixed32NoTagToArray (uint32 value, output) INL; - static inline uint8* WriteFixed64NoTagToArray (uint64 value, output) INL; - static inline uint8* WriteSFixed32NoTagToArray(int32 value, output) INL; - static inline uint8* WriteSFixed64NoTagToArray(int64 value, output) INL; - static inline uint8* WriteFloatNoTagToArray (float value, output) INL; - static inline uint8* WriteDoubleNoTagToArray (double value, output) INL; - static inline uint8* WriteBoolNoTagToArray (bool value, output) INL; - static inline uint8* WriteEnumNoTagToArray (int value, output) INL; - - // Write fields, including tags. - static inline uint8* WriteInt32ToArray( - field_number, int32 value, output) INL; - static inline uint8* WriteInt64ToArray( - field_number, int64 value, output) INL; - static inline uint8* WriteUInt32ToArray( - field_number, uint32 value, output) INL; - static inline uint8* WriteUInt64ToArray( - field_number, uint64 value, output) INL; - static inline uint8* WriteSInt32ToArray( - field_number, int32 value, output) INL; - static inline uint8* WriteSInt64ToArray( - field_number, int64 value, output) INL; - static inline uint8* WriteFixed32ToArray( - field_number, uint32 value, output) INL; - static inline uint8* WriteFixed64ToArray( - field_number, uint64 value, output) INL; - static inline uint8* WriteSFixed32ToArray( - field_number, int32 value, output) INL; - static inline uint8* WriteSFixed64ToArray( - field_number, int64 value, output) INL; - static inline uint8* WriteFloatToArray( - field_number, float value, output) INL; - static inline uint8* WriteDoubleToArray( - field_number, double value, output) INL; - static inline uint8* WriteBoolToArray( - field_number, bool value, output) INL; - static inline uint8* WriteEnumToArray( - field_number, int value, output) INL; - - static inline uint8* WriteStringToArray( - field_number, const string& value, output) INL; - static inline uint8* WriteBytesToArray( - field_number, const string& value, output) INL; - - static inline uint8* WriteGroupToArray( - field_number, const Message& value, output) INL; - static inline uint8* WriteMessageToArray( - field_number, const Message& value, output) INL; - - // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The - // pointer must point at an instance of MessageType, *not* a subclass (or - // the subclass must not override SerializeWithCachedSizes()). - template - static inline uint8* WriteGroupNoVirtualToArray( - field_number, const MessageType& value, output) INL; - template - static inline uint8* WriteMessageNoVirtualToArray( - field_number, const MessageType& value, output) INL; - -#undef output -#undef input -#undef INL - - // Compute the byte size of a tag. For groups, this includes both the start - // and end tags. - static inline int TagSize(field_number, FieldDescriptor::Type type); - -#undef field_number - - // Compute the byte size of a field. The XxSize() functions do NOT include - // the tag, so you must also call TagSize(). (This is because, for repeated - // fields, you should only call TagSize() once and multiply it by the element - // count, but you may have to call XxSize() for each individual element.) - static inline int Int32Size ( int32 value); - static inline int Int64Size ( int64 value); - static inline int UInt32Size (uint32 value); - static inline int UInt64Size (uint64 value); - static inline int SInt32Size ( int32 value); - static inline int SInt64Size ( int64 value); - static inline int EnumSize ( int value); - - // These types always have the same size. - static const int kFixed32Size = 4; - static const int kFixed64Size = 8; - static const int kSFixed32Size = 4; - static const int kSFixed64Size = 8; - static const int kFloatSize = 4; - static const int kDoubleSize = 8; - static const int kBoolSize = 1; - - static inline int StringSize(const string& value); - static inline int BytesSize (const string& value); - - static inline int GroupSize (const Message& value); - static inline int MessageSize(const Message& value); - - // Like above, but de-virtualize the call to ByteSize(). The - // pointer must point at an instance of MessageType, *not* a subclass (or - // the subclass must not override ByteSize()). - template - static inline int GroupSizeNoVirtual (const MessageType& value); - template - static inline int MessageSizeNoVirtual(const MessageType& value); - - private: - static const WireType kWireTypeForFieldType[]; - // Parse/serialize a MessageSet::Item group. Used with messages that use // opion message_set_wire_format = true. static bool ParseAndMergeMessageSetItem( @@ -476,97 +221,82 @@ class LIBPROTOBUF_EXPORT WireFormat { const FieldDescriptor* field, // Cannot be NULL const Message& message); - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat); -}; + enum Operation { + PARSE, + SERIALIZE, + }; -// inline methods ==================================================== + // Verifies that a string field is valid UTF8, logging an error if not. + static void VerifyUTF8String(const char* data, int size, Operation op); -// This macro does the same thing as WireFormat::MakeTag(), but the -// result is usable as a compile-time constant, which makes it usable -// as a switch case or a template input. WireFormat::MakeTag() is more -// type-safe, though, so prefer it if possible. -#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \ - static_cast( \ - ((FIELD_NUMBER) << ::google::protobuf::internal::WireFormat::kTagTypeBits) | (TYPE)) + private: + // Verifies that a string field is valid UTF8, logging an error if not. + static void VerifyUTF8StringFallback( + const char* data, + int size, + Operation op); -inline uint32 WireFormat::MakeTag(int field_number, WireType type) { - return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type); -} -inline WireFormat::WireType WireFormat::GetTagWireType(uint32 tag) { - return static_cast(tag & kTagTypeMask); -} -inline int WireFormat::GetTagFieldNumber(uint32 tag) { - return static_cast(tag >> kTagTypeBits); -} + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat); +}; -inline uint32 WireFormat::EncodeFloat(float value) { - union {float f; uint32 i;}; - f = value; - return i; -} +// Subclass of FieldSkipper which saves skipped fields to an UnknownFieldSet. +class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper { + public: + UnknownFieldSetFieldSkipper(UnknownFieldSet* unknown_fields) + : unknown_fields_(unknown_fields) {} + virtual ~UnknownFieldSetFieldSkipper() {} -inline float WireFormat::DecodeFloat(uint32 value) { - union {float f; uint32 i;}; - i = value; - return f; -} + // implements FieldSkipper ----------------------------------------- + virtual bool SkipField(io::CodedInputStream* input, uint32 tag); + virtual bool SkipMessage(io::CodedInputStream* input); + virtual void SkipUnknownEnum(int field_number, int value); -inline uint64 WireFormat::EncodeDouble(double value) { - union {double f; uint64 i;}; - f = value; - return i; -} + private: + UnknownFieldSet* unknown_fields_; +}; -inline double WireFormat::DecodeDouble(uint64 value) { - union {double f; uint64 i;}; - i = value; - return f; -} +// inline methods ==================================================== -// ZigZag Transform: Encodes signed integers so that they can be -// effectively used with varint encoding. -// -// varint operates on unsigned integers, encoding smaller numbers into -// fewer bytes. If you try to use it on a signed integer, it will treat -// this number as a very large unsigned integer, which means that even -// small signed numbers like -1 will take the maximum number of bytes -// (10) to encode. ZigZagEncode() maps signed integers to unsigned -// in such a way that those with a small absolute value will have smaller -// encoded values, making them appropriate for encoding using varint. -// -// int32 -> uint32 -// ------------------------- -// 0 -> 0 -// -1 -> 1 -// 1 -> 2 -// -2 -> 3 -// ... -> ... -// 2147483647 -> 4294967294 -// -2147483648 -> 4294967295 -// -// >> encode >> -// << decode << +inline WireFormatLite::WireType WireFormat::WireTypeForField( + const FieldDescriptor* field) { + if (field->options().packed()) { + return WireFormatLite::WIRETYPE_LENGTH_DELIMITED; + } else { + return WireTypeForFieldType(field->type()); + } +} -inline uint32 WireFormat::ZigZagEncode32(int32 n) { - // Note: the right-shift must be arithmetic - return (n << 1) ^ (n >> 31); +inline WireFormatLite::WireType WireFormat::WireTypeForFieldType( + FieldDescriptor::Type type) { + // Some compilers don't like enum -> enum casts, so we implicit_cast to + // int first. + return WireFormatLite::WireTypeForFieldType( + static_cast( + implicit_cast(type))); } -inline int32 WireFormat::ZigZagDecode32(uint32 n) { - return (n >> 1) ^ -static_cast(n & 1); +inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) { + return WireFormatLite::MakeTag(field->number(), WireTypeForField(field)); } -inline uint64 WireFormat::ZigZagEncode64(int64 n) { - // Note: the right-shift must be arithmetic - return (n << 1) ^ (n >> 63); +inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) { + // Some compilers don't like enum -> enum casts, so we implicit_cast to + // int first. + return WireFormatLite::TagSize(field_number, + static_cast( + implicit_cast(type))); } -inline int64 WireFormat::ZigZagDecode64(uint64 n) { - return (n >> 1) ^ -static_cast(n & 1); +inline void WireFormat::VerifyUTF8String(const char* data, int size, + WireFormat::Operation op) { +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + WireFormat::VerifyUTF8StringFallback(data, size, op); +#endif } + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/wire_format_inl.h b/src/google/protobuf/wire_format_inl.h deleted file mode 100644 index 69256080..00000000 --- a/src/google/protobuf/wire_format_inl.h +++ /dev/null @@ -1,687 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_INL_H__ -#define GOOGLE_PROTOBUF_WIRE_FORMAT_INL_H__ - -#include -#include -#include -#include -#include -#include - - -// Do UTF-8 validation on string type in Debug build only -#ifndef NDEBUG -#define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED -#endif - - -namespace google { -namespace protobuf { -namespace internal { - -inline WireFormat::WireType WireFormat::WireTypeForField( - const FieldDescriptor* field) { - if (field->options().packed()) { - return WIRETYPE_LENGTH_DELIMITED; - } else { - return WireTypeForFieldType(field->type()); - } -} - -inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) { - return MakeTag(field->number(), WireTypeForField(field)); -} - -inline bool WireFormat::ReadInt32(io::CodedInputStream* input, int32* value) { - uint32 temp; - if (!input->ReadVarint32(&temp)) return false; - *value = static_cast(temp); - return true; -} -inline bool WireFormat::ReadInt64(io::CodedInputStream* input, int64* value) { - uint64 temp; - if (!input->ReadVarint64(&temp)) return false; - *value = static_cast(temp); - return true; -} -inline bool WireFormat::ReadUInt32(io::CodedInputStream* input, uint32* value) { - return input->ReadVarint32(value); -} -inline bool WireFormat::ReadUInt64(io::CodedInputStream* input, uint64* value) { - return input->ReadVarint64(value); -} -inline bool WireFormat::ReadSInt32(io::CodedInputStream* input, int32* value) { - uint32 temp; - if (!input->ReadVarint32(&temp)) return false; - *value = ZigZagDecode32(temp); - return true; -} -inline bool WireFormat::ReadSInt64(io::CodedInputStream* input, int64* value) { - uint64 temp; - if (!input->ReadVarint64(&temp)) return false; - *value = ZigZagDecode64(temp); - return true; -} -inline bool WireFormat::ReadFixed32(io::CodedInputStream* input, - uint32* value) { - return input->ReadLittleEndian32(value); -} -inline bool WireFormat::ReadFixed64(io::CodedInputStream* input, - uint64* value) { - return input->ReadLittleEndian64(value); -} -inline bool WireFormat::ReadSFixed32(io::CodedInputStream* input, - int32* value) { - uint32 temp; - if (!input->ReadLittleEndian32(&temp)) return false; - *value = static_cast(temp); - return true; -} -inline bool WireFormat::ReadSFixed64(io::CodedInputStream* input, - int64* value) { - uint64 temp; - if (!input->ReadLittleEndian64(&temp)) return false; - *value = static_cast(temp); - return true; -} -inline bool WireFormat::ReadFloat(io::CodedInputStream* input, float* value) { - uint32 temp; - if (!input->ReadLittleEndian32(&temp)) return false; - *value = DecodeFloat(temp); - return true; -} -inline bool WireFormat::ReadDouble(io::CodedInputStream* input, double* value) { - uint64 temp; - if (!input->ReadLittleEndian64(&temp)) return false; - *value = DecodeDouble(temp); - return true; -} -inline bool WireFormat::ReadBool(io::CodedInputStream* input, bool* value) { - uint32 temp; - if (!input->ReadVarint32(&temp)) return false; - *value = temp != 0; - return true; -} -inline bool WireFormat::ReadEnum(io::CodedInputStream* input, int* value) { - uint32 temp; - if (!input->ReadVarint32(&temp)) return false; - *value = static_cast(temp); - return true; -} - -inline bool WireFormat::ReadString(io::CodedInputStream* input, string* value) { - // String is for UTF-8 text only - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->ReadString(value, length)) return false; -#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - if (!IsStructurallyValidUTF8(value->data(), length)) { - GOOGLE_LOG(ERROR) << "Encountered string containing invalid UTF-8 data while " - "parsing protocol buffer. Strings must contain only UTF-8; " - "use the 'bytes' type for raw bytes."; - } -#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - return true; -} -inline bool WireFormat::ReadBytes(io::CodedInputStream* input, string* value) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - return input->ReadString(value, length); -} - - -inline bool WireFormat::ReadGroup(int field_number, - io::CodedInputStream* input, - Message* value) { - if (!input->IncrementRecursionDepth()) return false; - if (!value->MergePartialFromCodedStream(input)) return false; - input->DecrementRecursionDepth(); - // Make sure the last thing read was an end tag for this group. - if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { - return false; - } - return true; -} -inline bool WireFormat::ReadMessage(io::CodedInputStream* input, - Message* value) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->IncrementRecursionDepth()) return false; - io::CodedInputStream::Limit limit = input->PushLimit(length); - if (!value->MergePartialFromCodedStream(input)) return false; - // Make sure that parsing stopped when the limit was hit, not at an endgroup - // tag. - if (!input->ConsumedEntireMessage()) return false; - input->PopLimit(limit); - input->DecrementRecursionDepth(); - return true; -} - -template -inline bool WireFormat::ReadGroupNoVirtual(int field_number, - io::CodedInputStream* input, - MessageType* value) { - if (!input->IncrementRecursionDepth()) return false; - if (!value->MessageType::MergePartialFromCodedStream(input)) return false; - input->DecrementRecursionDepth(); - // Make sure the last thing read was an end tag for this group. - if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { - return false; - } - return true; -} -template -inline bool WireFormat::ReadMessageNoVirtual(io::CodedInputStream* input, - MessageType* value) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->IncrementRecursionDepth()) return false; - io::CodedInputStream::Limit limit = input->PushLimit(length); - if (!value->MessageType::MergePartialFromCodedStream(input)) return false; - // Make sure that parsing stopped when the limit was hit, not at an endgroup - // tag. - if (!input->ConsumedEntireMessage()) return false; - input->PopLimit(limit); - input->DecrementRecursionDepth(); - return true; -} - -// =================================================================== - -inline void WireFormat::WriteTag(int field_number, WireType type, - io::CodedOutputStream* output) { - output->WriteTag(MakeTag(field_number, type)); -} - -inline void WireFormat::WriteInt32NoTag(int32 value, - io::CodedOutputStream* output) { - output->WriteVarint32SignExtended(value); -} -inline void WireFormat::WriteInt64NoTag(int64 value, - io::CodedOutputStream* output) { - output->WriteVarint64(static_cast(value)); -} -inline void WireFormat::WriteUInt32NoTag(uint32 value, - io::CodedOutputStream* output) { - output->WriteVarint32(value); -} -inline void WireFormat::WriteUInt64NoTag(uint64 value, - io::CodedOutputStream* output) { - output->WriteVarint64(value); -} -inline void WireFormat::WriteSInt32NoTag(int32 value, - io::CodedOutputStream* output) { - output->WriteVarint32(ZigZagEncode32(value)); -} -inline void WireFormat::WriteSInt64NoTag(int64 value, - io::CodedOutputStream* output) { - output->WriteVarint64(ZigZagEncode64(value)); -} -inline void WireFormat::WriteFixed32NoTag(uint32 value, - io::CodedOutputStream* output) { - output->WriteLittleEndian32(value); -} -inline void WireFormat::WriteFixed64NoTag(uint64 value, - io::CodedOutputStream* output) { - output->WriteLittleEndian64(value); -} -inline void WireFormat::WriteSFixed32NoTag(int32 value, - io::CodedOutputStream* output) { - output->WriteLittleEndian32(static_cast(value)); -} -inline void WireFormat::WriteSFixed64NoTag(int64 value, - io::CodedOutputStream* output) { - output->WriteLittleEndian64(static_cast(value)); -} -inline void WireFormat::WriteFloatNoTag(float value, - io::CodedOutputStream* output) { - output->WriteLittleEndian32(EncodeFloat(value)); -} -inline void WireFormat::WriteDoubleNoTag(double value, - io::CodedOutputStream* output) { - output->WriteLittleEndian64(EncodeDouble(value)); -} -inline void WireFormat::WriteBoolNoTag(bool value, - io::CodedOutputStream* output) { - output->WriteVarint32(value ? 1 : 0); -} -inline void WireFormat::WriteEnumNoTag(int value, - io::CodedOutputStream* output) { - output->WriteVarint32SignExtended(value); -} - -inline void WireFormat::WriteInt32(int field_number, int32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteInt32NoTag(value, output); -} -inline void WireFormat::WriteInt64(int field_number, int64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteInt64NoTag(value, output); -} -inline void WireFormat::WriteUInt32(int field_number, uint32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteUInt32NoTag(value, output); -} -inline void WireFormat::WriteUInt64(int field_number, uint64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteUInt64NoTag(value, output); -} -inline void WireFormat::WriteSInt32(int field_number, int32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteSInt32NoTag(value, output); -} -inline void WireFormat::WriteSInt64(int field_number, int64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteSInt64NoTag(value, output); -} -inline void WireFormat::WriteFixed32(int field_number, uint32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED32, output); - WriteFixed32NoTag(value, output); -} -inline void WireFormat::WriteFixed64(int field_number, uint64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED64, output); - WriteFixed64NoTag(value, output); -} -inline void WireFormat::WriteSFixed32(int field_number, int32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED32, output); - WriteSFixed32NoTag(value, output); -} -inline void WireFormat::WriteSFixed64(int field_number, int64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED64, output); - WriteSFixed64NoTag(value, output); -} -inline void WireFormat::WriteFloat(int field_number, float value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED32, output); - WriteFloatNoTag(value, output); -} -inline void WireFormat::WriteDouble(int field_number, double value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED64, output); - WriteDoubleNoTag(value, output); -} -inline void WireFormat::WriteBool(int field_number, bool value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteBoolNoTag(value, output); -} -inline void WireFormat::WriteEnum(int field_number, int value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteEnumNoTag(value, output); -} - -inline void WireFormat::WriteString(int field_number, const string& value, - io::CodedOutputStream* output) { - // String is for UTF-8 text only -#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - if (!IsStructurallyValidUTF8(value.data(), value.size())) { - GOOGLE_LOG(ERROR) << "Encountered string containing invalid UTF-8 data while " - "serializing protocol buffer. Strings must contain only UTF-8; " - "use the 'bytes' type for raw bytes."; - } -#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(value.size()); - output->WriteString(value); -} -inline void WireFormat::WriteBytes(int field_number, const string& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(value.size()); - output->WriteString(value); -} - - -inline void WireFormat::WriteGroup(int field_number, const Message& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_START_GROUP, output); - value.SerializeWithCachedSizes(output); - WriteTag(field_number, WIRETYPE_END_GROUP, output); -} -inline void WireFormat::WriteMessage(int field_number, const Message& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(value.GetCachedSize()); - value.SerializeWithCachedSizes(output); -} - -template -inline void WireFormat::WriteGroupNoVirtual( - int field_number, const MessageType& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_START_GROUP, output); - value.MessageType::SerializeWithCachedSizes(output); - WriteTag(field_number, WIRETYPE_END_GROUP, output); -} -template -inline void WireFormat::WriteMessageNoVirtual( - int field_number, const MessageType& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(value.MessageType::GetCachedSize()); - value.MessageType::SerializeWithCachedSizes(output); -} - -// =================================================================== - -inline uint8* WireFormat::WriteTagToArray(int field_number, - WireType type, - uint8* target) { - return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type), - target); -} - -inline uint8* WireFormat::WriteInt32NoTagToArray(int32 value, uint8* target) { - return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); -} -inline uint8* WireFormat::WriteInt64NoTagToArray(int64 value, uint8* target) { - return io::CodedOutputStream::WriteVarint64ToArray( - static_cast(value), target); -} -inline uint8* WireFormat::WriteUInt32NoTagToArray(uint32 value, uint8* target) { - return io::CodedOutputStream::WriteVarint32ToArray(value, target); -} -inline uint8* WireFormat::WriteUInt64NoTagToArray(uint64 value, uint8* target) { - return io::CodedOutputStream::WriteVarint64ToArray(value, target); -} -inline uint8* WireFormat::WriteSInt32NoTagToArray(int32 value, uint8* target) { - return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value), - target); -} -inline uint8* WireFormat::WriteSInt64NoTagToArray(int64 value, uint8* target) { - return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value), - target); -} -inline uint8* WireFormat::WriteFixed32NoTagToArray(uint32 value, - uint8* target) { - return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target); -} -inline uint8* WireFormat::WriteFixed64NoTagToArray(uint64 value, - uint8* target) { - return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target); -} -inline uint8* WireFormat::WriteSFixed32NoTagToArray(int32 value, - uint8* target) { - return io::CodedOutputStream::WriteLittleEndian32ToArray( - static_cast(value), target); -} -inline uint8* WireFormat::WriteSFixed64NoTagToArray(int64 value, - uint8* target) { - return io::CodedOutputStream::WriteLittleEndian64ToArray( - static_cast(value), target); -} -inline uint8* WireFormat::WriteFloatNoTagToArray(float value, uint8* target) { - return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value), - target); -} -inline uint8* WireFormat::WriteDoubleNoTagToArray(double value, - uint8* target) { - return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value), - target); -} -inline uint8* WireFormat::WriteBoolNoTagToArray(bool value, - uint8* target) { - return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target); -} -inline uint8* WireFormat::WriteEnumNoTagToArray(int value, - uint8* target) { - return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); -} - -inline uint8* WireFormat::WriteInt32ToArray(int field_number, - int32 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteInt32NoTagToArray(value, target); -} -inline uint8* WireFormat::WriteInt64ToArray(int field_number, - int64 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteInt64NoTagToArray(value, target); -} -inline uint8* WireFormat::WriteUInt32ToArray(int field_number, - uint32 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteUInt32NoTagToArray(value, target); -} -inline uint8* WireFormat::WriteUInt64ToArray(int field_number, - uint64 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteUInt64NoTagToArray(value, target); -} -inline uint8* WireFormat::WriteSInt32ToArray(int field_number, - int32 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteSInt32NoTagToArray(value, target); -} -inline uint8* WireFormat::WriteSInt64ToArray(int field_number, - int64 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteSInt64NoTagToArray(value, target); -} -inline uint8* WireFormat::WriteFixed32ToArray(int field_number, - uint32 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); - return WriteFixed32NoTagToArray(value, target); -} -inline uint8* WireFormat::WriteFixed64ToArray(int field_number, - uint64 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); - return WriteFixed64NoTagToArray(value, target); -} -inline uint8* WireFormat::WriteSFixed32ToArray(int field_number, - int32 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); - return WriteSFixed32NoTagToArray(value, target); -} -inline uint8* WireFormat::WriteSFixed64ToArray(int field_number, - int64 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); - return WriteSFixed64NoTagToArray(value, target); -} -inline uint8* WireFormat::WriteFloatToArray(int field_number, - float value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); - return WriteFloatNoTagToArray(value, target); -} -inline uint8* WireFormat::WriteDoubleToArray(int field_number, - double value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); - return WriteDoubleNoTagToArray(value, target); -} -inline uint8* WireFormat::WriteBoolToArray(int field_number, - bool value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteBoolNoTagToArray(value, target); -} -inline uint8* WireFormat::WriteEnumToArray(int field_number, - int value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteEnumNoTagToArray(value, target); -} - -inline uint8* WireFormat::WriteStringToArray(int field_number, - const string& value, - uint8* target) { - // String is for UTF-8 text only -#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - if (!IsStructurallyValidUTF8(value.data(), value.size())) { - GOOGLE_LOG(ERROR) << "Encountered string containing invalid UTF-8 data while " - "serializing protocol buffer. Strings must contain only UTF-8; " - "use the 'bytes' type for raw bytes."; - } -#endif - // WARNING: In wire_format.cc, both strings and bytes are handled by - // WriteString() to avoid code duplication. If the implementations become - // different, you will need to update that usage. - target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); - target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target); - return io::CodedOutputStream::WriteStringToArray(value, target); -} -inline uint8* WireFormat::WriteBytesToArray(int field_number, - const string& value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); - target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target); - return io::CodedOutputStream::WriteStringToArray(value, target); -} - - -inline uint8* WireFormat::WriteGroupToArray(int field_number, - const Message& value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); - target = value.SerializeWithCachedSizesToArray(target); - return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); -} -inline uint8* WireFormat::WriteMessageToArray(int field_number, - const Message& value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); - target = io::CodedOutputStream::WriteVarint32ToArray( - value.GetCachedSize(), target); - return value.SerializeWithCachedSizesToArray(target); -} - -template -inline uint8* WireFormat::WriteGroupNoVirtualToArray( - int field_number, const MessageType& value, uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); - target = value.MessageType::SerializeWithCachedSizesToArray(target); - return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); -} -template -inline uint8* WireFormat::WriteMessageNoVirtualToArray( - int field_number, const MessageType& value, uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); - target = io::CodedOutputStream::WriteVarint32ToArray( - value.MessageType::GetCachedSize(), target); - return value.MessageType::SerializeWithCachedSizesToArray(target); -} - -// =================================================================== - -inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) { - int result = io::CodedOutputStream::VarintSize32( - field_number << kTagTypeBits); - if (type == FieldDescriptor::TYPE_GROUP) { - // Groups have both a start and an end tag. - return result * 2; - } else { - return result; - } -} - -inline int WireFormat::Int32Size(int32 value) { - return io::CodedOutputStream::VarintSize32SignExtended(value); -} -inline int WireFormat::Int64Size(int64 value) { - return io::CodedOutputStream::VarintSize64(static_cast(value)); -} -inline int WireFormat::UInt32Size(uint32 value) { - return io::CodedOutputStream::VarintSize32(value); -} -inline int WireFormat::UInt64Size(uint64 value) { - return io::CodedOutputStream::VarintSize64(value); -} -inline int WireFormat::SInt32Size(int32 value) { - return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); -} -inline int WireFormat::SInt64Size(int64 value) { - return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); -} -inline int WireFormat::EnumSize(int value) { - return io::CodedOutputStream::VarintSize32SignExtended(value); -} - -inline int WireFormat::StringSize(const string& value) { - return io::CodedOutputStream::VarintSize32(value.size()) + - value.size(); -} -inline int WireFormat::BytesSize(const string& value) { - return io::CodedOutputStream::VarintSize32(value.size()) + - value.size(); -} - - -inline int WireFormat::GroupSize(const Message& value) { - return value.ByteSize(); -} -inline int WireFormat::MessageSize(const Message& value) { - int size = value.ByteSize(); - return io::CodedOutputStream::VarintSize32(size) + size; -} - -template -inline int WireFormat::GroupSizeNoVirtual(const MessageType& value) { - return value.MessageType::ByteSize(); -} -template -inline int WireFormat::MessageSizeNoVirtual(const MessageType& value) { - int size = value.MessageType::ByteSize(); - return io::CodedOutputStream::VarintSize32(size) + size; -} - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_INL_H__ diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc new file mode 100644 index 00000000..bbbf5236 --- /dev/null +++ b/src/google/protobuf/wire_format_lite.cc @@ -0,0 +1,193 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +#ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC + // requires them. +const int WireFormatLite::kMessageSetItemStartTag; +const int WireFormatLite::kMessageSetItemEndTag; +const int WireFormatLite::kMessageSetTypeIdTag; +const int WireFormatLite::kMessageSetMessageTag; + +#endif + +const int WireFormatLite::kMessageSetItemTagsSize = + io::CodedOutputStream::VarintSize32(kMessageSetItemStartTag) + + io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) + + io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) + + io::CodedOutputStream::VarintSize32(kMessageSetMessageTag); + +const WireFormatLite::CppType +WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = { + static_cast(0), // 0 is reserved for errors + + CPPTYPE_DOUBLE, // TYPE_DOUBLE + CPPTYPE_FLOAT, // TYPE_FLOAT + CPPTYPE_INT64, // TYPE_INT64 + CPPTYPE_UINT64, // TYPE_UINT64 + CPPTYPE_INT32, // TYPE_INT32 + CPPTYPE_UINT64, // TYPE_FIXED64 + CPPTYPE_UINT32, // TYPE_FIXED32 + CPPTYPE_BOOL, // TYPE_BOOL + CPPTYPE_STRING, // TYPE_STRING + CPPTYPE_MESSAGE, // TYPE_GROUP + CPPTYPE_MESSAGE, // TYPE_MESSAGE + CPPTYPE_STRING, // TYPE_BYTES + CPPTYPE_UINT32, // TYPE_UINT32 + CPPTYPE_ENUM, // TYPE_ENUM + CPPTYPE_INT32, // TYPE_SFIXED32 + CPPTYPE_INT64, // TYPE_SFIXED64 + CPPTYPE_INT32, // TYPE_SINT32 + CPPTYPE_INT64, // TYPE_SINT64 +}; + +const WireFormatLite::WireType +WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = { + static_cast(-1), // invalid + WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE + WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT + WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64 + WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64 + WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32 + WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64 + WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32 + WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING + WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES + WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32 + WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM + WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32 + WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64 + WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32 + WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64 +}; + +bool WireFormatLite::SkipField( + io::CodedInputStream* input, uint32 tag) { + switch (WireFormatLite::GetTagWireType(tag)) { + case WireFormatLite::WIRETYPE_VARINT: { + uint64 value; + if (!input->ReadVarint64(&value)) return false; + return true; + } + case WireFormatLite::WIRETYPE_FIXED64: { + uint64 value; + if (!input->ReadLittleEndian64(&value)) return false; + return true; + } + case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->Skip(length)) return false; + return true; + } + case WireFormatLite::WIRETYPE_START_GROUP: { + if (!input->IncrementRecursionDepth()) return false; + if (!SkipMessage(input)) return false; + input->DecrementRecursionDepth(); + // Check that the ending tag matched the starting tag. + if (!input->LastTagWas(WireFormatLite::MakeTag( + WireFormatLite::GetTagFieldNumber(tag), + WireFormatLite::WIRETYPE_END_GROUP))) { + return false; + } + return true; + } + case WireFormatLite::WIRETYPE_END_GROUP: { + return false; + } + case WireFormatLite::WIRETYPE_FIXED32: { + uint32 value; + if (!input->ReadLittleEndian32(&value)) return false; + return true; + } + default: { + return false; + } + } +} + +bool WireFormatLite::SkipMessage(io::CodedInputStream* input) { + while(true) { + uint32 tag = input->ReadTag(); + if (tag == 0) { + // End of input. This is a valid place to end, so return true. + return true; + } + + WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); + + if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { + // Must be the end of the message. + return true; + } + + if (!SkipField(input, tag)) return false; + } +} + +bool FieldSkipper::SkipField( + io::CodedInputStream* input, uint32 tag) { + return WireFormatLite::SkipField(input, tag); +} + +bool FieldSkipper::SkipMessage(io::CodedInputStream* input) { + return WireFormatLite::SkipMessage(input); +} + +void FieldSkipper::SkipUnknownEnum( + int field_number, int value) { + // Nothing. +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h new file mode 100644 index 00000000..9b7a4010 --- /dev/null +++ b/src/google/protobuf/wire_format_lite.h @@ -0,0 +1,558 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// atenasio@google.com (Chris Atenasio) (ZigZag transform) +// wink@google.com (Wink Saville) (refactored from wire_format.h) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ +#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ + +#include +#include + +namespace google { + +namespace protobuf { + namespace io { + class CodedInputStream; // coded_stream.h + class CodedOutputStream; // coded_stream.h + } +} + +namespace protobuf { +namespace internal { + +// This class is for internal use by the protocol buffer library and by +// protocol-complier-generated message classes. It must not be called +// directly by clients. +// +// This class contains helpers for implementing the binary protocol buffer +// wire format without the need for reflection. Use WireFormat when using +// reflection. +// +// This class is really a namespace that contains only static methods. +class LIBPROTOBUF_EXPORT WireFormatLite { + public: + + // ----------------------------------------------------------------- + // Helper constants and functions related to the format. These are + // mostly meant for internal and generated code to use. + + // The wire format is composed of a sequence of tag/value pairs, each + // of which contains the value of one field (or one element of a repeated + // field). Each tag is encoded as a varint. The lower bits of the tag + // identify its wire type, which specifies the format of the data to follow. + // The rest of the bits contain the field number. Each type of field (as + // declared by FieldDescriptor::Type, in descriptor.h) maps to one of + // these wire types. Immediately following each tag is the field's value, + // encoded in the format specified by the wire type. Because the tag + // identifies the encoding of this data, it is possible to skip + // unrecognized fields for forwards compatibility. + + enum WireType { + WIRETYPE_VARINT = 0, + WIRETYPE_FIXED64 = 1, + WIRETYPE_LENGTH_DELIMITED = 2, + WIRETYPE_START_GROUP = 3, + WIRETYPE_END_GROUP = 4, + WIRETYPE_FIXED32 = 5, + }; + + // Lite alternative to FieldDescriptor::Type. Must be kept in sync. + enum FieldType { + TYPE_DOUBLE = 1, + TYPE_FLOAT = 2, + TYPE_INT64 = 3, + TYPE_UINT64 = 4, + TYPE_INT32 = 5, + TYPE_FIXED64 = 6, + TYPE_FIXED32 = 7, + TYPE_BOOL = 8, + TYPE_STRING = 9, + TYPE_GROUP = 10, + TYPE_MESSAGE = 11, + TYPE_BYTES = 12, + TYPE_UINT32 = 13, + TYPE_ENUM = 14, + TYPE_SFIXED32 = 15, + TYPE_SFIXED64 = 16, + TYPE_SINT32 = 17, + TYPE_SINT64 = 18, + MAX_FIELD_TYPE = 18, + }; + + // Lite alternative to FieldDescriptor::CppType. Must be kept in sync. + enum CppType { + CPPTYPE_INT32 = 1, + CPPTYPE_INT64 = 2, + CPPTYPE_UINT32 = 3, + CPPTYPE_UINT64 = 4, + CPPTYPE_DOUBLE = 5, + CPPTYPE_FLOAT = 6, + CPPTYPE_BOOL = 7, + CPPTYPE_ENUM = 8, + CPPTYPE_STRING = 9, + CPPTYPE_MESSAGE = 10, + MAX_CPPTYPE = 10, + }; + + // Helper method to get the CppType for a particular Type. + static CppType FieldTypeToCppType(FieldType type); + + // Given a FieldSescriptor::Type return its WireType + static inline WireFormatLite::WireType WireTypeForFieldType( + WireFormatLite::FieldType type) { + return kWireTypeForFieldType[type]; + } + + // Number of bits in a tag which identify the wire type. + static const int kTagTypeBits = 3; + // Mask for those bits. + static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1; + + // Helper functions for encoding and decoding tags. (Inlined below and in + // _inl.h) + // + // This is different from MakeTag(field->number(), field->type()) in the case + // of packed repeated fields. + static uint32 MakeTag(int field_number, WireType type); + static WireType GetTagWireType(uint32 tag); + static int GetTagFieldNumber(uint32 tag); + + // Compute the byte size of a tag. For groups, this includes both the start + // and end tags. + static inline int TagSize(int field_number, WireFormatLite::FieldType type); + + // Skips a field value with the given tag. The input should start + // positioned immediately after the tag. Skipped values are simply discarded, + // not recorded anywhere. See WireFormat::SkipField() for a version that + // records to an UnknownFieldSet. + static bool SkipField(io::CodedInputStream* input, uint32 tag); + + // Reads and ignores a message from the input. Skipped values are simply + // discarded, not recorded anywhere. See WireFormat::SkipMessage() for a + // version that records to an UnknownFieldSet. + static bool SkipMessage(io::CodedInputStream* input); + +// This macro does the same thing as WireFormatLite::MakeTag(), but the +// result is usable as a compile-time constant, which makes it usable +// as a switch case or a template input. WireFormatLite::MakeTag() is more +// type-safe, though, so prefer it if possible. +#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \ + static_cast( \ + ((FIELD_NUMBER) << ::google::protobuf::internal::WireFormatLite::kTagTypeBits) \ + | (TYPE)) + + // These are the tags for the old MessageSet format, which was defined as: + // message MessageSet { + // repeated group Item = 1 { + // required int32 type_id = 2; + // required string message = 3; + // } + // } + static const int kMessageSetItemStartTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(1, WireFormatLite::WIRETYPE_START_GROUP); + static const int kMessageSetItemEndTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(1, WireFormatLite::WIRETYPE_END_GROUP); + static const int kMessageSetTypeIdTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(2, WireFormatLite::WIRETYPE_VARINT); + static const int kMessageSetMessageTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(3, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + + // Byte size of all tags of a MessageSet::Item combined. + static const int kMessageSetItemTagsSize; + + // Helper functions for converting between floats/doubles and IEEE-754 + // uint32s/uint64s so that they can be written. (Assumes your platform + // uses IEEE-754 floats.) + static uint32 EncodeFloat(float value); + static float DecodeFloat(uint32 value); + static uint64 EncodeDouble(double value); + static double DecodeDouble(uint64 value); + + // Helper functions for mapping signed integers to unsigned integers in + // such a way that numbers with small magnitudes will encode to smaller + // varints. If you simply static_cast a negative number to an unsigned + // number and varint-encode it, it will always take 10 bytes, defeating + // the purpose of varint. So, for the "sint32" and "sint64" field types, + // we ZigZag-encode the values. + static uint32 ZigZagEncode32(int32 n); + static int32 ZigZagDecode32(uint32 n); + static uint64 ZigZagEncode64(int64 n); + static int64 ZigZagDecode64(uint64 n); + + // ================================================================= + // Methods for reading/writing individual field. The implementations + // of these methods are defined in wire_format_lite_inl.h; you must #include + // that file to use these. + +// Avoid ugly line wrapping +#define input io::CodedInputStream* input +#define output io::CodedOutputStream* output +#define field_number int field_number +#define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE + + // Read fields, not including tags. The assumption is that you already + // read the tag to determine what field to read. + static inline bool ReadInt32 (input, int32* value); + static inline bool ReadInt64 (input, int64* value); + static inline bool ReadUInt32 (input, uint32* value); + static inline bool ReadUInt64 (input, uint64* value); + static inline bool ReadSInt32 (input, int32* value); + static inline bool ReadSInt64 (input, int64* value); + static inline bool ReadFixed32 (input, uint32* value); + static inline bool ReadFixed64 (input, uint64* value); + static inline bool ReadSFixed32(input, int32* value); + static inline bool ReadSFixed64(input, int64* value); + static inline bool ReadFloat (input, float* value); + static inline bool ReadDouble (input, double* value); + static inline bool ReadBool (input, bool* value); + static inline bool ReadEnum (input, int* value); + + static inline bool ReadString(input, string* value); + static inline bool ReadBytes (input, string* value); + + static inline bool ReadGroup (field_number, input, MessageLite* value); + static inline bool ReadMessage(input, MessageLite* value); + + // Like above, but de-virtualize the call to MergePartialFromCodedStream(). + // The pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override MergePartialFromCodedStream()). + template + static inline bool ReadGroupNoVirtual(field_number, input, + MessageType* value); + template + static inline bool ReadMessageNoVirtual(input, MessageType* value); + + // Write a tag. The Write*() functions typically include the tag, so + // normally there's no need to call this unless using the Write*NoTag() + // variants. + static inline void WriteTag(field_number, WireType type, output) INL; + + // Write fields, without tags. + static inline void WriteInt32NoTag (int32 value, output) INL; + static inline void WriteInt64NoTag (int64 value, output) INL; + static inline void WriteUInt32NoTag (uint32 value, output) INL; + static inline void WriteUInt64NoTag (uint64 value, output) INL; + static inline void WriteSInt32NoTag (int32 value, output) INL; + static inline void WriteSInt64NoTag (int64 value, output) INL; + static inline void WriteFixed32NoTag (uint32 value, output) INL; + static inline void WriteFixed64NoTag (uint64 value, output) INL; + static inline void WriteSFixed32NoTag(int32 value, output) INL; + static inline void WriteSFixed64NoTag(int64 value, output) INL; + static inline void WriteFloatNoTag (float value, output) INL; + static inline void WriteDoubleNoTag (double value, output) INL; + static inline void WriteBoolNoTag (bool value, output) INL; + static inline void WriteEnumNoTag (int value, output) INL; + + // Write fields, including tags. + static inline void WriteInt32 (field_number, int32 value, output) INL; + static inline void WriteInt64 (field_number, int64 value, output) INL; + static inline void WriteUInt32 (field_number, uint32 value, output) INL; + static inline void WriteUInt64 (field_number, uint64 value, output) INL; + static inline void WriteSInt32 (field_number, int32 value, output) INL; + static inline void WriteSInt64 (field_number, int64 value, output) INL; + static inline void WriteFixed32 (field_number, uint32 value, output) INL; + static inline void WriteFixed64 (field_number, uint64 value, output) INL; + static inline void WriteSFixed32(field_number, int32 value, output) INL; + static inline void WriteSFixed64(field_number, int64 value, output) INL; + static inline void WriteFloat (field_number, float value, output) INL; + static inline void WriteDouble (field_number, double value, output) INL; + static inline void WriteBool (field_number, bool value, output) INL; + static inline void WriteEnum (field_number, int value, output) INL; + + static inline void WriteString(field_number, const string& value, output) INL; + static inline void WriteBytes (field_number, const string& value, output) INL; + + static inline void WriteGroup( + field_number, const MessageLite& value, output) INL; + static inline void WriteMessage( + field_number, const MessageLite& value, output) INL; + + // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The + // pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override SerializeWithCachedSizes()). + template + static inline void WriteGroupNoVirtual( + field_number, const MessageType& value, output) INL; + template + static inline void WriteMessageNoVirtual( + field_number, const MessageType& value, output) INL; + +#undef output +#define output uint8* target + + // Like above, but use only *ToArray methods of CodedOutputStream. + static inline uint8* WriteTagToArray(field_number, WireType type, output) INL; + + // Write fields, without tags. + static inline uint8* WriteInt32NoTagToArray (int32 value, output) INL; + static inline uint8* WriteInt64NoTagToArray (int64 value, output) INL; + static inline uint8* WriteUInt32NoTagToArray (uint32 value, output) INL; + static inline uint8* WriteUInt64NoTagToArray (uint64 value, output) INL; + static inline uint8* WriteSInt32NoTagToArray (int32 value, output) INL; + static inline uint8* WriteSInt64NoTagToArray (int64 value, output) INL; + static inline uint8* WriteFixed32NoTagToArray (uint32 value, output) INL; + static inline uint8* WriteFixed64NoTagToArray (uint64 value, output) INL; + static inline uint8* WriteSFixed32NoTagToArray(int32 value, output) INL; + static inline uint8* WriteSFixed64NoTagToArray(int64 value, output) INL; + static inline uint8* WriteFloatNoTagToArray (float value, output) INL; + static inline uint8* WriteDoubleNoTagToArray (double value, output) INL; + static inline uint8* WriteBoolNoTagToArray (bool value, output) INL; + static inline uint8* WriteEnumNoTagToArray (int value, output) INL; + + // Write fields, including tags. + static inline uint8* WriteInt32ToArray( + field_number, int32 value, output) INL; + static inline uint8* WriteInt64ToArray( + field_number, int64 value, output) INL; + static inline uint8* WriteUInt32ToArray( + field_number, uint32 value, output) INL; + static inline uint8* WriteUInt64ToArray( + field_number, uint64 value, output) INL; + static inline uint8* WriteSInt32ToArray( + field_number, int32 value, output) INL; + static inline uint8* WriteSInt64ToArray( + field_number, int64 value, output) INL; + static inline uint8* WriteFixed32ToArray( + field_number, uint32 value, output) INL; + static inline uint8* WriteFixed64ToArray( + field_number, uint64 value, output) INL; + static inline uint8* WriteSFixed32ToArray( + field_number, int32 value, output) INL; + static inline uint8* WriteSFixed64ToArray( + field_number, int64 value, output) INL; + static inline uint8* WriteFloatToArray( + field_number, float value, output) INL; + static inline uint8* WriteDoubleToArray( + field_number, double value, output) INL; + static inline uint8* WriteBoolToArray( + field_number, bool value, output) INL; + static inline uint8* WriteEnumToArray( + field_number, int value, output) INL; + + static inline uint8* WriteStringToArray( + field_number, const string& value, output) INL; + static inline uint8* WriteBytesToArray( + field_number, const string& value, output) INL; + + static inline uint8* WriteGroupToArray( + field_number, const MessageLite& value, output) INL; + static inline uint8* WriteMessageToArray( + field_number, const MessageLite& value, output) INL; + + // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The + // pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override SerializeWithCachedSizes()). + template + static inline uint8* WriteGroupNoVirtualToArray( + field_number, const MessageType& value, output) INL; + template + static inline uint8* WriteMessageNoVirtualToArray( + field_number, const MessageType& value, output) INL; + +#undef output +#undef input +#undef INL + +#undef field_number + + // Compute the byte size of a field. The XxSize() functions do NOT include + // the tag, so you must also call TagSize(). (This is because, for repeated + // fields, you should only call TagSize() once and multiply it by the element + // count, but you may have to call XxSize() for each individual element.) + static inline int Int32Size ( int32 value); + static inline int Int64Size ( int64 value); + static inline int UInt32Size (uint32 value); + static inline int UInt64Size (uint64 value); + static inline int SInt32Size ( int32 value); + static inline int SInt64Size ( int64 value); + static inline int EnumSize ( int value); + + // These types always have the same size. + static const int kFixed32Size = 4; + static const int kFixed64Size = 8; + static const int kSFixed32Size = 4; + static const int kSFixed64Size = 8; + static const int kFloatSize = 4; + static const int kDoubleSize = 8; + static const int kBoolSize = 1; + + static inline int StringSize(const string& value); + static inline int BytesSize (const string& value); + + static inline int GroupSize (const MessageLite& value); + static inline int MessageSize(const MessageLite& value); + + // Like above, but de-virtualize the call to ByteSize(). The + // pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override ByteSize()). + template + static inline int GroupSizeNoVirtual (const MessageType& value); + template + static inline int MessageSizeNoVirtual(const MessageType& value); + + private: + static const CppType kFieldTypeToCppTypeMap[]; + static const WireFormatLite::WireType kWireTypeForFieldType[]; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite); +}; + +// A class which deals with unknown values. The default implementation just +// discards them. WireFormat defines a subclass which writes to an +// UnknownFieldSet. This class is used by ExtensionSet::ParseField(), since +// ExtensionSet is part of the lite library but UnknownFieldSet is not. +class LIBPROTOBUF_EXPORT FieldSkipper { + public: + FieldSkipper() {} + virtual ~FieldSkipper() {} + + // Skip a field whose tag has already been consumed. + virtual bool SkipField(io::CodedInputStream* input, uint32 tag); + + // Skip an entire message or group, up to an end-group tag (which is consumed) + // or end-of-stream. + virtual bool SkipMessage(io::CodedInputStream* input); + + // Deal with an already-parsed unrecognized enum value. The default + // implementation does nothing, but the UnknownFieldSet-based implementation + // saves it as an unknown varint. + virtual void SkipUnknownEnum(int field_number, int value); +}; + +// inline methods ==================================================== + +inline WireFormatLite::CppType +WireFormatLite::FieldTypeToCppType(FieldType type) { + return kFieldTypeToCppTypeMap[type]; +} + +inline uint32 WireFormatLite::MakeTag(int field_number, WireType type) { + return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type); +} + +inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) { + return static_cast(tag & kTagTypeMask); +} + +inline int WireFormatLite::GetTagFieldNumber(uint32 tag) { + return static_cast(tag >> kTagTypeBits); +} + +inline int WireFormatLite::TagSize(int field_number, + WireFormatLite::FieldType type) { + int result = io::CodedOutputStream::VarintSize32( + field_number << kTagTypeBits); + if (type == TYPE_GROUP) { + // Groups have both a start and an end tag. + return result * 2; + } else { + return result; + } +} + +inline uint32 WireFormatLite::EncodeFloat(float value) { + union {float f; uint32 i;}; + f = value; + return i; +} + +inline float WireFormatLite::DecodeFloat(uint32 value) { + union {float f; uint32 i;}; + i = value; + return f; +} + +inline uint64 WireFormatLite::EncodeDouble(double value) { + union {double f; uint64 i;}; + f = value; + return i; +} + +inline double WireFormatLite::DecodeDouble(uint64 value) { + union {double f; uint64 i;}; + i = value; + return f; +} + +// ZigZag Transform: Encodes signed integers so that they can be +// effectively used with varint encoding. +// +// varint operates on unsigned integers, encoding smaller numbers into +// fewer bytes. If you try to use it on a signed integer, it will treat +// this number as a very large unsigned integer, which means that even +// small signed numbers like -1 will take the maximum number of bytes +// (10) to encode. ZigZagEncode() maps signed integers to unsigned +// in such a way that those with a small absolute value will have smaller +// encoded values, making them appropriate for encoding using varint. +// +// int32 -> uint32 +// ------------------------- +// 0 -> 0 +// -1 -> 1 +// 1 -> 2 +// -2 -> 3 +// ... -> ... +// 2147483647 -> 4294967294 +// -2147483648 -> 4294967295 +// +// >> encode >> +// << decode << + +inline uint32 WireFormatLite::ZigZagEncode32(int32 n) { + // Note: the right-shift must be arithmetic + return (n << 1) ^ (n >> 31); +} + +inline int32 WireFormatLite::ZigZagDecode32(uint32 n) { + return (n >> 1) ^ -static_cast(n & 1); +} + +inline uint64 WireFormatLite::ZigZagEncode64(int64 n) { + // Note: the right-shift must be arithmetic + return (n << 1) ^ (n >> 63); +} + +inline int64 WireFormatLite::ZigZagDecode64(uint64 n) { + return (n >> 1) ^ -static_cast(n & 1); +} + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h new file mode 100644 index 00000000..eb9155e9 --- /dev/null +++ b/src/google/protobuf/wire_format_lite_inl.h @@ -0,0 +1,657 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// wink@google.com (Wink Saville) (refactored from wire_format.h) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ +#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ + +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace internal { + +inline bool WireFormatLite::ReadInt32(io::CodedInputStream* input, + int32* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = static_cast(temp); + return true; +} +inline bool WireFormatLite::ReadInt64(io::CodedInputStream* input, + int64* value) { + uint64 temp; + if (!input->ReadVarint64(&temp)) return false; + *value = static_cast(temp); + return true; +} +inline bool WireFormatLite::ReadUInt32(io::CodedInputStream* input, + uint32* value) { + return input->ReadVarint32(value); +} +inline bool WireFormatLite::ReadUInt64(io::CodedInputStream* input, + uint64* value) { + return input->ReadVarint64(value); +} +inline bool WireFormatLite::ReadSInt32(io::CodedInputStream* input, + int32* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = ZigZagDecode32(temp); + return true; +} +inline bool WireFormatLite::ReadSInt64(io::CodedInputStream* input, + int64* value) { + uint64 temp; + if (!input->ReadVarint64(&temp)) return false; + *value = ZigZagDecode64(temp); + return true; +} +inline bool WireFormatLite::ReadFixed32(io::CodedInputStream* input, + uint32* value) { + return input->ReadLittleEndian32(value); +} +inline bool WireFormatLite::ReadFixed64(io::CodedInputStream* input, + uint64* value) { + return input->ReadLittleEndian64(value); +} +inline bool WireFormatLite::ReadSFixed32(io::CodedInputStream* input, + int32* value) { + uint32 temp; + if (!input->ReadLittleEndian32(&temp)) return false; + *value = static_cast(temp); + return true; +} +inline bool WireFormatLite::ReadSFixed64(io::CodedInputStream* input, + int64* value) { + uint64 temp; + if (!input->ReadLittleEndian64(&temp)) return false; + *value = static_cast(temp); + return true; +} +inline bool WireFormatLite::ReadFloat(io::CodedInputStream* input, + float* value) { + uint32 temp; + if (!input->ReadLittleEndian32(&temp)) return false; + *value = DecodeFloat(temp); + return true; +} +inline bool WireFormatLite::ReadDouble(io::CodedInputStream* input, + double* value) { + uint64 temp; + if (!input->ReadLittleEndian64(&temp)) return false; + *value = DecodeDouble(temp); + return true; +} +inline bool WireFormatLite::ReadBool(io::CodedInputStream* input, + bool* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = temp != 0; + return true; +} +inline bool WireFormatLite::ReadEnum(io::CodedInputStream* input, + int* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = static_cast(temp); + return true; +} + +inline bool WireFormatLite::ReadString(io::CodedInputStream* input, + string* value) { + // String is for UTF-8 text only + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->ReadString(value, length)) return false; + return true; +} +inline bool WireFormatLite::ReadBytes(io::CodedInputStream* input, + string* value) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + return input->ReadString(value, length); +} + + +inline bool WireFormatLite::ReadGroup(int field_number, + io::CodedInputStream* input, + MessageLite* value) { + if (!input->IncrementRecursionDepth()) return false; + if (!value->MergePartialFromCodedStream(input)) return false; + input->DecrementRecursionDepth(); + // Make sure the last thing read was an end tag for this group. + if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { + return false; + } + return true; +} +inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, + MessageLite* value) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->IncrementRecursionDepth()) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + if (!value->MergePartialFromCodedStream(input)) return false; + // Make sure that parsing stopped when the limit was hit, not at an endgroup + // tag. + if (!input->ConsumedEntireMessage()) return false; + input->PopLimit(limit); + input->DecrementRecursionDepth(); + return true; +} + +template +inline bool WireFormatLite::ReadGroupNoVirtual(int field_number, + io::CodedInputStream* input, + MessageType* value) { + if (!input->IncrementRecursionDepth()) return false; + if (!value->MessageType::MergePartialFromCodedStream(input)) return false; + input->DecrementRecursionDepth(); + // Make sure the last thing read was an end tag for this group. + if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { + return false; + } + return true; +} +template +inline bool WireFormatLite::ReadMessageNoVirtual(io::CodedInputStream* input, + MessageType* value) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->IncrementRecursionDepth()) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + if (!value->MessageType::MergePartialFromCodedStream(input)) return false; + // Make sure that parsing stopped when the limit was hit, not at an endgroup + // tag. + if (!input->ConsumedEntireMessage()) return false; + input->PopLimit(limit); + input->DecrementRecursionDepth(); + return true; +} + +// =================================================================== + +inline void WireFormatLite::WriteTag(int field_number, WireType type, + io::CodedOutputStream* output) { + output->WriteTag(MakeTag(field_number, type)); +} + +inline void WireFormatLite::WriteInt32NoTag(int32 value, + io::CodedOutputStream* output) { + output->WriteVarint32SignExtended(value); +} +inline void WireFormatLite::WriteInt64NoTag(int64 value, + io::CodedOutputStream* output) { + output->WriteVarint64(static_cast(value)); +} +inline void WireFormatLite::WriteUInt32NoTag(uint32 value, + io::CodedOutputStream* output) { + output->WriteVarint32(value); +} +inline void WireFormatLite::WriteUInt64NoTag(uint64 value, + io::CodedOutputStream* output) { + output->WriteVarint64(value); +} +inline void WireFormatLite::WriteSInt32NoTag(int32 value, + io::CodedOutputStream* output) { + output->WriteVarint32(ZigZagEncode32(value)); +} +inline void WireFormatLite::WriteSInt64NoTag(int64 value, + io::CodedOutputStream* output) { + output->WriteVarint64(ZigZagEncode64(value)); +} +inline void WireFormatLite::WriteFixed32NoTag(uint32 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian32(value); +} +inline void WireFormatLite::WriteFixed64NoTag(uint64 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian64(value); +} +inline void WireFormatLite::WriteSFixed32NoTag(int32 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian32(static_cast(value)); +} +inline void WireFormatLite::WriteSFixed64NoTag(int64 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian64(static_cast(value)); +} +inline void WireFormatLite::WriteFloatNoTag(float value, + io::CodedOutputStream* output) { + output->WriteLittleEndian32(EncodeFloat(value)); +} +inline void WireFormatLite::WriteDoubleNoTag(double value, + io::CodedOutputStream* output) { + output->WriteLittleEndian64(EncodeDouble(value)); +} +inline void WireFormatLite::WriteBoolNoTag(bool value, + io::CodedOutputStream* output) { + output->WriteVarint32(value ? 1 : 0); +} +inline void WireFormatLite::WriteEnumNoTag(int value, + io::CodedOutputStream* output) { + output->WriteVarint32SignExtended(value); +} + +inline void WireFormatLite::WriteInt32(int field_number, int32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteInt32NoTag(value, output); +} +inline void WireFormatLite::WriteInt64(int field_number, int64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteInt64NoTag(value, output); +} +inline void WireFormatLite::WriteUInt32(int field_number, uint32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteUInt32NoTag(value, output); +} +inline void WireFormatLite::WriteUInt64(int field_number, uint64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteUInt64NoTag(value, output); +} +inline void WireFormatLite::WriteSInt32(int field_number, int32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteSInt32NoTag(value, output); +} +inline void WireFormatLite::WriteSInt64(int field_number, int64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteSInt64NoTag(value, output); +} +inline void WireFormatLite::WriteFixed32(int field_number, uint32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED32, output); + WriteFixed32NoTag(value, output); +} +inline void WireFormatLite::WriteFixed64(int field_number, uint64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED64, output); + WriteFixed64NoTag(value, output); +} +inline void WireFormatLite::WriteSFixed32(int field_number, int32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED32, output); + WriteSFixed32NoTag(value, output); +} +inline void WireFormatLite::WriteSFixed64(int field_number, int64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED64, output); + WriteSFixed64NoTag(value, output); +} +inline void WireFormatLite::WriteFloat(int field_number, float value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED32, output); + WriteFloatNoTag(value, output); +} +inline void WireFormatLite::WriteDouble(int field_number, double value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED64, output); + WriteDoubleNoTag(value, output); +} +inline void WireFormatLite::WriteBool(int field_number, bool value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteBoolNoTag(value, output); +} +inline void WireFormatLite::WriteEnum(int field_number, int value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteEnumNoTag(value, output); +} + +inline void WireFormatLite::WriteString(int field_number, const string& value, + io::CodedOutputStream* output) { + // String is for UTF-8 text only + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(value.size()); + output->WriteString(value); +} +inline void WireFormatLite::WriteBytes(int field_number, const string& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(value.size()); + output->WriteString(value); +} + + +inline void WireFormatLite::WriteGroup(int field_number, + const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_START_GROUP, output); + value.SerializeWithCachedSizes(output); + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} +inline void WireFormatLite::WriteMessage(int field_number, + const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(value.GetCachedSize()); + value.SerializeWithCachedSizes(output); +} + +template +inline void WireFormatLite::WriteGroupNoVirtual(int field_number, + const MessageType& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_START_GROUP, output); + value.MessageType::SerializeWithCachedSizes(output); + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} +template +inline void WireFormatLite::WriteMessageNoVirtual(int field_number, + const MessageType& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(value.MessageType::GetCachedSize()); + value.MessageType::SerializeWithCachedSizes(output); +} + +// =================================================================== + +inline uint8* WireFormatLite::WriteTagToArray(int field_number, + WireType type, + uint8* target) { + return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type), + target); +} + +inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); +} +inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint64ToArray( + static_cast(value), target); +} +inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32ToArray(value, target); +} +inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint64ToArray(value, target); +} +inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value), + target); +} +inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value), + target); +} +inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target); +} +inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target); +} +inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian32ToArray( + static_cast(value), target); +} +inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian64ToArray( + static_cast(value), target); +} +inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value), + target); +} +inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value), + target); +} +inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target); +} +inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); +} + +inline uint8* WireFormatLite::WriteInt32ToArray(int field_number, + int32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteInt32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteInt64ToArray(int field_number, + int64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteInt64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number, + uint32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteUInt32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number, + uint64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteUInt64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number, + int32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteSInt32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number, + int64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteSInt64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number, + uint32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); + return WriteFixed32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number, + uint64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); + return WriteFixed64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number, + int32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); + return WriteSFixed32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number, + int64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); + return WriteSFixed64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteFloatToArray(int field_number, + float value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); + return WriteFloatNoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteDoubleToArray(int field_number, + double value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); + return WriteDoubleNoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteBoolToArray(int field_number, + bool value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteBoolNoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteEnumToArray(int field_number, + int value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteEnumNoTagToArray(value, target); +} + +inline uint8* WireFormatLite::WriteStringToArray(int field_number, + const string& value, + uint8* target) { + // String is for UTF-8 text only + // WARNING: In wire_format.cc, both strings and bytes are handled by + // WriteString() to avoid code duplication. If the implementations become + // different, you will need to update that usage. + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target); + return io::CodedOutputStream::WriteStringToArray(value, target); +} +inline uint8* WireFormatLite::WriteBytesToArray(int field_number, + const string& value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target); + return io::CodedOutputStream::WriteStringToArray(value, target); +} + + +inline uint8* WireFormatLite::WriteGroupToArray(int field_number, + const MessageLite& value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); + target = value.SerializeWithCachedSizesToArray(target); + return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); +} +inline uint8* WireFormatLite::WriteMessageToArray(int field_number, + const MessageLite& value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArray( + value.GetCachedSize(), target); + return value.SerializeWithCachedSizesToArray(target); +} + +template +inline uint8* WireFormatLite::WriteGroupNoVirtualToArray( + int field_number, const MessageType& value, uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); + target = value.MessageType::SerializeWithCachedSizesToArray(target); + return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); +} +template +inline uint8* WireFormatLite::WriteMessageNoVirtualToArray( + int field_number, const MessageType& value, uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArray( + value.MessageType::GetCachedSize(), target); + return value.MessageType::SerializeWithCachedSizesToArray(target); +} + +// =================================================================== + +inline int WireFormatLite::Int32Size(int32 value) { + return io::CodedOutputStream::VarintSize32SignExtended(value); +} +inline int WireFormatLite::Int64Size(int64 value) { + return io::CodedOutputStream::VarintSize64(static_cast(value)); +} +inline int WireFormatLite::UInt32Size(uint32 value) { + return io::CodedOutputStream::VarintSize32(value); +} +inline int WireFormatLite::UInt64Size(uint64 value) { + return io::CodedOutputStream::VarintSize64(value); +} +inline int WireFormatLite::SInt32Size(int32 value) { + return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); +} +inline int WireFormatLite::SInt64Size(int64 value) { + return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); +} +inline int WireFormatLite::EnumSize(int value) { + return io::CodedOutputStream::VarintSize32SignExtended(value); +} + +inline int WireFormatLite::StringSize(const string& value) { + return io::CodedOutputStream::VarintSize32(value.size()) + + value.size(); +} +inline int WireFormatLite::BytesSize(const string& value) { + return io::CodedOutputStream::VarintSize32(value.size()) + + value.size(); +} + + +inline int WireFormatLite::GroupSize(const MessageLite& value) { + return value.ByteSize(); +} +inline int WireFormatLite::MessageSize(const MessageLite& value) { + int size = value.ByteSize(); + return io::CodedOutputStream::VarintSize32(size) + size; +} + +template +inline int WireFormatLite::GroupSizeNoVirtual(const MessageType& value) { + return value.MessageType::ByteSize(); +} +template +inline int WireFormatLite::MessageSizeNoVirtual(const MessageType& value) { + int size = value.MessageType::ByteSize(); + return io::CodedOutputStream::VarintSize32(size) + size; +} + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc index 6352b0a6..51960ee7 100644 --- a/src/google/protobuf/wire_format_unittest.cc +++ b/src/google/protobuf/wire_format_unittest.cc @@ -33,7 +33,7 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include -#include +#include #include #include #include @@ -51,9 +51,27 @@ namespace protobuf { namespace internal { namespace { +TEST(WireFormatTest, EnumsInSync) { + // Verify that WireFormatLite::FieldType and WireFormatLite::CppType match + // FieldDescriptor::Type and FieldDescriptor::CppType. + + EXPECT_EQ(implicit_cast(FieldDescriptor::MAX_TYPE), + implicit_cast(WireFormatLite::MAX_FIELD_TYPE)); + EXPECT_EQ(implicit_cast(FieldDescriptor::MAX_CPPTYPE), + implicit_cast(WireFormatLite::MAX_CPPTYPE)); + + for (int i = 1; i <= WireFormatLite::MAX_FIELD_TYPE; i++) { + EXPECT_EQ( + implicit_cast(FieldDescriptor::TypeToCppType( + static_cast(i))), + implicit_cast(WireFormatLite::FieldTypeToCppType( + static_cast(i)))); + } +} + TEST(WireFormatTest, MaxFieldNumber) { // Make sure the max field number constant is accurate. - EXPECT_EQ((1 << (32 - WireFormat::kTagTypeBits)) - 1, + EXPECT_EQ((1 << (32 - WireFormatLite::kTagTypeBits)) - 1, FieldDescriptor::kMaxNumber); } @@ -326,9 +344,9 @@ TEST(WireFormatTest, SerializeMessageSet) { EXPECT_EQ("bar", raw.item(2).message()); } -TEST(WireFormatTest, SerializeMessageSetToStreamAndArrayAreEqual) { - // Serialize a MessageSet to a stream and to a flat array and check that the - // results are equal. +TEST(WireFormatTest, SerializeMessageSetVariousWaysAreEqual) { + // Serialize a MessageSet to a stream and to a flat array using generated + // code, and also using WireFormat, and check that the results are equal. // Set up a TestMessageSet with two known messages and an unknown one, as // above. @@ -341,10 +359,15 @@ TEST(WireFormatTest, SerializeMessageSetToStreamAndArrayAreEqual) { kUnknownTypeId, "bar"); int size = message_set.ByteSize(); + EXPECT_EQ(size, message_set.GetCachedSize()); + ASSERT_EQ(size, WireFormat::ByteSize(message_set)); + string flat_data; string stream_data; + string dynamic_data; flat_data.resize(size); stream_data.resize(size); + // Serialize to flat array { uint8* target = reinterpret_cast(string_as_array(&flat_data)); @@ -360,7 +383,16 @@ TEST(WireFormatTest, SerializeMessageSetToStreamAndArrayAreEqual) { ASSERT_FALSE(output_stream.HadError()); } + // Serialize to buffer with WireFormat. + { + io::StringOutputStream string_stream(&dynamic_data); + io::CodedOutputStream output_stream(&string_stream); + WireFormat::SerializeWithCachedSizes(message_set, size, &output_stream); + ASSERT_FALSE(output_stream.HadError()); + } + EXPECT_TRUE(flat_data == stream_data); + EXPECT_TRUE(flat_data == dynamic_data); } TEST(WireFormatTest, ParseMessageSet) { @@ -407,6 +439,13 @@ TEST(WireFormatTest, ParseMessageSet) { ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED, message_set.unknown_fields().field(0).type()); EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited()); + + // Also parse using WireFormat. + unittest::TestMessageSet dynamic_message_set; + io::CodedInputStream input(reinterpret_cast(data.data()), + data.size()); + ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &dynamic_message_set)); + EXPECT_EQ(message_set.DebugString(), dynamic_message_set.DebugString()); } TEST(WireFormatTest, RecursionLimit) { @@ -464,10 +503,10 @@ TEST(WireFormatTest, ZigZag) { // avoid line-wrapping #define LL(x) GOOGLE_LONGLONG(x) #define ULL(x) GOOGLE_ULONGLONG(x) -#define ZigZagEncode32(x) WireFormat::ZigZagEncode32(x) -#define ZigZagDecode32(x) WireFormat::ZigZagDecode32(x) -#define ZigZagEncode64(x) WireFormat::ZigZagEncode64(x) -#define ZigZagDecode64(x) WireFormat::ZigZagDecode64(x) +#define ZigZagEncode32(x) WireFormatLite::ZigZagEncode32(x) +#define ZigZagDecode32(x) WireFormatLite::ZigZagDecode32(x) +#define ZigZagEncode64(x) WireFormatLite::ZigZagEncode64(x) +#define ZigZagDecode64(x) WireFormatLite::ZigZagDecode64(x) EXPECT_EQ(0u, ZigZagEncode32( 0)); EXPECT_EQ(1u, ZigZagEncode32(-1)); @@ -545,7 +584,7 @@ class WireFormatInvalidInputTest : public testing::Test { io::StringOutputStream raw_output(&result); io::CodedOutputStream output(&raw_output); - WireFormat::WriteBytes(field->number(), string(bytes, size), &output); + WireFormatLite::WriteBytes(field->number(), string(bytes, size), &output); } return result; @@ -569,8 +608,8 @@ class WireFormatInvalidInputTest : public testing::Test { output.WriteVarint32(WireFormat::MakeTag(field)); output.WriteString(string(bytes, size)); if (include_end_tag) { - output.WriteVarint32(WireFormat::MakeTag( - field->number(), WireFormat::WIRETYPE_END_GROUP)); + output.WriteVarint32(WireFormatLite::MakeTag( + field->number(), WireFormatLite::WIRETYPE_END_GROUP)); } } -- cgit v1.2.3