From d64a2d9941c36a7bc2a7959ea10ab8363192ac14 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Wed, 29 Jun 2016 15:23:27 -0700 Subject: Integrated internal changes from Google This includes all internal changes from around May 20 to now. --- src/google/protobuf/any.pb.cc | 4 +- src/google/protobuf/any.pb.h | 8 +- src/google/protobuf/any.proto | 16 +- src/google/protobuf/api.pb.cc | 32 +- src/google/protobuf/api.pb.h | 24 +- src/google/protobuf/arena.cc | 11 +- src/google/protobuf/arena.h | 2 +- src/google/protobuf/arena_unittest.cc | 1 - .../protobuf/compiler/command_line_interface.cc | 27 +- src/google/protobuf/compiler/cpp/cpp_enum_field.cc | 2 +- src/google/protobuf/compiler/cpp/cpp_map_field.cc | 57 +- src/google/protobuf/compiler/cpp/cpp_message.cc | 39 +- .../protobuf/compiler/cpp/cpp_message_field.cc | 8 +- src/google/protobuf/compiler/cpp/cpp_options.h | 2 + src/google/protobuf/compiler/java/java_context.cc | 8 +- src/google/protobuf/compiler/java/java_context.h | 14 +- src/google/protobuf/compiler/java/java_enum.cc | 8 +- src/google/protobuf/compiler/java/java_enum.h | 5 +- .../protobuf/compiler/java/java_enum_field.cc | 29 +- .../protobuf/compiler/java/java_enum_field_lite.cc | 10 +- .../protobuf/compiler/java/java_enum_lite.cc | 17 +- src/google/protobuf/compiler/java/java_enum_lite.h | 5 +- src/google/protobuf/compiler/java/java_file.cc | 87 ++- src/google/protobuf/compiler/java/java_file.h | 11 +- .../protobuf/compiler/java/java_generator.cc | 87 ++- src/google/protobuf/compiler/java/java_helpers.cc | 23 +- src/google/protobuf/compiler/java/java_helpers.h | 54 +- .../compiler/java/java_lazy_message_field.cc | 12 +- .../compiler/java/java_lazy_message_field_lite.cc | 57 +- .../protobuf/compiler/java/java_map_field.cc | 396 ++++++++-- src/google/protobuf/compiler/java/java_map_field.h | 1 + .../protobuf/compiler/java/java_map_field_lite.cc | 502 ++++++++++-- src/google/protobuf/compiler/java/java_message.cc | 56 +- src/google/protobuf/compiler/java/java_message.h | 3 +- .../protobuf/compiler/java/java_message_field.cc | 35 +- .../protobuf/compiler/java/java_message_lite.cc | 35 +- .../protobuf/compiler/java/java_message_lite.h | 3 +- src/google/protobuf/compiler/java/java_options.h | 73 ++ .../protobuf/compiler/java/java_primitive_field.cc | 4 +- .../compiler/java/java_primitive_field_lite.cc | 38 +- src/google/protobuf/compiler/java/java_service.cc | 5 +- src/google/protobuf/compiler/java/java_service.h | 4 +- .../compiler/java/java_shared_code_generator.cc | 50 +- .../compiler/java/java_shared_code_generator.h | 13 +- .../protobuf/compiler/java/java_string_field.cc | 8 +- src/google/protobuf/compiler/js/js_generator.cc | 405 +++++++--- src/google/protobuf/compiler/main.cc | 8 + src/google/protobuf/compiler/parser.cc | 10 + src/google/protobuf/compiler/plugin.pb.cc | 20 +- src/google/protobuf/compiler/plugin.pb.h | 24 +- .../protobuf/compiler/python/python_generator.cc | 25 +- .../protobuf/compiler/python/python_generator.h | 2 + .../compiler/ruby/ruby_generator_unittest.cc | 20 +- src/google/protobuf/descriptor.cc | 21 +- src/google/protobuf/descriptor.h | 9 +- src/google/protobuf/descriptor.pb.cc | 861 +++++++++++++++------ src/google/protobuf/descriptor.pb.h | 384 +++++++-- src/google/protobuf/descriptor.proto | 9 + .../protobuf/descriptor_database_unittest.cc | 1 - src/google/protobuf/descriptor_unittest.cc | 10 +- src/google/protobuf/duration.pb.cc | 4 +- src/google/protobuf/duration.pb.h | 8 +- src/google/protobuf/dynamic_message.cc | 1 - src/google/protobuf/dynamic_message_unittest.cc | 3 +- src/google/protobuf/empty.pb.cc | 4 +- src/google/protobuf/empty.pb.h | 8 +- src/google/protobuf/extension_set.cc | 71 +- src/google/protobuf/extension_set.h | 71 +- src/google/protobuf/extension_set_heavy.cc | 85 +- src/google/protobuf/extension_set_unittest.cc | 68 ++ src/google/protobuf/field_mask.pb.cc | 4 +- src/google/protobuf/field_mask.pb.h | 8 +- src/google/protobuf/field_mask.proto | 52 ++ .../protobuf/generated_message_reflection.cc | 3 +- .../generated_message_reflection_unittest.cc | 67 ++ src/google/protobuf/io/coded_stream.cc | 117 ++- src/google/protobuf/io/coded_stream.h | 26 + src/google/protobuf/io/printer.h | 20 + .../protobuf/io/zero_copy_stream_impl_lite.h | 1 - src/google/protobuf/map.h | 20 +- src/google/protobuf/map_entry.h | 6 +- src/google/protobuf/map_entry_lite.h | 147 +++- src/google/protobuf/map_field_test.cc | 2 +- src/google/protobuf/map_test.cc | 204 ++++- src/google/protobuf/map_type_handler.h | 42 +- src/google/protobuf/message.h | 4 +- src/google/protobuf/message_lite.cc | 3 +- src/google/protobuf/message_lite.h | 27 +- src/google/protobuf/repeated_field.h | 30 +- src/google/protobuf/source_context.pb.cc | 4 +- src/google/protobuf/source_context.pb.h | 8 +- src/google/protobuf/source_context.proto | 2 +- src/google/protobuf/struct.pb.cc | 41 +- src/google/protobuf/struct.pb.h | 24 +- src/google/protobuf/stubs/mathlimits.h | 6 +- src/google/protobuf/stubs/port.h | 9 + src/google/protobuf/test_util.cc | 6 +- src/google/protobuf/testing/googletest.cc | 4 + src/google/protobuf/text_format.cc | 54 +- src/google/protobuf/text_format_unittest.cc | 75 +- src/google/protobuf/timestamp.pb.cc | 4 +- src/google/protobuf/timestamp.pb.h | 8 +- src/google/protobuf/type.pb.cc | 56 +- src/google/protobuf/type.pb.h | 40 +- src/google/protobuf/unittest.proto | 1 + src/google/protobuf/unittest_custom_options.proto | 9 + src/google/protobuf/util/field_mask_util.cc | 54 +- src/google/protobuf/util/field_mask_util.h | 12 +- src/google/protobuf/util/field_mask_util_test.cc | 115 +++ src/google/protobuf/util/internal/datapiece.cc | 30 +- src/google/protobuf/util/internal/datapiece.h | 10 +- src/google/protobuf/util/internal/json_escaping.cc | 2 +- src/google/protobuf/util/internal/object_writer.h | 1 + src/google/protobuf/util/internal/proto_writer.cc | 30 +- src/google/protobuf/util/internal/proto_writer.h | 4 + .../util/internal/protostream_objectsource.cc | 12 +- .../util/internal/protostream_objectsource.h | 4 + .../util/internal/protostream_objectwriter.cc | 9 +- .../util/internal/protostream_objectwriter.h | 12 +- src/google/protobuf/util/internal/utility.cc | 10 +- src/google/protobuf/util/internal/utility.h | 4 + src/google/protobuf/util/json_format_proto3.proto | 5 + src/google/protobuf/util/message_differencer.cc | 3 + src/google/protobuf/util/message_differencer.h | 6 + src/google/protobuf/wire_format_lite.h | 40 +- src/google/protobuf/wire_format_lite_inl.h | 46 +- src/google/protobuf/wrappers.pb.cc | 36 +- src/google/protobuf/wrappers.pb.h | 72 +- 128 files changed, 4351 insertions(+), 1318 deletions(-) create mode 100644 src/google/protobuf/compiler/java/java_options.h (limited to 'src/google/protobuf') diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index fbde4a6d..c91faa08 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -283,8 +283,8 @@ void Any::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Any) } -::google::protobuf::uint8* Any::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Any::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Any) // optional string type_url = 1; if (this->type_url().size() > 0) { diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index 100a67f6..d8cbee2d 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -42,7 +42,7 @@ class Any; // =================================================================== -class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Any) */ { public: Any(); virtual ~Any(); @@ -86,7 +86,11 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/src/google/protobuf/any.proto b/src/google/protobuf/any.proto index 45db6ede..81dcf46c 100644 --- a/src/google/protobuf/any.proto +++ b/src/google/protobuf/any.proto @@ -65,6 +65,16 @@ option objc_class_prefix = "GPB"; // foo = any.unpack(Foo.class); // } // +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// // The pack methods provided by protobuf library will by default use // 'type.googleapis.com/full.type.name' as the type URL and the unpack // methods only use the fully qualified type name after the last '/' @@ -104,10 +114,10 @@ message Any { // A URL/resource name whose content describes the type of the // serialized protocol buffer message. // - // For URLs which use the schema `http`, `https`, or no schema, the + // For URLs which use the scheme `http`, `https`, or no scheme, the // following restrictions and interpretations apply: // - // * If no schema is provided, `https` is assumed. + // * If no scheme is provided, `https` is assumed. // * The last segment of the URL's path must represent the fully // qualified name of the type (as in `path/google.protobuf.Duration`). // The name should be in a canonical form (e.g., leading "." is @@ -120,7 +130,7 @@ message Any { // on changes to types. (Use versioned type names to manage // breaking changes.) // - // Schemas other than `http`, `https` (or the empty schema) might be + // Schemes other than `http`, `https` (or the empty scheme) might be // used with implementation specific semantics. // string type_url = 1; diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index cbeba302..d5dd8923 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -475,8 +475,8 @@ void Api::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Api) } -::google::protobuf::uint8* Api::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Api::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Api) // optional string name = 1; if (this->name().size() > 0) { @@ -492,15 +492,15 @@ void Api::SerializeWithCachedSizes( // repeated .google.protobuf.Method methods = 2; for (unsigned int i = 0, n = this->methods_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, this->methods(i), target); + InternalWriteMessageNoVirtualToArray( + 2, this->methods(i), false, target); } // repeated .google.protobuf.Option options = 3; for (unsigned int i = 0, n = this->options_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 3, this->options(i), target); + InternalWriteMessageNoVirtualToArray( + 3, this->options(i), false, target); } // optional string version = 4; @@ -517,15 +517,15 @@ void Api::SerializeWithCachedSizes( // optional .google.protobuf.SourceContext source_context = 5; if (this->has_source_context()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, *this->source_context_, target); + InternalWriteMessageNoVirtualToArray( + 5, *this->source_context_, false, target); } // repeated .google.protobuf.Mixin mixins = 6; for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 6, this->mixins(i), target); + InternalWriteMessageNoVirtualToArray( + 6, this->mixins(i), false, target); } // optional .google.protobuf.Syntax syntax = 7; @@ -1225,8 +1225,8 @@ void Method::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Method) } -::google::protobuf::uint8* Method::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Method::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Method) // optional string name = 1; if (this->name().size() > 0) { @@ -1274,8 +1274,8 @@ void Method::SerializeWithCachedSizes( // repeated .google.protobuf.Option options = 6; for (unsigned int i = 0, n = this->options_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 6, this->options(i), target); + InternalWriteMessageNoVirtualToArray( + 6, this->options(i), false, target); } // optional .google.protobuf.Syntax syntax = 7; @@ -1803,8 +1803,8 @@ void Mixin::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Mixin) } -::google::protobuf::uint8* Mixin::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Mixin::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin) // optional string name = 1; if (this->name().size() > 0) { diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index bb35e471..c9ec923a 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -45,7 +45,7 @@ class Mixin; // =================================================================== -class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Api) */ { public: Api(); virtual ~Api(); @@ -79,7 +79,11 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -196,7 +200,7 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Method) */ { public: Method(); virtual ~Method(); @@ -230,7 +234,11 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -337,7 +345,7 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Mixin) */ { public: Mixin(); virtual ~Mixin(); @@ -371,7 +379,11 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index 613e5897..78e20946 100755 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -133,12 +133,7 @@ Arena::Block* Arena::NewBlock(void* me, Block* my_last_block, size_t n, Block* b = reinterpret_cast(options_.block_alloc(size)); b->pos = kHeaderSize + n; b->size = size; - if (b->avail() == 0) { - // Do not attempt to reuse this block. - b->owner = NULL; - } else { - b->owner = me; - } + b->owner = me; #ifdef ADDRESS_SANITIZER // Poison the rest of the block for ASAN. It was unpoisoned by the underlying // malloc but it's not yet usable until we return it as part of an allocation. @@ -223,9 +218,7 @@ void* Arena::SlowAlloc(size_t n) { } b = NewBlock(me, b, n, options_.start_block_size, options_.max_block_size); AddBlock(b); - if (b->owner == me) { // If this block can be reused (see NewBlock()). - SetThreadCacheBlock(b); - } + SetThreadCacheBlock(b); return reinterpret_cast(b) + kHeaderSize; } diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index cf07b9fc..58b1e126 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -801,7 +801,7 @@ class LIBPROTOBUF_EXPORT Arena { template static void CreateInArenaStorageInternal( T* ptr, Arena* arena, google::protobuf::internal::false_type) { - new (ptr) T; + new (ptr) T(); } template diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index ab25ffe1..5f33e939 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -42,7 +42,6 @@ #include #include -#include #include #include #include diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index c1a6c15d..df6f8afc 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -641,18 +641,23 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { return; } - // Seek backwards to the beginning of the line, which is where we will - // insert the data. Note that this has the effect of pushing the insertion - // point down, so the data is inserted before it. This is intentional - // because it means that multiple insertions at the same point will end - // up in the expected order in the final output. - pos = target->find_last_of('\n', pos); - if (pos == string::npos) { - // Insertion point is on the first line. - pos = 0; + if ((pos > 3) && (target->substr(pos - 3, 2) == "/*")) { + // Support for inline "/* @@protoc_insertion_point() */" + pos = pos - 3; } else { - // Advance to character after '\n'. - ++pos; + // Seek backwards to the beginning of the line, which is where we will + // insert the data. Note that this has the effect of pushing the + // insertion point down, so the data is inserted before it. This is + // intentional because it means that multiple insertions at the same point + // will end up in the expected order in the final output. + pos = target->find_last_of('\n', pos); + if (pos == string::npos) { + // Insertion point is on the first line. + pos = 0; + } else { + // Advance to character after '\n'. + ++pos; + } } // Extract indent. diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc index 10252b39..ffd81529 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -35,8 +35,8 @@ #include #include #include -#include #include +#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc index f585c31b..dd9f1887 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc @@ -182,33 +182,33 @@ GenerateConstructorCode(io::Printer* printer) const { void MapFieldGenerator:: GenerateMergeFromCodedStream(io::Printer* printer) const { + const FieldDescriptor* key_field = + descriptor_->message_type()->FindFieldByName("key"); const FieldDescriptor* value_field = descriptor_->message_type()->FindFieldByName("value"); - printer->Print(variables_, - "::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry());\n"); - + bool using_entry = false; + string key; + string value; if (IsProto3Field(descriptor_) || value_field->type() != FieldDescriptor::TYPE_ENUM) { printer->Print(variables_, + "$map_classname$::Parser< ::google::protobuf::internal::MapField$lite$<\n" + " $key_cpp$, $val_cpp$,\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" + " $default_enum_value$ >,\n" + " ::google::protobuf::Map< $key_cpp$, $val_cpp$ > >" + " parser(&$name$_);\n" "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n" - " input, entry.get()));\n"); - switch (value_field->cpp_type()) { - case FieldDescriptor::CPPTYPE_MESSAGE: - printer->Print(variables_, - "(*mutable_$name$())[entry->key()].Swap(" - "entry->mutable_value());\n"); - break; - case FieldDescriptor::CPPTYPE_ENUM: - printer->Print(variables_, - "(*mutable_$name$())[entry->key()] =\n" - " static_cast< $val_cpp$ >(*entry->mutable_value());\n"); - break; - default: - printer->Print(variables_, - "(*mutable_$name$())[entry->key()] = *entry->mutable_value();\n"); - break; - } + " input, &parser));\n"); + key = "parser.key()"; + value = "parser.value()"; } else { + using_entry = true; + key = "entry->key()"; + value = "entry->value()"; + printer->Print(variables_, + "::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry());\n"); printer->Print(variables_, "{\n" " ::std::string data;\n" @@ -229,28 +229,23 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { " unknown_fields_stream.WriteString(data);\n"); } - printer->Print(variables_, " }\n" "}\n"); } - const FieldDescriptor* key_field = - descriptor_->message_type()->FindFieldByName("key"); if (key_field->type() == FieldDescriptor::TYPE_STRING) { GenerateUtf8CheckCodeForString( - key_field, options_, true, variables_, - "entry->key().data(), entry->key().length(),\n", printer); + key_field, options_, true, variables_, + StrCat(key, ".data(), ", key, ".length(),\n").data(), printer); } if (value_field->type() == FieldDescriptor::TYPE_STRING) { GenerateUtf8CheckCodeForString(value_field, options_, true, variables_, - "entry->mutable_value()->data(),\n" - "entry->mutable_value()->length(),\n", - printer); + StrCat(value, ".data(), ", value, ".length(),\n").data(), printer); } // If entry is allocated by arena, its desctructor should be avoided. - if (SupportsArenas(descriptor_)) { + if (using_entry && SupportsArenas(descriptor_)) { printer->Print(variables_, "if (entry->GetArena() != NULL) entry.release();\n"); } @@ -333,8 +328,8 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { printer->Print(variables_, " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" " target = ::google::protobuf::internal::WireFormatLite::\n" - " Write$declared_type$NoVirtualToArray(\n" - " $number$, *entry, target);\n"); + " InternalWrite$declared_type$NoVirtualToArray(\n" + " $number$, *entry, false, target);\n"); printer->Indent(); printer->Indent(); diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index da2a4c92..32f63152 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -838,11 +838,13 @@ GenerateDependentBaseClassDefinition(io::Printer* printer) { map vars; vars["classname"] = DependentBaseClassTemplateName(descriptor_); + vars["full_name"] = descriptor_->full_name(); vars["superclass"] = SuperClassName(descriptor_, options_); printer->Print(vars, "template \n" - "class $classname$ : public $superclass$ {\n" + "class $classname$ : public $superclass$ " + "/* @@protoc_insertion_point(dep_base_class_definition:$full_name$) */ {\n" " public:\n"); printer->Indent(); @@ -878,6 +880,7 @@ GenerateClassDefinition(io::Printer* printer) { map vars; vars["classname"] = classname_; + vars["full_name"] = descriptor_->full_name(); vars["field_count"] = SimpleItoa(descriptor_->field_count()); vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count()); if (options_.dllexport_decl.empty()) { @@ -892,7 +895,9 @@ GenerateClassDefinition(io::Printer* printer) { vars["superclass"] = SuperClassName(descriptor_, options_); } printer->Print(vars, - "class $dllexport$$classname$ : public $superclass$ {\n"); + "class $dllexport$$classname$ : public $superclass$ " + "/* @@protoc_insertion_point(class_definition:$full_name$) */ " + "{\n"); printer->Annotate("classname", descriptor_); if (use_dependent_base_) { printer->Print(vars, " friend class $superclass$;\n"); @@ -1076,7 +1081,11 @@ GenerateClassDefinition(io::Printer* printer) { } if (HasFastArraySerialization(descriptor_->file(), options_)) { printer->Print( - "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n"); + "::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(\n" + " bool deterministic, ::google::protobuf::uint8* output) const;\n" + "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {\n" + " return InternalSerializeWithCachedSizesToArray(false, output);\n" + "}\n"); } } @@ -1095,6 +1104,13 @@ GenerateClassDefinition(io::Printer* printer) { descriptors.push_back(descriptor_->oneof_decl(i)->field(j)); } } + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + const Descriptor* nested_type = descriptor_->nested_type(i); + if (IsMapEntryMessage(nested_type)) { + descriptors.push_back(nested_type->FindFieldByName("key")); + descriptors.push_back(nested_type->FindFieldByName("value")); + } + } uses_string_ = false; if (PreserveUnknownFields(descriptor_) && !UseUnknownFieldSet(descriptor_->file(), options_)) { @@ -3267,8 +3283,8 @@ void MessageGenerator::GenerateSerializeOneExtensionRange( "// Extension range [$start$, $end$)\n"); if (to_array) { printer->Print(vars, - "target = _extensions_.SerializeWithCachedSizesToArray(\n" - " $start$, $end$, target);\n\n"); + "target = _extensions_.InternalSerializeWithCachedSizesToArray(\n" + " $start$, $end$, false, target);\n\n"); } else { printer->Print(vars, "_extensions_.SerializeWithCachedSizes(\n" @@ -3320,10 +3336,11 @@ 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", + "::google::protobuf::uint8* $classname$::InternalSerializeWithCachedSizesToArray(\n" + " bool deterministic, ::google::protobuf::uint8* target) const {\n" + " target = _extensions_." + "InternalSerializeMessageSetWithCachedSizesToArray(\n" + " deterministic, target);\n", "classname", classname_); GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_)); printer->Print( @@ -3337,8 +3354,8 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) { } printer->Print( - "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n" - " ::google::protobuf::uint8* target) const {\n", + "::google::protobuf::uint8* $classname$::InternalSerializeWithCachedSizesToArray(\n" + " bool deterministic, ::google::protobuf::uint8* target) const {\n", "classname", classname_); printer->Indent(); diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index 332c0264..d021035d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -520,8 +520,8 @@ void MessageFieldGenerator:: GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { printer->Print(variables_, "target = ::google::protobuf::internal::WireFormatLite::\n" - " Write$declared_type$NoVirtualToArray(\n" - " $number$, *$non_null_ptr_to_name$, target);\n"); + " InternalWrite$declared_type$NoVirtualToArray(\n" + " $number$, *$non_null_ptr_to_name$, false, target);\n"); } void MessageFieldGenerator:: @@ -1033,8 +1033,8 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { printer->Print(variables_, "for (unsigned int i = 0, n = this->$name$_size(); i < n; i++) {\n" " target = ::google::protobuf::internal::WireFormatLite::\n" - " Write$declared_type$NoVirtualToArray(\n" - " $number$, this->$name$(i), target);\n" + " InternalWrite$declared_type$NoVirtualToArray(\n" + " $number$, this->$name$(i), false, target);\n" "}\n"); } diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h index ab1d2ed3..ee44fb0a 100644 --- a/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/src/google/protobuf/compiler/cpp/cpp_options.h @@ -46,12 +46,14 @@ struct Options { Options() : safe_boundary_check(false), proto_h(false), + allow_import_public(true), annotate_headers(false), enforce_lite(false) {} string dllexport_decl; bool safe_boundary_check; bool proto_h; + bool allow_import_public; bool annotate_headers; bool enforce_lite; string annotation_pragma_name; diff --git a/src/google/protobuf/compiler/java/java_context.cc b/src/google/protobuf/compiler/java/java_context.cc index 0a112888..6cfa14a0 100644 --- a/src/google/protobuf/compiler/java/java_context.cc +++ b/src/google/protobuf/compiler/java/java_context.cc @@ -42,8 +42,8 @@ namespace protobuf { namespace compiler { namespace java { -Context::Context(const FileDescriptor* file) - : name_resolver_(new ClassNameResolver), enforce_lite_(false) { +Context::Context(const FileDescriptor* file, const Options& options) + : name_resolver_(new ClassNameResolver), options_(options) { InitializeFieldGeneratorInfo(file); } @@ -192,8 +192,8 @@ const OneofGeneratorInfo* Context::GetOneofGeneratorInfo( // Does this message class have generated parsing, serialization, and other // standard methods for which reflection-based fallback implementations exist? bool Context::HasGeneratedMethods(const Descriptor* descriptor) const { - return enforce_lite_ || descriptor->file()->options().optimize_for() != - FileOptions::CODE_SIZE; + return options_.enforce_lite || + descriptor->file()->options().optimize_for() != FileOptions::CODE_SIZE; } } // namespace java diff --git a/src/google/protobuf/compiler/java/java_context.h b/src/google/protobuf/compiler/java/java_context.h index a480e45d..f92ae87e 100644 --- a/src/google/protobuf/compiler/java/java_context.h +++ b/src/google/protobuf/compiler/java/java_context.h @@ -39,6 +39,7 @@ #include #include +#include namespace google { namespace protobuf { @@ -64,7 +65,7 @@ struct OneofGeneratorInfo; // generators. class Context { public: - explicit Context(const FileDescriptor* file); + Context(const FileDescriptor* file, const Options& options); ~Context(); // Get the name resolver associated with this context. The resolver @@ -79,15 +80,12 @@ class Context { const OneofGeneratorInfo* GetOneofGeneratorInfo( const OneofDescriptor* oneof) const; + const Options& options() const { return options_; } + // Enforces all the files (including transitive dependencies) to use // LiteRuntime. - void SetEnforceLite(bool enforce_lite) { - enforce_lite_ = enforce_lite; - } - bool EnforceLite() const { - return enforce_lite_; - } + bool EnforceLite() const { return options_.enforce_lite; } // Does this message class have generated parsing, serialization, and other // standard methods for which reflection-based fallback implementations exist? @@ -102,7 +100,7 @@ class Context { google::protobuf::scoped_ptr name_resolver_; map field_generator_info_map_; map oneof_generator_info_map_; - bool enforce_lite_; + Options options_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Context); }; diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc index 947b80e4..b46cfe9c 100644 --- a/src/google/protobuf/compiler/java/java_enum.cc +++ b/src/google/protobuf/compiler/java/java_enum.cc @@ -86,10 +86,12 @@ EnumGenerator::~EnumGenerator() {} void EnumGenerator::Generate(io::Printer* printer) { WriteEnumDocComment(printer, descriptor_); + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_); printer->Print( - "public enum $classname$\n" - " implements com.google.protobuf.ProtocolMessageEnum {\n", - "classname", descriptor_->name()); + "public enum $classname$\n" + " implements com.google.protobuf.ProtocolMessageEnum {\n", + "classname", descriptor_->name()); + printer->Annotate("classname", descriptor_); printer->Indent(); bool ordinal_is_index = true; diff --git a/src/google/protobuf/compiler/java/java_enum.h b/src/google/protobuf/compiler/java/java_enum.h index a0d91f5a..c33e713d 100644 --- a/src/google/protobuf/compiler/java/java_enum.h +++ b/src/google/protobuf/compiler/java/java_enum.h @@ -58,9 +58,8 @@ namespace java { class EnumGenerator { public: - explicit EnumGenerator(const EnumDescriptor* descriptor, - bool immutable_api, - Context* context); + EnumGenerator(const EnumDescriptor* descriptor, bool immutable_api, + Context* context); ~EnumGenerator(); void Generate(io::Printer* printer); diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc index 3e54be3d..2e916c56 100644 --- a/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/src/google/protobuf/compiler/java/java_enum_field.cc @@ -76,6 +76,11 @@ void SetEnumVariables(const FieldDescriptor* descriptor, (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; (*variables)["on_changed"] = "onChanged();"; + // Use deprecated valueOf() method to be compatible with old generated code + // for v2.5.0/v2.6.1. + // TODO(xiaofeng): Use "forNumber" when we no longer support compatibility + // with v2.5.0/v2.6.1. + (*variables)["for_number"] = "valueOf"; if (SupportFieldPresence(descriptor->file())) { // For singular messages and builders, one bit is used for the hasField bit. @@ -191,7 +196,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public $type$ get$capitalized_name$() {\n" - " $type$ result = $type$.forNumber($name$_);\n" + " $type$ result = $type$.$for_number$($name$_);\n" " return result == null ? $unknown$ : result;\n" "}\n"); } @@ -224,7 +229,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public $type$ get$capitalized_name$() {\n" - " $type$ result = $type$.forNumber($name$_);\n" + " $type$ result = $type$.$for_number$($name$_);\n" " return result == null ? $unknown$ : result;\n" "}\n"); WriteFieldDocComment(printer, descriptor_); @@ -304,7 +309,7 @@ GenerateParsingCode(io::Printer* printer) const { } else { printer->Print(variables_, "int rawValue = input.readEnum();\n" - "$type$ value = $type$.forNumber(rawValue);\n" + "$type$ value = $type$.$for_number$(rawValue);\n" "if (value == null) {\n"); if (PreserveUnknownFields(descriptor_->containing_type())) { printer->Print(variables_, @@ -398,7 +403,8 @@ GenerateMembers(io::Printer* printer) const { printer->Print(variables_, "$deprecation$public $type$ get$capitalized_name$() {\n" " if ($has_oneof_case_message$) {\n" - " $type$ result = $type$.forNumber((java.lang.Integer) $oneof_name$_);\n" + " $type$ result = $type$.$for_number$(\n" + " (java.lang.Integer) $oneof_name$_);\n" " return result == null ? $unknown$ : result;\n" " }\n" " return $default$;\n" @@ -436,7 +442,8 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Print(variables_, "$deprecation$public $type$ get$capitalized_name$() {\n" " if ($has_oneof_case_message$) {\n" - " $type$ result = $type$.forNumber((java.lang.Integer) $oneof_name$_);\n" + " $type$ result = $type$.$for_number$(\n" + " (java.lang.Integer) $oneof_name$_);\n" " return result == null ? $unknown$ : result;\n" " }\n" " return $default$;\n" @@ -493,7 +500,7 @@ GenerateParsingCode(io::Printer* printer) const { } else { printer->Print(variables_, "int rawValue = input.readEnum();\n" - "$type$ value = $type$.forNumber(rawValue);\n" + "$type$ value = $type$.$for_number$(rawValue);\n" "if (value == null) {\n"); if (PreserveUnknownFields(descriptor_->containing_type())) { printer->Print(variables_, @@ -606,7 +613,7 @@ GenerateMembers(io::Printer* printer) const { " new com.google.protobuf.Internal.ListAdapter.Converter<\n" " java.lang.Integer, $type$>() {\n" " public $type$ convert(java.lang.Integer from) {\n" - " $type$ result = $type$.forNumber(from);\n" + " $type$ result = $type$.$for_number$(from);\n" " return result == null ? $unknown$ : result;\n" " }\n" " };\n"); @@ -839,7 +846,7 @@ GenerateParsingCode(io::Printer* printer) const { } else { printer->Print(variables_, "int rawValue = input.readEnum();\n" - "$type$ value = $type$.forNumber(rawValue);\n" + "$type$ value = $type$.$for_number$(rawValue);\n" "if (value == null) {\n"); if (PreserveUnknownFields(descriptor_->containing_type())) { printer->Print(variables_, @@ -887,8 +894,8 @@ GenerateSerializationCode(io::Printer* printer) const { if (descriptor_->is_packed()) { printer->Print(variables_, "if (get$capitalized_name$List().size() > 0) {\n" - " output.writeRawVarint32($tag$);\n" - " output.writeRawVarint32($name$MemoizedSerializedSize);\n" + " output.writeUInt32NoTag($tag$);\n" + " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n" "}\n" "for (int i = 0; i < $name$_.size(); i++) {\n" " output.writeEnumNoTag($name$_.get(i));\n" @@ -920,7 +927,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { "if (!get$capitalized_name$List().isEmpty()) {" " size += $tag_size$;\n" " size += com.google.protobuf.CodedOutputStream\n" - " .computeRawVarint32Size(dataSize);\n" + " .computeUInt32SizeNoTag(dataSize);\n" "}"); } else { printer->Print(variables_, diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc index 908d6db4..aa0eb5e8 100644 --- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc @@ -258,7 +258,9 @@ GenerateFieldBuilderInitializationCode(io::Printer* printer) const { void ImmutableEnumFieldLiteGenerator:: GenerateInitializationCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_ = $default_number$;\n"); + if (!IsDefaultValueJavaDefault(descriptor_)) { + printer->Print(variables_, "$name$_ = $default_number$;\n"); + } } void ImmutableEnumFieldLiteGenerator:: @@ -885,8 +887,8 @@ GenerateSerializationCode(io::Printer* printer) const { if (descriptor_->options().packed()) { printer->Print(variables_, "if (get$capitalized_name$List().size() > 0) {\n" - " output.writeRawVarint32($tag$);\n" - " output.writeRawVarint32($name$MemoizedSerializedSize);\n" + " output.writeUInt32NoTag($tag$);\n" + " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n" "}\n" "for (int i = 0; i < $name$_.size(); i++) {\n" " output.writeEnumNoTag($name$_.getInt(i));\n" @@ -918,7 +920,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { "if (!get$capitalized_name$List().isEmpty()) {" " size += $tag_size$;\n" " size += com.google.protobuf.CodedOutputStream\n" - " .computeRawVarint32Size(dataSize);\n" + " .computeUInt32SizeNoTag(dataSize);\n" "}"); } else { printer->Print(variables_, diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc index c22da8d7..99f52d40 100644 --- a/src/google/protobuf/compiler/java/java_enum_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_lite.cc @@ -61,10 +61,11 @@ bool EnumHasCustomOptions(const EnumDescriptor* descriptor) { } // namespace EnumLiteGenerator::EnumLiteGenerator(const EnumDescriptor* descriptor, - bool immutable_api, - Context* context) - : descriptor_(descriptor), immutable_api_(immutable_api), - name_resolver_(context->GetNameResolver()) { + bool immutable_api, Context* context) + : descriptor_(descriptor), + immutable_api_(immutable_api), + context_(context), + name_resolver_(context->GetNameResolver()) { for (int i = 0; i < descriptor_->value_count(); i++) { const EnumValueDescriptor* value = descriptor_->value(i); const EnumValueDescriptor* canonical_value = @@ -85,10 +86,12 @@ EnumLiteGenerator::~EnumLiteGenerator() {} void EnumLiteGenerator::Generate(io::Printer* printer) { WriteEnumDocComment(printer, descriptor_); + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_); printer->Print( - "public enum $classname$\n" - " implements com.google.protobuf.Internal.EnumLite {\n", - "classname", descriptor_->name()); + "public enum $classname$\n" + " implements com.google.protobuf.Internal.EnumLite {\n", + "classname", descriptor_->name()); + printer->Annotate("classname", descriptor_); printer->Indent(); for (int i = 0; i < canonical_values_.size(); i++) { diff --git a/src/google/protobuf/compiler/java/java_enum_lite.h b/src/google/protobuf/compiler/java/java_enum_lite.h index ee2f5f7a..f27cb76f 100644 --- a/src/google/protobuf/compiler/java/java_enum_lite.h +++ b/src/google/protobuf/compiler/java/java_enum_lite.h @@ -58,9 +58,8 @@ namespace java { class EnumLiteGenerator { public: - explicit EnumLiteGenerator(const EnumDescriptor* descriptor, - bool immutable_api, - Context* context); + EnumLiteGenerator(const EnumDescriptor* descriptor, bool immutable_api, + Context* context); ~EnumLiteGenerator(); void Generate(io::Printer* printer); diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index c53aae6b..a06c5f6d 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -193,19 +193,19 @@ void MaybeRestartJavaMethod(io::Printer* printer, } // namespace -FileGenerator::FileGenerator(const FileDescriptor* file, bool immutable_api, - bool enforce_lite) +FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options, + bool immutable_api) : file_(file), java_package_(FileJavaPackage(file, immutable_api)), message_generators_( new google::protobuf::scoped_ptr[file->message_type_count()]), extension_generators_( new google::protobuf::scoped_ptr[file->extension_count()]), - context_(new Context(file)), + context_(new Context(file, options)), name_resolver_(context_->GetNameResolver()), + options_(options), immutable_api_(immutable_api) { classname_ = name_resolver_->GetFileClassName(file, immutable_api); - context_->SetEnforceLite(enforce_lite); generator_factory_.reset( new ImmutableGeneratorFactory(context_.get())); for (int i = 0; i < file_->message_type_count(); ++i) { @@ -253,10 +253,13 @@ void FileGenerator::Generate(io::Printer* printer) { "\n", "package", java_package_); } + PrintGeneratedAnnotation( + printer, '$', options_.annotate_code ? classname_ + ".java.pb.meta" : ""); printer->Print( - "public final class $classname$ {\n" - " private $classname$() {}\n", - "classname", classname_); + "public final class $classname$ {\n" + " private $ctor$() {}\n", + "classname", classname_, "ctor", classname_); + printer->Annotate("classname", file_->name()); printer->Indent(); // ----------------------------------------------------------------- @@ -372,7 +375,7 @@ void FileGenerator::GenerateDescriptorInitializationCodeForImmutable( "final", ""); printer->Indent(); - SharedCodeGenerator shared_code_generator(file_); + SharedCodeGenerator shared_code_generator(file_, options_); shared_code_generator.GenerateDescriptors(printer); int bytecode_estimate = 0; @@ -523,20 +526,26 @@ void FileGenerator::GenerateDescriptorInitializationCodeForMutable(io::Printer* "}\n"); } -template +template static void GenerateSibling(const string& package_dir, const string& java_package, const DescriptorClass* descriptor, GeneratorContext* context, - vector* file_list, + vector* file_list, bool annotate_code, + vector* annotation_list, const string& name_suffix, GeneratorClass* generator, void (GeneratorClass::*pfn)(io::Printer* printer)) { string filename = package_dir + descriptor->name() + name_suffix + ".java"; file_list->push_back(filename); + string info_full_path = filename + ".pb.meta"; + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector annotation_collector( + &annotations); google::protobuf::scoped_ptr output(context->Open(filename)); - io::Printer printer(output.get(), '$'); + io::Printer printer(output.get(), '$', + annotate_code ? &annotation_collector : NULL); printer.Print( "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" @@ -551,55 +560,57 @@ static void GenerateSibling(const string& package_dir, } (generator->*pfn)(&printer); + + if (annotate_code) { + google::protobuf::scoped_ptr info_output( + context->Open(info_full_path)); + annotations.SerializeToZeroCopyStream(info_output.get()); + annotation_list->push_back(info_full_path); + } } void FileGenerator::GenerateSiblings(const string& package_dir, GeneratorContext* context, - vector* file_list) { + vector* file_list, + vector* annotation_list) { if (MultipleJavaFiles(file_, immutable_api_)) { for (int i = 0; i < file_->enum_type_count(); i++) { if (HasDescriptorMethods(file_, context_->EnforceLite())) { EnumGenerator generator(file_->enum_type(i), immutable_api_, context_.get()); - GenerateSibling(package_dir, java_package_, - file_->enum_type(i), - context, file_list, "", - &generator, - &EnumGenerator::Generate); + GenerateSibling( + package_dir, java_package_, file_->enum_type(i), context, file_list, + options_.annotate_code, annotation_list, "", &generator, + &EnumGenerator::Generate); } else { EnumLiteGenerator generator(file_->enum_type(i), immutable_api_, context_.get()); - GenerateSibling(package_dir, java_package_, - file_->enum_type(i), - context, file_list, "", - &generator, - &EnumLiteGenerator::Generate); + GenerateSibling( + package_dir, java_package_, file_->enum_type(i), context, file_list, + options_.annotate_code, annotation_list, "", &generator, + &EnumLiteGenerator::Generate); } } for (int i = 0; i < file_->message_type_count(); i++) { if (immutable_api_) { - GenerateSibling(package_dir, java_package_, - file_->message_type(i), - context, file_list, - "OrBuilder", - message_generators_[i].get(), - &MessageGenerator::GenerateInterface); + GenerateSibling( + package_dir, java_package_, file_->message_type(i), context, + file_list, options_.annotate_code, annotation_list, "OrBuilder", + message_generators_[i].get(), &MessageGenerator::GenerateInterface); } - GenerateSibling(package_dir, java_package_, - file_->message_type(i), - context, file_list, "", - message_generators_[i].get(), - &MessageGenerator::Generate); + GenerateSibling( + package_dir, java_package_, file_->message_type(i), context, + file_list, options_.annotate_code, annotation_list, "", + message_generators_[i].get(), &MessageGenerator::Generate); } if (HasGenericServices(file_, context_->EnforceLite())) { for (int i = 0; i < file_->service_count(); i++) { google::protobuf::scoped_ptr generator( generator_factory_->NewServiceGenerator(file_->service(i))); - GenerateSibling(package_dir, java_package_, - file_->service(i), - context, file_list, "", - generator.get(), - &ServiceGenerator::Generate); + GenerateSibling( + package_dir, java_package_, file_->service(i), context, file_list, + options_.annotate_code, annotation_list, "", generator.get(), + &ServiceGenerator::Generate); } } } diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h index 7dbeb94e..1e643f79 100644 --- a/src/google/protobuf/compiler/java/java_file.h +++ b/src/google/protobuf/compiler/java/java_file.h @@ -42,6 +42,7 @@ #include #include #include +#include namespace google { namespace protobuf { @@ -67,8 +68,8 @@ namespace java { class FileGenerator { public: - FileGenerator(const FileDescriptor* file, bool immutable_api = true, - bool enforce_lite = false); + FileGenerator(const FileDescriptor* file, const Options& options, + bool immutable_api = true); ~FileGenerator(); // Checks for problems that would otherwise lead to cryptic compile errors. @@ -83,12 +84,12 @@ class FileGenerator { // service type). void GenerateSiblings(const string& package_dir, GeneratorContext* generator_context, - vector* file_list); + vector* file_list, + vector* annotation_list); const string& java_package() { return java_package_; } const string& classname() { return classname_; } - private: void GenerateDescriptorInitializationCodeForImmutable(io::Printer* printer); void GenerateDescriptorInitializationCodeForMutable(io::Printer* printer); @@ -105,9 +106,9 @@ class FileGenerator { google::protobuf::scoped_ptr generator_factory_; google::protobuf::scoped_ptr context_; ClassNameResolver* name_resolver_; + const Options options_; bool immutable_api_; - 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 a46c7fc4..3c545e15 100644 --- a/src/google/protobuf/compiler/java/java_generator.cc +++ b/src/google/protobuf/compiler/java/java_generator.cc @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -64,63 +65,60 @@ bool JavaGenerator::Generate(const FileDescriptor* file, // ----------------------------------------------------------------- // parse generator options - // Name a file where we will write a list of generated file names, one - // per line. - string output_list_file; - vector > options; ParseGeneratorParameter(parameter, &options); + Options file_options; - bool generate_immutable_code = false; - bool generate_mutable_code = false; - bool generate_shared_code = false; - bool enforce_lite = false; for (int i = 0; i < options.size(); i++) { if (options[i].first == "output_list_file") { - output_list_file = options[i].second; + file_options.output_list_file = options[i].second; } else if (options[i].first == "immutable") { - generate_immutable_code = true; + file_options.generate_immutable_code = true; } else if (options[i].first == "mutable") { - generate_mutable_code = true; + file_options.generate_mutable_code = true; } else if (options[i].first == "shared") { - generate_shared_code = true; + file_options.generate_shared_code = true; } else if (options[i].first == "lite") { - // When set, the protoc will generate the current files and all the - // transitive dependencies as lite runtime. - enforce_lite = true; + file_options.enforce_lite = true; + } else if (options[i].first == "annotate_code") { + file_options.annotate_code = true; + } else if (options[i].first == "annotation_list_file") { + file_options.annotation_list_file = options[i].second; } else { *error = "Unknown generator option: " + options[i].first; return false; } } - if (enforce_lite && generate_mutable_code) { + if (file_options.enforce_lite && file_options.generate_mutable_code) { *error = "lite runtime generator option cannot be used with mutable API."; return false; } // By default we generate immutable code and shared code for immutable API. - if (!generate_immutable_code && !generate_mutable_code && - !generate_shared_code) { - generate_immutable_code = true; - generate_shared_code = true; + if (!file_options.generate_immutable_code && + !file_options.generate_mutable_code && + !file_options.generate_shared_code) { + file_options.generate_immutable_code = true; + file_options.generate_shared_code = true; } // ----------------------------------------------------------------- vector all_files; + vector all_annotations; vector file_generators; - if (generate_immutable_code) { - file_generators.push_back( - new FileGenerator(file, /* immutable = */ true, enforce_lite)); + if (file_options.generate_immutable_code) { + file_generators.push_back(new FileGenerator(file, file_options, + /* immutable = */ true)); } - if (generate_mutable_code) { - file_generators.push_back( - new FileGenerator(file, /* mutable = */ false, enforce_lite)); + if (file_options.generate_mutable_code) { + file_generators.push_back(new FileGenerator(file, file_options, + /* mutable = */ false)); } for (int i = 0; i < file_generators.size(); ++i) { if (!file_generators[i]->Validate(error)) { @@ -140,15 +138,32 @@ bool JavaGenerator::Generate(const FileDescriptor* file, java_filename += file_generator->classname(); java_filename += ".java"; all_files.push_back(java_filename); + string info_full_path = java_filename + ".pb.meta"; + if (file_options.annotate_code) { + all_annotations.push_back(info_full_path); + } // Generate main java file. google::protobuf::scoped_ptr output( context->Open(java_filename)); - io::Printer printer(output.get(), '$'); + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector annotation_collector( + &annotations); + io::Printer printer(output.get(), '$', file_options.annotate_code + ? &annotation_collector + : NULL); + file_generator->Generate(&printer); // Generate sibling files. - file_generator->GenerateSiblings(package_dir, context, &all_files); + file_generator->GenerateSiblings(package_dir, context, &all_files, + &all_annotations); + + if (file_options.annotate_code) { + google::protobuf::scoped_ptr info_output( + context->Open(info_full_path)); + annotations.SerializeToZeroCopyStream(info_output.get()); + } } for (int i = 0; i < file_generators.size(); ++i) { @@ -157,17 +172,29 @@ bool JavaGenerator::Generate(const FileDescriptor* file, file_generators.clear(); // Generate output list if requested. - if (!output_list_file.empty()) { + if (!file_options.output_list_file.empty()) { // Generate output list. This is just a simple text file placed in a // deterministic location which lists the .java files being generated. google::protobuf::scoped_ptr srclist_raw_output( - context->Open(output_list_file)); + context->Open(file_options.output_list_file)); io::Printer srclist_printer(srclist_raw_output.get(), '$'); for (int i = 0; i < all_files.size(); i++) { srclist_printer.Print("$filename$\n", "filename", all_files[i]); } } + if (!file_options.annotation_list_file.empty()) { + // Generate output list. This is just a simple text file placed in a + // deterministic location which lists the .java files being generated. + google::protobuf::scoped_ptr annotation_list_raw_output( + context->Open(file_options.annotation_list_file)); + io::Printer annotation_list_printer(annotation_list_raw_output.get(), '$'); + for (int i = 0; i < all_annotations.size(); i++) { + annotation_list_printer.Print("$filename$\n", "filename", + all_annotations[i]); + } + } + return true; } diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc index e24894b1..c31df265 100644 --- a/src/google/protobuf/compiler/java/java_helpers.cc +++ b/src/google/protobuf/compiler/java/java_helpers.cc @@ -101,6 +101,20 @@ string FieldName(const FieldDescriptor* field) { } // namespace +void PrintGeneratedAnnotation(io::Printer* printer, char delimiter, + const string& annotation_file) { + if (annotation_file.empty()) { + return; + } + string ptemplate = + "@javax.annotation.Generated(value=\"protoc\", comments=\"annotations:"; + ptemplate.push_back(delimiter); + ptemplate.append("annotation_file"); + ptemplate.push_back(delimiter); + ptemplate.append("\")\n"); + printer->Print(ptemplate.c_str(), "annotation_file", annotation_file); +} + string UnderscoresToCamelCase(const string& input, bool cap_next_letter) { string result; // Note: I distrust ctype.h due to locales. @@ -481,9 +495,9 @@ bool IsDefaultValueJavaDefault(const FieldDescriptor* field) { return field->default_value_float() == 0.0; case FieldDescriptor::CPPTYPE_BOOL: return field->default_value_bool() == false; - - case FieldDescriptor::CPPTYPE_STRING: case FieldDescriptor::CPPTYPE_ENUM: + return field->default_value_enum()->number() == 0; + case FieldDescriptor::CPPTYPE_STRING: case FieldDescriptor::CPPTYPE_MESSAGE: return false; @@ -495,6 +509,11 @@ bool IsDefaultValueJavaDefault(const FieldDescriptor* field) { return false; } +bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field) { + return GetJavaType(field) == JAVATYPE_BYTES && + field->default_value_string() != ""; +} + const char* bit_masks[] = { "0x00000001", "0x00000002", diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h index c850423e..5316d2f9 100644 --- a/src/google/protobuf/compiler/java/java_helpers.h +++ b/src/google/protobuf/compiler/java/java_helpers.h @@ -36,6 +36,8 @@ #define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ #include +#include +#include #include #include @@ -49,6 +51,17 @@ namespace java { extern const char kThickSeparator[]; extern const char kThinSeparator[]; +// If annotation_file is non-empty, prints a javax.annotation.Generated +// annotation to the given Printer. annotation_file will be referenced in the +// annotation's comments field. delimiter should be the Printer's delimiter +// character. annotation_file will be included verbatim into a Java literal +// string, so it should not contain quotes or invalid Java escape sequences; +// however, these are unlikely to appear in practice, as the value of +// annotation_file should be generated from the filename of the source file +// being annotated (which in turn must be a Java identifier plus ".java"). +void PrintGeneratedAnnotation(io::Printer* printer, char delimiter = '$', + const string& annotation_file = ""); + // Converts a name to camel-case. If cap_first_letter is true, capitalize the // first letter. string UnderscoresToCamelCase(const string& name, bool cap_first_letter); @@ -126,6 +139,38 @@ inline bool MultipleJavaFiles( return descriptor->options().java_multiple_files(); } +// Returns true if `descriptor` will be written to its own .java file. +// `immutable` should be set to true if we're generating for the immutable API. +template +bool IsOwnFile(const Descriptor* descriptor, bool immutable) { + return descriptor->containing_type() == NULL && + MultipleJavaFiles(descriptor->file(), immutable); +} + +template <> +inline bool IsOwnFile(const ServiceDescriptor* descriptor, bool immutable) { + return MultipleJavaFiles(descriptor->file(), immutable); +} + +// If `descriptor` describes an object with its own .java file, +// returns the name (relative to that .java file) of the file that stores +// annotation data for that descriptor. `suffix` is usually empty, but may +// (e.g.) be "OrBuilder" for some generated interfaces. +template +string AnnotationFileName(const Descriptor* descriptor, const string& suffix) { + return descriptor->name() + suffix + ".java.pb.meta"; +} + +template +void MaybePrintGeneratedAnnotation(Context* context, io::Printer* printer, + Descriptor* descriptor, bool immutable, + const string& suffix = "") { + if (context->options().annotate_code && IsOwnFile(descriptor, immutable)) { + PrintGeneratedAnnotation(printer, '$', + AnnotationFileName(descriptor, suffix)); + } +} + // Get the unqualified name that should be used for a field's field // number constant. string FieldConstantName(const FieldDescriptor *field); @@ -169,11 +214,7 @@ inline string ImmutableDefaultValue(const FieldDescriptor* field, return DefaultValue(field, true, name_resolver); } bool IsDefaultValueJavaDefault(const FieldDescriptor* field); - -// Does this message have specialized equals() and hashCode() methods? -inline bool HasEqualsAndHashCode(const Descriptor* descriptor) { - return descriptor->file()->options().java_generate_equals_and_hash(); -} +bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field); // Does this message class have descriptor and reflection methods? inline bool HasDescriptorMethods(const Descriptor* descriptor, @@ -344,6 +385,9 @@ inline bool CheckUtf8(const FieldDescriptor* descriptor) { descriptor->file()->options().java_string_check_utf8(); } +inline string GeneratedCodeVersionSuffix() { + return "V3"; +} } // namespace java } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field.cc b/src/google/protobuf/compiler/java/java_lazy_message_field.cc index 0de8cbe5..abf8e55c 100644 --- a/src/google/protobuf/compiler/java/java_lazy_message_field.cc +++ b/src/google/protobuf/compiler/java/java_lazy_message_field.cc @@ -93,7 +93,7 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Print(variables_, // If this builder is non-null, it is used and the other fields are // ignored. - "private com.google.protobuf.SingleFieldBuilder<\n" + "private com.google.protobuf.SingleFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" "\n"); @@ -193,11 +193,11 @@ GenerateBuilderMembers(io::Printer* printer) const { "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "private com.google.protobuf.SingleFieldBuilder<\n" + "private com.google.protobuf.SingleFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder> \n" " get$capitalized_name$FieldBuilder() {\n" " if ($name$Builder_ == null) {\n" - " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n" + " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder>(\n" " $name$_,\n" " getParentForChildren(),\n" @@ -535,7 +535,7 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Print(variables_, // If this builder is non-null, it is used and the other fields are // ignored. - "private com.google.protobuf.RepeatedFieldBuilder<\n" + "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n" "\n"); @@ -763,11 +763,11 @@ GenerateBuilderMembers(io::Printer* printer) const { " get$capitalized_name$BuilderList() {\n" " return get$capitalized_name$FieldBuilder().getBuilderList();\n" "}\n" - "private com.google.protobuf.RepeatedFieldBuilder<\n" + "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder> \n" " get$capitalized_name$FieldBuilder() {\n" " if ($name$Builder_ == null) {\n" - " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\n" + " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder>(\n" " $name$_,\n" " $get_mutable_bit_builder$,\n" diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc index 62f39302..dac1b51f 100644 --- a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc @@ -59,19 +59,28 @@ ImmutableLazyMessageFieldLiteGenerator:: void ImmutableLazyMessageFieldLiteGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, - "private com.google.protobuf.LazyFieldLite $name$_ =\n" - " new com.google.protobuf.LazyFieldLite();\n"); + "private com.google.protobuf.LazyFieldLite $name$_;"); PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $get_has_field_bit_message$;\n" - "}\n"); + if (SupportFieldPresence(descriptor_->file())) { + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + } else { + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $name$_ != null;\n" + "}\n"); + } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public $type$ get$capitalized_name$() {\n" + " if ($name$_ == null) {\n" + " return $type$.getDefaultInstance();\n" + " }\n" " return ($type$) $name$_.getValue($type$.getDefaultInstance());\n" "}\n"); @@ -82,8 +91,11 @@ GenerateMembers(io::Printer* printer) const { " if (value == null) {\n" " throw new NullPointerException();\n" " }\n" + " if ($name$_ == null) {\n" + " $name$_ = new com.google.protobuf.LazyFieldLite();\n" + " }\n" " $name$_.setValue(value);\n" - " $set_has_field_bit_message$;\n" + " $set_has_field_bit_message$\n" "}\n"); // Field.Builder setField(Field.Builder builderForValue) @@ -91,30 +103,36 @@ GenerateMembers(io::Printer* printer) const { printer->Print(variables_, "private void set$capitalized_name$(\n" " $type$.Builder builderForValue) {\n" + " if ($name$_ == null) {\n" + " $name$_ = new com.google.protobuf.LazyFieldLite();\n" + " }\n" " $name$_.setValue(builderForValue.build());\n" - " $set_has_field_bit_message$;\n" + " $set_has_field_bit_message$\n" "}\n"); // Field.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "private void merge$capitalized_name$($type$ value) {\n" - " if ($get_has_field_bit_message$ &&\n" + " if (has$capitalized_name$() &&\n" " !$name$_.containsDefaultInstance()) {\n" " $name$_.setValue(\n" " $type$.newBuilder(\n" " get$capitalized_name$()).mergeFrom(value).buildPartial());\n" " } else {\n" + " if ($name$_ == null) {\n" + " $name$_ = new com.google.protobuf.LazyFieldLite();\n" + " }\n" " $name$_.setValue(value);\n" + " $set_has_field_bit_message$\n" " }\n" - " $set_has_field_bit_message$;\n" "}\n"); // Field.Builder clearField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "private void clear$capitalized_name$() {\n" - " $name$_.clear();\n" + " $name$_ = null;\n" " $clear_has_field_bit_message$;\n" "}\n"); } @@ -177,31 +195,30 @@ GenerateBuilderMembers(io::Printer* printer) const { void ImmutableLazyMessageFieldLiteGenerator:: -GenerateInitializationCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.clear();\n"); -} +GenerateInitializationCode(io::Printer* printer) const {} void ImmutableLazyMessageFieldLiteGenerator:: GenerateVisitCode(io::Printer* printer) const { printer->Print(variables_, - "$name$_ = visitor.visitLazyMessage(\n" - " has$capitalized_name$(), $name$_,\n" - " other.has$capitalized_name$(), other.$name$_);\n"); + "$name$_ = visitor.visitLazyMessage($name$_, other.$name$_);\n"); } void ImmutableLazyMessageFieldLiteGenerator:: GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, + "if ($name$_ == null) {\n" + " $name$_ = new com.google.protobuf.LazyFieldLite();\n" + "}\n" "$name$_.mergeFrom(input, extensionRegistry);\n"); printer->Print(variables_, - "$set_has_field_bit_message$;\n"); + "$set_has_field_bit_message$\n"); } void ImmutableLazyMessageFieldLiteGenerator:: GenerateSerializationCode(io::Printer* printer) const { // Do not de-serialize lazy fields. printer->Print(variables_, - "if ($get_has_field_bit_message$) {\n" + "if (has$capitalized_name$()) {\n" " output.writeBytes($number$, $name$_.toByteString());\n" "}\n"); } @@ -209,7 +226,7 @@ GenerateSerializationCode(io::Printer* printer) const { void ImmutableLazyMessageFieldLiteGenerator:: GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print(variables_, - "if ($get_has_field_bit_message$) {\n" + "if (has$capitalized_name$()) {\n" " size += com.google.protobuf.CodedOutputStream\n" " .computeLazyFieldSize($number$, $name$_);\n" "}\n"); diff --git a/src/google/protobuf/compiler/java/java_map_field.cc b/src/google/protobuf/compiler/java/java_map_field.cc index 2a551ca4..16c5bec5 100644 --- a/src/google/protobuf/compiler/java/java_map_field.cc +++ b/src/google/protobuf/compiler/java/java_map_field.cc @@ -88,11 +88,18 @@ void SetMessageVariables(const FieldDescriptor* descriptor, name_resolver->GetImmutableClassName(descriptor->message_type()); const FieldDescriptor* key = KeyField(descriptor); const FieldDescriptor* value = ValueField(descriptor); + const JavaType keyJavaType = GetJavaType(key); + const JavaType valueJavaType = GetJavaType(value); + (*variables)["key_type"] = TypeName(key, name_resolver, false); (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true); (*variables)["key_wire_type"] = WireType(key); (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver); - if (GetJavaType(value) == JAVATYPE_ENUM) { + (*variables)["key_null_check"] = IsReferenceType(keyJavaType) ? + "if (key == null) { throw new java.lang.NullPointerException(); }" : ""; + (*variables)["value_null_check"] = IsReferenceType(valueJavaType) ? + "if (value == null) { throw new java.lang.NullPointerException(); }" : ""; + if (valueJavaType == JAVATYPE_ENUM) { // We store enums as Integers internally. (*variables)["value_type"] = "int"; (*variables)["boxed_value_type"] = "java.lang.Integer"; @@ -135,7 +142,6 @@ void SetMessageVariables(const FieldDescriptor* descriptor, (*variables)["default_entry"] = (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry"; - (*variables)["lite"] = ""; (*variables)["map_field_parameter"] = (*variables)["default_entry"]; (*variables)["descriptor"] = name_resolver->GetImmutableClassName(descriptor->file()) + @@ -169,25 +175,95 @@ int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const { void ImmutableMapFieldGenerator:: GenerateInterfaceMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$boolean contains$capitalized_name$(\n" + " $key_type$ key);\n"); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "get$capitalized_name$();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$();\n"); + "get$capitalized_name$Map();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$$value_enum_type$ get$capitalized_name$OrDefault(\n" + " $key_type$ key,\n" + " $value_enum_type$ defaultValue);\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$$value_enum_type$ get$capitalized_name$OrThrow(\n" + " $key_type$ key);\n"); if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$type_parameters$>\n" + "get$capitalized_name$Value();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$type_parameters$>\n" - "get$capitalized_name$Value();\n"); + "get$capitalized_name$ValueMap();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "$value_type$ get$capitalized_name$ValueOrDefault(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue);\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "$value_type$ get$capitalized_name$ValueOrThrow(\n" + " $key_type$ key);\n"); } } else { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$type_parameters$>\n" + "get$capitalized_name$();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$type_parameters$>\n" - "get$capitalized_name$();\n"); + "get$capitalized_name$Map();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "$value_type$ get$capitalized_name$OrDefault(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue);\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "$value_type$ get$capitalized_name$OrThrow(\n" + " $key_type$ key);\n"); } } @@ -196,9 +272,9 @@ GenerateMembers(io::Printer* printer) const { printer->Print( variables_, "private static final class $capitalized_name$DefaultEntryHolder {\n" - " static final com.google.protobuf.MapEntry$lite$<\n" + " static final com.google.protobuf.MapEntry<\n" " $type_parameters$> defaultEntry =\n" - " com.google.protobuf.MapEntry$lite$\n" + " com.google.protobuf.MapEntry\n" " .<$type_parameters$>newDefaultInstance(\n" " $descriptor$\n" " $key_wire_type$,\n" @@ -208,12 +284,12 @@ GenerateMembers(io::Printer* printer) const { "}\n"); printer->Print( variables_, - "private com.google.protobuf.MapField$lite$<\n" + "private com.google.protobuf.MapField<\n" " $type_parameters$> $name$_;\n" - "private com.google.protobuf.MapField$lite$<$type_parameters$>\n" + "private com.google.protobuf.MapField<$type_parameters$>\n" "internalGet$capitalized_name$() {\n" " if ($name$_ == null) {\n" - " return com.google.protobuf.MapField$lite$.emptyMapField(\n" + " return com.google.protobuf.MapField.emptyMapField(\n" " $map_field_parameter$);\n" " }\n" " return $name$_;\n" @@ -227,57 +303,29 @@ GenerateMembers(io::Printer* printer) const { " com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n" " $value_enum_type$.internalGetValueMap(),\n" " $unrecognized_value$);\n"); - if (SupportUnknownEnumValue(descriptor_->file())) { - WriteFieldDocComment(printer, descriptor_); - printer->Print( - variables_, - "$deprecation$\n" - "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$Value() {\n" - " return internalGet$capitalized_name$().getMap();\n" - "}\n"); - } - WriteFieldDocComment(printer, descriptor_); - printer->Print( - variables_, - "$deprecation$\n" - "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$() {\n" - " return new com.google.protobuf.Internal.MapAdapter<\n" - " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" - " internalGet$capitalized_name$().getMap(),\n" - " $name$ValueConverter);\n" - "}\n"); - } else { - WriteFieldDocComment(printer, descriptor_); - printer->Print( - variables_, - "$deprecation$\n" - "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" - " return internalGet$capitalized_name$().getMap();\n" - "}\n"); } + GenerateMapGetters(printer); } void ImmutableMapFieldGenerator:: GenerateBuilderMembers(io::Printer* printer) const { printer->Print( variables_, - "private com.google.protobuf.MapField$lite$<\n" + "private com.google.protobuf.MapField<\n" " $type_parameters$> $name$_;\n" - "private com.google.protobuf.MapField$lite$<$type_parameters$>\n" + "private com.google.protobuf.MapField<$type_parameters$>\n" "internalGet$capitalized_name$() {\n" " if ($name$_ == null) {\n" - " return com.google.protobuf.MapField$lite$.emptyMapField(\n" + " return com.google.protobuf.MapField.emptyMapField(\n" " $map_field_parameter$);\n" " }\n" " return $name$_;\n" "}\n" - "private com.google.protobuf.MapField$lite$<$type_parameters$>\n" + "private com.google.protobuf.MapField<$type_parameters$>\n" "internalGetMutable$capitalized_name$() {\n" " $on_changed$;\n" " if ($name$_ == null) {\n" - " $name$_ = com.google.protobuf.MapField$lite$.newMapField(\n" + " $name$_ = com.google.protobuf.MapField.newMapField(\n" " $map_field_parameter$);\n" " }\n" " if (!$name$_.isMutable()) {\n" @@ -285,53 +333,82 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return $name$_;\n" "}\n"); + GenerateMapGetters(printer); + printer->Print( + variables_, + "$deprecation$\n" + "public Builder clear$capitalized_name$() {\n" + " getMutable$capitalized_name$().clear();\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public Builder remove$capitalized_name$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " getMutable$capitalized_name$().remove(key);\n" + " return this;\n" + "}\n"); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { - WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$\n" + "/**\n" + " * Use alternate mutation accessors instead.\n" + " */\n" + "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$() {\n" + "getMutable$capitalized_name$() {\n" " return new com.google.protobuf.Internal.MapAdapter<\n" " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" - " internalGet$capitalized_name$().getMap(),\n" + " internalGetMutable$capitalized_name$().getMutableMap(),\n" " $name$ValueConverter);\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$\n" - "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "getMutable$capitalized_name$() {\n" - " return new com.google.protobuf.Internal.MapAdapter<\n" - " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" - " internalGetMutable$capitalized_name$().getMutableMap(),\n" - " $name$ValueConverter);\n" + "$deprecation$public Builder put$capitalized_name$(\n" + " $key_type$ key,\n" + " $value_enum_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " getMutable$capitalized_name$().put(key, value);\n" + " return this;\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + // TODO(arielb): null check map keys/values here and everywhere else + // related to putAll "$deprecation$public Builder putAll$capitalized_name$(\n" " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n" " getMutable$capitalized_name$().putAll(values);\n" " return this;\n" "}\n"); if (SupportUnknownEnumValue(descriptor_->file())) { - WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$\n" + "/**\n" + " * Use alternate mutation accessors instead.\n" + " */\n" + "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$Value() {\n" - " return internalGet$capitalized_name$().getMap();\n" + "getMutable$capitalized_name$Value() {\n" + " return internalGetMutable$capitalized_name$().getMutableMap();\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$\n" - "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "getMutable$capitalized_name$Value() {\n" - " return internalGetMutable$capitalized_name$().getMutableMap();\n" + "$deprecation$public Builder put$capitalized_name$Value(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " if ($value_enum_type$.forNumber(value) == null) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " getMutable$capitalized_name$Value().put(key, value);\n" + " return this;\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( @@ -343,23 +420,33 @@ GenerateBuilderMembers(io::Printer* printer) const { "}\n"); } } else { - WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" - " return internalGet$capitalized_name$().getMap();\n" + "/**\n" + " * Use alternate mutation accessors instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$type_parameters$>\n" + "getMutable$capitalized_name$() {\n" + " return internalGetMutable$capitalized_name$().getMutableMap();\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "public java.util.Map<$type_parameters$>\n" - "getMutable$capitalized_name$() {\n" - " return internalGetMutable$capitalized_name$().getMutableMap();\n" + "$deprecation$" + "public Builder put$capitalized_name$(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " getMutable$capitalized_name$().put(key, value);\n" + " return this;\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder putAll$capitalized_name$(\n" + "$deprecation$\n" + "public Builder putAll$capitalized_name$(\n" " java.util.Map<$type_parameters$> values) {\n" " getMutable$capitalized_name$().putAll(values);\n" " return this;\n" @@ -367,6 +454,165 @@ GenerateBuilderMembers(io::Printer* printer) const { } } +void ImmutableMapFieldGenerator:: +GenerateMapGetters(io::Printer* printer) const { + printer->Print( + variables_, + "$deprecation$\n" + "public int get$capitalized_name$Count() {\n" + " return internalGet$capitalized_name$().getMap().size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public boolean contains$capitalized_name$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " return internalGet$capitalized_name$().getMap().containsKey(key);\n" + "}\n"); + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "get$capitalized_name$() {\n" + " return get$capitalized_name$Map();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "get$capitalized_name$Map() {\n" + " return new com.google.protobuf.Internal.MapAdapter<\n" + " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" + " internalGet$capitalized_name$().getMap(),\n" + " $name$ValueConverter);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_enum_type$ get$capitalized_name$OrDefault(\n" + " $key_type$ key,\n" + " $value_enum_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " return map.containsKey(key)\n" + " ? $name$ValueConverter.doForward(map.get(key))\n" + " : defaultValue;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_enum_type$ get$capitalized_name$OrThrow(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return $name$ValueConverter.doForward(map.get(key));\n" + "}\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "get$capitalized_name$Value() {\n" + " return get$capitalized_name$ValueMap();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "get$capitalized_name$ValueMap() {\n" + " return internalGet$capitalized_name$().getMap();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_type$ get$capitalized_name$ValueOrDefault(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " return map.containsKey(key) ? map.get(key) : defaultValue;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_type$ get$capitalized_name$ValueOrThrow(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" + "}\n"); + } + } else { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" + " return get$capitalized_name$Map();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$type_parameters$> get$capitalized_name$Map() {\n" + " return internalGet$capitalized_name$().getMap();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_type$ get$capitalized_name$OrDefault(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " return map.containsKey(key) ? map.get(key) : defaultValue;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_type$ get$capitalized_name$OrThrow(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" + "}\n"); + } +} + void ImmutableMapFieldGenerator:: GenerateFieldBuilderInitializationCode(io::Printer* printer) const { // Nothing to initialize. @@ -405,7 +651,7 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print( variables_, "if (!$get_mutable_bit_parser$) {\n" - " $name$_ = com.google.protobuf.MapField$lite$.newMapField(\n" + " $name$_ = com.google.protobuf.MapField.newMapField(\n" " $map_field_parameter$);\n" " $set_mutable_bit_parser$;\n" "}\n"); @@ -414,7 +660,7 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print( variables_, "com.google.protobuf.ByteString bytes = input.readBytes();\n" - "com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" + "com.google.protobuf.MapEntry<$type_parameters$>\n" "$name$ = $default_entry$.getParserForType().parseFrom(bytes);\n"); printer->Print( variables_, @@ -426,7 +672,7 @@ GenerateParsingCode(io::Printer* printer) const { } else { printer->Print( variables_, - "com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" + "com.google.protobuf.MapEntry<$type_parameters$>\n" "$name$ = input.readMessage(\n" " $default_entry$.getParserForType(), extensionRegistry);\n" "$name$_.getMutableMap().put($name$.getKey(), $name$.getValue());\n"); @@ -444,7 +690,7 @@ GenerateSerializationCode(io::Printer* printer) const { variables_, "for (java.util.Map.Entry<$type_parameters$> entry\n" " : internalGet$capitalized_name$().getMap().entrySet()) {\n" - " com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" + " com.google.protobuf.MapEntry<$type_parameters$>\n" " $name$ = $default_entry$.newBuilderForType()\n" " .setKey(entry.getKey())\n" " .setValue(entry.getValue())\n" @@ -459,7 +705,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { variables_, "for (java.util.Map.Entry<$type_parameters$> entry\n" " : internalGet$capitalized_name$().getMap().entrySet()) {\n" - " com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" + " com.google.protobuf.MapEntry<$type_parameters$>\n" " $name$ = $default_entry$.newBuilderForType()\n" " .setKey(entry.getKey())\n" " .setValue(entry.getValue())\n" diff --git a/src/google/protobuf/compiler/java/java_map_field.h b/src/google/protobuf/compiler/java/java_map_field.h index f2768f3a..ae7ce7c5 100644 --- a/src/google/protobuf/compiler/java/java_map_field.h +++ b/src/google/protobuf/compiler/java/java_map_field.h @@ -69,6 +69,7 @@ class ImmutableMapFieldGenerator : public ImmutableFieldGenerator { const FieldDescriptor* descriptor_; map variables_; ClassNameResolver* name_resolver_; + void GenerateMapGetters(io::Printer* printer) const; }; } // namespace java diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.cc b/src/google/protobuf/compiler/java/java_map_field_lite.cc index b80d4139..0d3bea17 100644 --- a/src/google/protobuf/compiler/java/java_map_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc @@ -88,10 +88,18 @@ void SetMessageVariables(const FieldDescriptor* descriptor, name_resolver->GetImmutableClassName(descriptor->message_type()); const FieldDescriptor* key = KeyField(descriptor); const FieldDescriptor* value = ValueField(descriptor); + const JavaType keyJavaType = GetJavaType(key); + const JavaType valueJavaType = GetJavaType(value); + (*variables)["key_type"] = TypeName(key, name_resolver, false); (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true); (*variables)["key_wire_type"] = WireType(key); (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver); + (*variables)["key_null_check"] = IsReferenceType(keyJavaType) ? + "if (key == null) { throw new java.lang.NullPointerException(); }" : ""; + (*variables)["value_null_check"] = IsReferenceType(valueJavaType) ? + "if (value == null) { throw new java.lang.NullPointerException(); }" : ""; + if (GetJavaType(value) == JAVATYPE_ENUM) { // We store enums as Integers internally. (*variables)["value_type"] = "int"; @@ -127,8 +135,6 @@ void SetMessageVariables(const FieldDescriptor* descriptor, (*variables)["default_entry"] = (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry"; - (*variables)["lite"] = "Lite"; - (*variables)["descriptor"] = ""; } } // namespace @@ -157,25 +163,95 @@ int ImmutableMapFieldLiteGenerator::GetNumBitsForBuilder() const { void ImmutableMapFieldLiteGenerator:: GenerateInterfaceMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$boolean contains$capitalized_name$(\n" + " $key_type$ key);\n"); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "get$capitalized_name$();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$();\n"); + "get$capitalized_name$Map();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$$value_enum_type$ get$capitalized_name$OrDefault(\n" + " $key_type$ key,\n" + " $value_enum_type$ defaultValue);\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$$value_enum_type$ get$capitalized_name$OrThrow(\n" + " $key_type$ key);\n"); if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$type_parameters$>\n" + "get$capitalized_name$Value();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$type_parameters$>\n" - "get$capitalized_name$Value();\n"); + "get$capitalized_name$ValueMap();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "$value_type$ get$capitalized_name$ValueOrDefault(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue);\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "$value_type$ get$capitalized_name$ValueOrThrow(\n" + " $key_type$ key);\n"); } } else { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$type_parameters$>\n" + "get$capitalized_name$();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$type_parameters$>\n" - "get$capitalized_name$();\n"); + "get$capitalized_name$Map();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "$value_type$ get$capitalized_name$OrDefault(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue);\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "$value_type$ get$capitalized_name$OrThrow(\n" + " $key_type$ key);\n"); } } @@ -184,11 +260,10 @@ GenerateMembers(io::Printer* printer) const { printer->Print( variables_, "private static final class $capitalized_name$DefaultEntryHolder {\n" - " static final com.google.protobuf.MapEntry$lite$<\n" + " static final com.google.protobuf.MapEntryLite<\n" " $type_parameters$> defaultEntry =\n" - " com.google.protobuf.MapEntry$lite$\n" + " com.google.protobuf.MapEntryLite\n" " .<$type_parameters$>newDefaultInstance(\n" - " $descriptor$\n" " $key_wire_type$,\n" " $key_default_value$,\n" " $value_wire_type$,\n" @@ -196,20 +271,35 @@ GenerateMembers(io::Printer* printer) const { "}\n"); printer->Print( variables_, - "private com.google.protobuf.MapField$lite$<\n" + "private com.google.protobuf.MapFieldLite<\n" " $type_parameters$> $name$_ =\n" - " com.google.protobuf.MapField$lite$.emptyMapField();\n" - "private com.google.protobuf.MapField$lite$<$type_parameters$>\n" + " com.google.protobuf.MapFieldLite.emptyMapField();\n" + "private com.google.protobuf.MapFieldLite<$type_parameters$>\n" "internalGet$capitalized_name$() {\n" " return $name$_;\n" "}\n" - "private com.google.protobuf.MapField$lite$<$type_parameters$>\n" + "private com.google.protobuf.MapFieldLite<$type_parameters$>\n" "internalGetMutable$capitalized_name$() {\n" " if (!$name$_.isMutable()) {\n" - " $name$_ = $name$_.copy();\n" + " $name$_ = $name$_.mutableCopy();\n" " }\n" " return $name$_;\n" "}\n"); + printer->Print( + variables_, + "$deprecation$\n" + "public int get$capitalized_name$Count() {\n" + " return internalGet$capitalized_name$().size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public boolean contains$capitalized_name$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " return internalGet$capitalized_name$().containsKey(key);\n" + "}\n"); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -219,34 +309,146 @@ GenerateMembers(io::Printer* printer) const { " com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n" " $value_enum_type$.internalGetValueMap(),\n" " $unrecognized_value$);\n"); + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "get$capitalized_name$() {\n" + " return get$capitalized_name$Map();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "get$capitalized_name$Map() {\n" + " return java.util.Collections.unmodifiableMap(\n" + " new com.google.protobuf.Internal.MapAdapter<\n" + " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" + " internalGet$capitalized_name$(),\n" + " $name$ValueConverter));\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_enum_type$ get$capitalized_name$OrDefault(\n" + " $key_type$ key,\n" + " $value_enum_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$();\n" + " return map.containsKey(key)\n" + " ? $name$ValueConverter.doForward(map.get(key))\n" + " : defaultValue;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_enum_type$ get$capitalized_name$OrThrow(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return $name$ValueConverter.doForward(map.get(key));\n" + "}\n"); if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "get$capitalized_name$Value() {\n" + " return get$capitalized_name$ValueMap();\n" + "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$Value() {\n" - " return internalGet$capitalized_name$().getMap();\n" + "get$capitalized_name$ValueMap() {\n" + " return java.util.Collections.unmodifiableMap(\n" + " internalGet$capitalized_name$());\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_type$ get$capitalized_name$ValueOrDefault(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$();\n" + " return map.containsKey(key) ? map.get(key) : defaultValue;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_type$ get$capitalized_name$ValueOrThrow(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" "}\n"); } + } else { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" + " return get$capitalized_name$Map();\n" + "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$() {\n" - " return new com.google.protobuf.Internal.MapAdapter<\n" - " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" - " internalGet$capitalized_name$().getMap(),\n" - " $name$ValueConverter);\n" + "public java.util.Map<$type_parameters$> get$capitalized_name$Map() {\n" + " return java.util.Collections.unmodifiableMap(\n" + " internalGet$capitalized_name$());\n" "}\n"); - } else { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" - " return internalGet$capitalized_name$().getMap();\n" + "public $value_type$ get$capitalized_name$OrDefault(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " internalGet$capitalized_name$();\n" + " return map.containsKey(key) ? map.get(key) : defaultValue;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_type$ get$capitalized_name$OrThrow(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " internalGet$capitalized_name$();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" "}\n"); } @@ -256,10 +458,10 @@ GenerateMembers(io::Printer* printer) const { printer->Print( variables_, "private java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "getMutable$capitalized_name$() {\n" + "getMutable$capitalized_name$Map() {\n" " return new com.google.protobuf.Internal.MapAdapter<\n" " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" - " internalGetMutable$capitalized_name$().getMutableMap(),\n" + " internalGetMutable$capitalized_name$(),\n" " $name$ValueConverter);\n" "}\n"); if (SupportUnknownEnumValue(descriptor_->file())) { @@ -267,8 +469,8 @@ GenerateMembers(io::Printer* printer) const { printer->Print( variables_, "private java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "getMutable$capitalized_name$Value() {\n" - " return internalGetMutable$capitalized_name$().getMutableMap();\n" + "getMutable$capitalized_name$ValueMap() {\n" + " return internalGetMutable$capitalized_name$();\n" "}\n"); } } else { @@ -276,88 +478,252 @@ GenerateMembers(io::Printer* printer) const { printer->Print( variables_, "private java.util.Map<$type_parameters$>\n" - "getMutable$capitalized_name$() {\n" - " return internalGetMutable$capitalized_name$().getMutableMap();\n" + "getMutable$capitalized_name$Map() {\n" + " return internalGetMutable$capitalized_name$();\n" "}\n"); } } void ImmutableMapFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { + printer->Print( + variables_, + "$deprecation$\n" + "public int get$capitalized_name$Count() {\n" + " return instance.get$capitalized_name$Map().size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public boolean contains$capitalized_name$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " return instance.get$capitalized_name$Map().containsKey(key);\n" + "}\n"); + printer->Print( + variables_, + "$deprecation$\n" + "public Builder clear$capitalized_name$() {\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$Map().clear();\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public Builder remove$capitalized_name$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$Map().remove(key);\n" + " return this;\n" + "}\n"); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { - WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$\n" + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" "get$capitalized_name$() {\n" - " return instance.get$capitalized_name$();\n" + " return get$capitalized_name$Map();\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "getMutable$capitalized_name$() {\n" + "get$capitalized_name$Map() {\n" + " return java.util.Collections.unmodifiableMap(\n" + " instance.get$capitalized_name$Map());\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_enum_type$ get$capitalized_name$OrDefault(\n" + " $key_type$ key,\n" + " $value_enum_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n" + " instance.get$capitalized_name$Map();\n" + " return map.containsKey(key)\n" + " ? map.get(key)\n" + " : defaultValue;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_enum_type$ get$capitalized_name$OrThrow(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n" + " instance.get$capitalized_name$Map();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public Builder put$capitalized_name$(\n" + " $key_type$ key,\n" + " $value_enum_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" " copyOnWrite();\n" - " return instance.getMutable$capitalized_name$();\n" + " instance.getMutable$capitalized_name$Map().put(key, value);\n" + " return this;\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$public Builder putAll$capitalized_name$(\n" " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n" - " getMutable$capitalized_name$().putAll(values);\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$Map().putAll(values);\n" " return this;\n" "}\n"); if (SupportUnknownEnumValue(descriptor_->file())) { - WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$\n" + "/**\n" + " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" "get$capitalized_name$Value() {\n" - " return instance.get$capitalized_name$Value();\n" + " return get$capitalized_name$ValueMap();\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "getMutable$capitalized_name$Value() {\n" + "get$capitalized_name$ValueMap() {\n" + " return java.util.Collections.unmodifiableMap(\n" + " instance.get$capitalized_name$ValueMap());\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_type$ get$capitalized_name$ValueOrDefault(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " instance.get$capitalized_name$ValueMap();\n" + " return map.containsKey(key) ? map.get(key) : defaultValue;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_type$ get$capitalized_name$ValueOrThrow(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " instance.get$capitalized_name$ValueMap();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public Builder put$capitalized_name$Value(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " if ($value_enum_type$.forNumber(value) == null) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" " copyOnWrite();\n" - " return instance.getMutable$capitalized_name$Value();\n" + " instance.getMutable$capitalized_name$ValueMap().put(key, value);\n" + " return this;\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$public Builder putAll$capitalized_name$Value(\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n" - " getMutable$capitalized_name$Value().putAll(values);\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$ValueMap().putAll(values);\n" " return this;\n" "}\n"); } } else { - WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" - " return instance.get$capitalized_name$();\n" + " return get$capitalized_name$Map();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$" + "public java.util.Map<$type_parameters$> get$capitalized_name$Map() {\n" + " return java.util.Collections.unmodifiableMap(\n" + " instance.get$capitalized_name$Map());\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_type$ get$capitalized_name$OrDefault(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " instance.get$capitalized_name$Map();\n" + " return map.containsKey(key) ? map.get(key) : defaultValue;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public $value_type$ get$capitalized_name$OrThrow(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " instance.get$capitalized_name$Map();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "public java.util.Map<$type_parameters$>\n" - "getMutable$capitalized_name$() {\n" + "$deprecation$" + "public Builder put$capitalized_name$(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" " copyOnWrite();\n" - " return instance.getMutable$capitalized_name$();\n" + " instance.getMutable$capitalized_name$Map().put(key, value);\n" + " return this;\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "$deprecation$" "public Builder putAll$capitalized_name$(\n" " java.util.Map<$type_parameters$> values) {\n" - " getMutable$capitalized_name$().putAll(values);\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$Map().putAll(values);\n" " return this;\n" "}\n"); } @@ -377,8 +743,8 @@ void ImmutableMapFieldLiteGenerator:: GenerateVisitCode(io::Printer* printer) const { printer->Print( variables_, - "$name$_ = visitor.visitMap(internalGetMutable$capitalized_name$(),\n" - " other.internalGet$capitalized_name$());\n"); + "$name$_ = visitor.visitMap(\n" + " $name$_, other.internalGet$capitalized_name$());\n"); } void ImmutableMapFieldLiteGenerator:: @@ -392,29 +758,26 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print( variables_, "if (!$name$_.isMutable()) {\n" - " $name$_ = $name$_.copy();\n" + " $name$_ = $name$_.mutableCopy();\n" "}\n"); if (!SupportUnknownEnumValue(descriptor_->file()) && GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, "com.google.protobuf.ByteString bytes = input.readBytes();\n" - "com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" - "$name$ = $default_entry$.getParserForType().parseFrom(bytes);\n"); + "java.util.Map.Entry<$type_parameters$> $name$ =\n" + " $default_entry$.parseEntry(bytes, extensionRegistry);\n"); printer->Print( variables_, "if ($value_enum_type$.forNumber($name$.getValue()) == null) {\n" " super.mergeLengthDelimitedField($number$, bytes);\n" "} else {\n" - " $name$_.getMutableMap().put($name$.getKey(), $name$.getValue());\n" + " $name$_.put($name$);\n" "}\n"); } else { printer->Print( variables_, - "com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" - "$name$ = input.readMessage(\n" - " $default_entry$.getParserForType(), extensionRegistry);\n" - "$name$_.getMutableMap().put($name$.getKey(), $name$.getValue());\n"); + "$default_entry$.parseInto($name$_, input, extensionRegistry);"); } } @@ -428,13 +791,9 @@ GenerateSerializationCode(io::Printer* printer) const { printer->Print( variables_, "for (java.util.Map.Entry<$type_parameters$> entry\n" - " : internalGet$capitalized_name$().getMap().entrySet()) {\n" - " com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" - " $name$ = $default_entry$.newBuilderForType()\n" - " .setKey(entry.getKey())\n" - " .setValue(entry.getValue())\n" - " .build();\n" - " output.writeMessage($number$, $name$);\n" + " : internalGet$capitalized_name$().entrySet()) {\n" + " $default_entry$.serializeTo(\n" + " output, $number$, entry.getKey(), entry.getValue());\n" "}\n"); } @@ -443,14 +802,9 @@ GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print( variables_, "for (java.util.Map.Entry<$type_parameters$> entry\n" - " : internalGet$capitalized_name$().getMap().entrySet()) {\n" - " com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" - " $name$ = $default_entry$.newBuilderForType()\n" - " .setKey(entry.getKey())\n" - " .setValue(entry.getValue())\n" - " .build();\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .computeMessageSize($number$, $name$);\n" + " : internalGet$capitalized_name$().entrySet()) {\n" + " size += $default_entry$.computeMessageSize(\n" + " $number$, entry.getKey(), entry.getValue());\n" "}\n"); } @@ -466,7 +820,7 @@ void ImmutableMapFieldLiteGenerator:: GenerateHashCode(io::Printer* printer) const { printer->Print( variables_, - "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n" + "if (!internalGet$capitalized_name$().isEmpty()) {\n" " hash = (37 * hash) + $constant_name$;\n" " hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n" "}\n"); diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 4c474a48..d55a9849 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -248,22 +248,27 @@ GenerateFieldAccessorTableInitializer(io::Printer* printer) { // =================================================================== void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, + /* immutable = */ true, "OrBuilder"); if (descriptor_->extension_range_count() > 0) { printer->Print( - "public interface $classname$OrBuilder extends\n" - " $extra_interfaces$\n" - " com.google.protobuf.GeneratedMessage.\n" - " ExtendableMessageOrBuilder<$classname$> {\n", - "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), - "classname", descriptor_->name()); + "public interface $classname$OrBuilder$idend$ extends\n" + " $extra_interfaces$\n" + " com.google.protobuf.GeneratedMessage.\n" + " ExtendableMessageOrBuilder<$classname$> {\n", + "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), + "classname", descriptor_->name(), + "idend", ""); } else { printer->Print( - "public interface $classname$OrBuilder extends\n" - " $extra_interfaces$\n" - " com.google.protobuf.MessageOrBuilder {\n", - "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), - "classname", descriptor_->name()); + "public interface $classname$OrBuilder$idend$ extends\n" + " $extra_interfaces$\n" + " com.google.protobuf.MessageOrBuilder {\n", + "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), + "classname", descriptor_->name(), + "idend", ""); } + printer->Annotate("classname", "idend", descriptor_); printer->Indent(); for (int i = 0; i < descriptor_->field_count(); i++) { @@ -291,9 +296,7 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { // =================================================================== void ImmutableMessageGenerator::Generate(io::Printer* printer) { - bool is_own_file = - descriptor_->containing_type() == NULL && - MultipleJavaFiles(descriptor_->file(), /* immutable = */ true); + bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true); map variables; variables["static"] = is_own_file ? " " : " static "; @@ -301,22 +304,29 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); WriteMessageDocComment(printer, descriptor_); + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, + /* immutable = */ true); // The builder_type stores the super type name of the nested Builder class. string builder_type; if (descriptor_->extension_range_count() > 0) { printer->Print(variables, - "public $static$final class $classname$ extends\n" - " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n" - " $classname$> implements\n" - " $extra_interfaces$\n" - " $classname$OrBuilder {\n"); + "public $static$final class $classname$ extends\n"); + printer->Annotate("classname", descriptor_); + printer->Print( + variables, + " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n" + " $classname$> implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n"); builder_type = strings::Substitute( "com.google.protobuf.GeneratedMessage.ExtendableBuilder<$0, ?>", name_resolver_->GetImmutableClassName(descriptor_)); } else { printer->Print(variables, - "public $static$final class $classname$ extends\n" + "public $static$final class $classname$ extends\n"); + printer->Annotate("classname", descriptor_); + printer->Print(variables, " com.google.protobuf.GeneratedMessage implements\n" " $extra_interfaces$\n" " $classname$OrBuilder {\n"); @@ -485,9 +495,6 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { if (context_->HasGeneratedMethods(descriptor_)) { GenerateIsInitialized(printer); GenerateMessageSerializationMethods(printer); - } - - if (HasEqualsAndHashCode(descriptor_)) { GenerateEqualsAndHashCode(printer); } @@ -1225,8 +1232,7 @@ GenerateParsingConstructor(io::Printer* printer) { "default: {\n" " if (!input.skipField(tag)) {\n" " done = true;\n" // it's an endgroup tag - " }\n"); - printer->Print( + " }\n" " break;\n" "}\n"); } diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h index e9fc57c2..da1447c1 100644 --- a/src/google/protobuf/compiler/java/java_message.h +++ b/src/google/protobuf/compiler/java/java_message.h @@ -92,8 +92,7 @@ class MessageGenerator { class ImmutableMessageGenerator : public MessageGenerator { public: - explicit ImmutableMessageGenerator(const Descriptor* descriptor, - Context* context); + ImmutableMessageGenerator(const Descriptor* descriptor, Context* context); virtual ~ImmutableMessageGenerator(); virtual void Generate(io::Printer* printer); diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc index 455516f6..cc627b5a 100644 --- a/src/google/protobuf/compiler/java/java_message_field.cc +++ b/src/google/protobuf/compiler/java/java_message_field.cc @@ -71,6 +71,10 @@ void SetMessageVariables(const FieldDescriptor* descriptor, (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; (*variables)["on_changed"] = "onChanged();"; + (*variables)["ver"] = GeneratedCodeVersionSuffix(); + (*variables)["get_parser"] = + ExposePublicParser(descriptor->message_type()->file()) + ? "PARSER" : "parser()"; if (SupportFieldPresence(descriptor->file())) { // For singular messages and builders, one bit is used for the hasField bit. @@ -252,7 +256,7 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Print(variables_, // If this builder is non-null, it is used and the other fields are // ignored. - "private com.google.protobuf.SingleFieldBuilder<\n" + "private com.google.protobuf.SingleFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" "\n"); @@ -374,11 +378,11 @@ GenerateBuilderMembers(io::Printer* printer) const { "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "private com.google.protobuf.SingleFieldBuilder<\n" + "private com.google.protobuf.SingleFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder> \n" " get$capitalized_name$FieldBuilder() {\n" " if ($name$Builder_ == null) {\n" - " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n" + " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder>(\n" " get$capitalized_name$(),\n" " getParentForChildren(),\n" @@ -451,11 +455,11 @@ GenerateParsingCode(io::Printer* printer) const { if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { printer->Print(variables_, - "$name$_ = input.readGroup($number$, $type$.parser(),\n" + "$name$_ = input.readGroup($number$, $type$.$get_parser$,\n" " extensionRegistry);\n"); } else { printer->Print(variables_, - "$name$_ = input.readMessage($type$.parser(), extensionRegistry);\n"); + "$name$_ = input.readMessage($type$.$get_parser$, extensionRegistry);\n"); } printer->Print(variables_, @@ -560,7 +564,7 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Print(variables_, // If this builder is non-null, it is used and the other fields are // ignored. - "private com.google.protobuf.SingleFieldBuilder<\n" + "private com.google.protobuf.SingleFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" "\n"); @@ -683,14 +687,14 @@ GenerateBuilderMembers(io::Printer* printer) const { "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "private com.google.protobuf.SingleFieldBuilder<\n" + "private com.google.protobuf.SingleFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder> \n" " get$capitalized_name$FieldBuilder() {\n" " if ($name$Builder_ == null) {\n" " if (!($has_oneof_case_message$)) {\n" " $oneof_name$_ = $type$.getDefaultInstance();\n" " }\n" - " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n" + " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder>(\n" " ($type$) $oneof_name$_,\n" " getParentForChildren(),\n" @@ -735,12 +739,12 @@ GenerateParsingCode(io::Printer* printer) const { if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { printer->Print(variables_, - "$oneof_name$_ = input.readGroup($number$, $type$.parser(),\n" + "$oneof_name$_ = input.readGroup($number$, $type$.$get_parser$,\n" " extensionRegistry);\n"); } else { printer->Print(variables_, "$oneof_name$_ =\n" - " input.readMessage($type$.parser(), extensionRegistry);\n"); + " input.readMessage($type$.$get_parser$, extensionRegistry);\n"); } printer->Print(variables_, @@ -920,7 +924,7 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Print(variables_, // If this builder is non-null, it is used and the other fields are // ignored. - "private com.google.protobuf.RepeatedFieldBuilder<\n" + "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n" "\n"); @@ -1137,11 +1141,11 @@ GenerateBuilderMembers(io::Printer* printer) const { " get$capitalized_name$BuilderList() {\n" " return get$capitalized_name$FieldBuilder().getBuilderList();\n" "}\n" - "private com.google.protobuf.RepeatedFieldBuilder<\n" + "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder> \n" " get$capitalized_name$FieldBuilder() {\n" " if ($name$Builder_ == null) {\n" - " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\n" + " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder>(\n" " $name$_,\n" " $get_mutable_bit_builder$,\n" @@ -1232,11 +1236,12 @@ GenerateParsingCode(io::Printer* printer) const { if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { printer->Print(variables_, - "$name$_.add(input.readGroup($number$, $type$.parser(),\n" + "$name$_.add(input.readGroup($number$, $type$.$get_parser$,\n" " extensionRegistry));\n"); } else { printer->Print(variables_, - "$name$_.add(input.readMessage($type$.parser(), extensionRegistry));\n"); + "$name$_.add(\n" + " input.readMessage($type$.$get_parser$, extensionRegistry));\n"); } } diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc index d4d2593a..7c8c4a03 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_lite.cc @@ -120,23 +120,28 @@ int ImmutableMessageLiteGenerator::GenerateStaticVariableInitializers( // =================================================================== void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, + /* immutable = */ true, "OrBuilder"); if (descriptor_->extension_range_count() > 0) { printer->Print( - "public interface $classname$OrBuilder extends \n" - " $extra_interfaces$\n" - " com.google.protobuf.GeneratedMessageLite.\n" - " ExtendableMessageOrBuilder<\n" - " $classname$, $classname$.Builder> {\n", - "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), - "classname", descriptor_->name()); + "public interface $classname$OrBuilder$idend$ extends \n" + " $extra_interfaces$\n" + " com.google.protobuf.GeneratedMessageLite.\n" + " ExtendableMessageOrBuilder<\n" + " $classname$, $classname$.Builder> {\n", + "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), + "classname", descriptor_->name(), + "idend", ""); } else { printer->Print( - "public interface $classname$OrBuilder extends\n" - " $extra_interfaces$\n" - " com.google.protobuf.MessageLiteOrBuilder {\n", - "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), - "classname", descriptor_->name()); + "public interface $classname$OrBuilder$idend$ extends\n" + " $extra_interfaces$\n" + " com.google.protobuf.MessageLiteOrBuilder {\n", + "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), + "classname", descriptor_->name(), + "idend", ""); } + printer->Annotate("classname", "idend", descriptor_); printer->Indent(); for (int i = 0; i < descriptor_->field_count(); i++) { @@ -163,9 +168,7 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { // =================================================================== void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { - bool is_own_file = - descriptor_->containing_type() == NULL && - MultipleJavaFiles(descriptor_->file(), /* immutable = */ true); + bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true); map variables; variables["static"] = is_own_file ? " " : " static "; @@ -173,6 +176,8 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); WriteMessageDocComment(printer, descriptor_); + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, + /* immutable = */ true); // The builder_type stores the super type name of the nested Builder class. string builder_type; diff --git a/src/google/protobuf/compiler/java/java_message_lite.h b/src/google/protobuf/compiler/java/java_message_lite.h index 292c1c56..1e319c6d 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.h +++ b/src/google/protobuf/compiler/java/java_message_lite.h @@ -47,8 +47,7 @@ namespace java { class ImmutableMessageLiteGenerator : public MessageGenerator { public: - explicit ImmutableMessageLiteGenerator(const Descriptor* descriptor, - Context* context); + ImmutableMessageLiteGenerator(const Descriptor* descriptor, Context* context); virtual ~ImmutableMessageLiteGenerator(); virtual void Generate(io::Printer* printer); diff --git a/src/google/protobuf/compiler/java/java_options.h b/src/google/protobuf/compiler/java/java_options.h new file mode 100644 index 00000000..7bce1447 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_options.h @@ -0,0 +1,73 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_OPTIONS_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_OPTIONS_H__ + +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +// Generator options +struct Options { + Options() + : generate_immutable_code(false), + generate_mutable_code(false), + generate_shared_code(false), + enforce_lite(false), + annotate_code(false) { + } + + bool generate_immutable_code; + bool generate_mutable_code; + bool generate_shared_code; + // When set, the protoc will generate the current files and all the transitive + // dependencies as lite runtime. + bool enforce_lite; + // If true, we should build .meta files and emit @Generated annotations into + // generated code. + bool annotate_code; + // Name of a file where we will write a list of generated .meta file names, + // one per line. + string annotation_list_file; + // Name of a file where we will write a list of generated file names, one + // per line. + string output_list_file; +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_OPTIONS_H__ diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index e42ec280..877baf0a 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -777,8 +777,8 @@ GenerateSerializationCode(io::Printer* printer) const { // That makes it safe to rely on the memoized size here. printer->Print(variables_, "if (get$capitalized_name$List().size() > 0) {\n" - " output.writeRawVarint32($tag$);\n" - " output.writeRawVarint32($name$MemoizedSerializedSize);\n" + " output.writeUInt32NoTag($tag$);\n" + " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n" "}\n" "for (int i = 0; i < $name$_.size(); i++) {\n" " output.write$capitalized_type$NoTag($name$_.get(i));\n" diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc index 690dad12..ad2db30c 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc @@ -63,22 +63,20 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, ClassNameResolver* name_resolver, map* variables) { SetCommonFieldVariables(descriptor, info, variables); - - (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor)); - (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor)); + JavaType javaType = GetJavaType(descriptor); + (*variables)["type"] = PrimitiveTypeName(javaType); + (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType); (*variables)["field_type"] = (*variables)["type"]; (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); - (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ? - "" : ("= " + ImmutableDefaultValue(descriptor, name_resolver)); (*variables)["capitalized_type"] = GetCapitalizedType(descriptor, /* immutable = */ true); (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); (*variables)["tag_size"] = SimpleItoa( WireFormat::TagSize(descriptor->number(), GetType(descriptor))); - string capitalized_type = UnderscoresToCamelCase(PrimitiveTypeName( - GetJavaType(descriptor)), true /* cap_next_letter */); - switch (GetJavaType(descriptor)) { + string capitalized_type = UnderscoresToCamelCase(PrimitiveTypeName(javaType), + true /* cap_next_letter */); + switch (javaType) { case JAVATYPE_INT: case JAVATYPE_LONG: case JAVATYPE_FLOAT: @@ -112,7 +110,12 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["visit_type_list"] = "visitList"; } - if (IsReferenceType(GetJavaType(descriptor))) { + if (javaType == JAVATYPE_BYTES) { + (*variables)["bytes_default"] = + ToUpper((*variables)["name"]) + "_DEFAULT_VALUE"; + } + + if (IsReferenceType(javaType)) { (*variables)["null_check"] = " if (value == null) {\n" " throw new NullPointerException();\n" @@ -204,6 +207,13 @@ GenerateInterfaceMembers(io::Printer* printer) const { void ImmutablePrimitiveFieldLiteGenerator:: GenerateMembers(io::Printer* printer) const { + if (IsByteStringWithCustomDefaultValue(descriptor_)) { + // allocate this once statically since we know ByteStrings are immutable + // values that can be reused. + printer->Print( + variables_, + "private static final $field_type$ $bytes_default$ = $default$;\n"); + } printer->Print(variables_, "private $field_type$ $name$_;\n"); PrintExtraFieldInfo(variables_, printer); @@ -287,7 +297,11 @@ GenerateFieldBuilderInitializationCode(io::Printer* printer) const { void ImmutablePrimitiveFieldLiteGenerator:: GenerateInitializationCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_ = $default$;\n"); + if (IsByteStringWithCustomDefaultValue(descriptor_)) { + printer->Print(variables_, "$name$_ = $bytes_default$;\n"); + } else if (!IsDefaultValueJavaDefault(descriptor_)) { + printer->Print(variables_, "$name$_ = $default$;\n"); + } } void ImmutablePrimitiveFieldLiteGenerator:: @@ -817,8 +831,8 @@ GenerateSerializationCode(io::Printer* printer) const { // That makes it safe to rely on the memoized size here. printer->Print(variables_, "if (get$capitalized_name$List().size() > 0) {\n" - " output.writeRawVarint32($tag$);\n" - " output.writeRawVarint32($name$MemoizedSerializedSize);\n" + " output.writeUInt32NoTag($tag$);\n" + " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n" "}\n" "for (int i = 0; i < $name$_.size(); i++) {\n" " output.write$capitalized_type$NoTag($repeated_get$(i));\n" diff --git a/src/google/protobuf/compiler/java/java_service.cc b/src/google/protobuf/compiler/java/java_service.cc index 11bfc12d..9f34f010 100644 --- a/src/google/protobuf/compiler/java/java_service.cc +++ b/src/google/protobuf/compiler/java/java_service.cc @@ -60,9 +60,10 @@ ImmutableServiceGenerator::ImmutableServiceGenerator( ImmutableServiceGenerator::~ImmutableServiceGenerator() {} void ImmutableServiceGenerator::Generate(io::Printer* printer) { - bool is_own_file = - MultipleJavaFiles(descriptor_->file(), /* immutable = */ true); + bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true); WriteServiceDocComment(printer, descriptor_); + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, + /* immutable = */ true); printer->Print( "public $static$ abstract class $classname$\n" " implements com.google.protobuf.Service {\n", diff --git a/src/google/protobuf/compiler/java/java_service.h b/src/google/protobuf/compiler/java/java_service.h index 6707e821..5fc9e2f6 100644 --- a/src/google/protobuf/compiler/java/java_service.h +++ b/src/google/protobuf/compiler/java/java_service.h @@ -74,8 +74,8 @@ class ServiceGenerator { class ImmutableServiceGenerator : public ServiceGenerator { public: - explicit ImmutableServiceGenerator(const ServiceDescriptor* descriptor, - Context* context); + ImmutableServiceGenerator(const ServiceDescriptor* descriptor, + Context* context); virtual ~ImmutableServiceGenerator(); virtual void Generate(io::Printer* printer); diff --git a/src/google/protobuf/compiler/java/java_shared_code_generator.cc b/src/google/protobuf/compiler/java/java_shared_code_generator.cc index 74253c3f..52893721 100644 --- a/src/google/protobuf/compiler/java/java_shared_code_generator.cc +++ b/src/google/protobuf/compiler/java/java_shared_code_generator.cc @@ -51,44 +51,53 @@ namespace protobuf { namespace compiler { namespace java { -SharedCodeGenerator::SharedCodeGenerator(const FileDescriptor* file) - : name_resolver_(new ClassNameResolver), - enforce_lite_(false), - file_(file) {} +SharedCodeGenerator::SharedCodeGenerator(const FileDescriptor* file, + const Options& options) + : name_resolver_(new ClassNameResolver), file_(file), options_(options) {} SharedCodeGenerator::~SharedCodeGenerator() { } void SharedCodeGenerator::Generate(GeneratorContext* context, - vector* file_list) { + vector* file_list, + vector* annotation_file_list) { string java_package = FileJavaPackage(file_); string package_dir = JavaPackageToDir(java_package); - if (HasDescriptorMethods(file_, enforce_lite_)) { + if (HasDescriptorMethods(file_, options_.enforce_lite)) { // Generate descriptors. string classname = name_resolver_->GetDescriptorClassName(file_); string filename = package_dir + classname + ".java"; file_list->push_back(filename); google::protobuf::scoped_ptr output(context->Open(filename)); - google::protobuf::scoped_ptr printer(new io::Printer(output.get(), '$')); - + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector annotation_collector( + &annotations); + google::protobuf::scoped_ptr printer( + new io::Printer(output.get(), '$', + options_.annotate_code ? &annotation_collector : NULL)); + string info_relative_path = classname + ".java.pb.meta"; + string info_full_path = filename + ".pb.meta"; printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "// source: $filename$\n" - "\n", - "filename", file_->name()); + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n", + "filename", file_->name()); if (!java_package.empty()) { printer->Print( "package $package$;\n" "\n", "package", java_package); } + PrintGeneratedAnnotation(printer.get(), '$', + options_.annotate_code ? info_relative_path : ""); printer->Print( - "public final class $classname$ {\n" - " public static com.google.protobuf.Descriptors.FileDescriptor\n" - " descriptor;\n" - " static {\n", - "classname", classname); + "public final class $classname$ {\n" + " public static com.google.protobuf.Descriptors.FileDescriptor\n" + " descriptor;\n" + " static {\n", + "classname", classname); + printer->Annotate("classname", file_->name()); printer->Indent(); printer->Indent(); GenerateDescriptors(printer.get()); @@ -98,6 +107,13 @@ void SharedCodeGenerator::Generate(GeneratorContext* context, " }\n" "}\n"); + if (options_.annotate_code) { + google::protobuf::scoped_ptr info_output( + context->Open(info_full_path)); + annotations.SerializeToZeroCopyStream(info_output.get()); + annotation_file_list->push_back(info_full_path); + } + printer.reset(); output.reset(); } diff --git a/src/google/protobuf/compiler/java/java_shared_code_generator.h b/src/google/protobuf/compiler/java/java_shared_code_generator.h index 3b573c07..7e1e1f17 100644 --- a/src/google/protobuf/compiler/java/java_shared_code_generator.h +++ b/src/google/protobuf/compiler/java/java_shared_code_generator.h @@ -43,6 +43,7 @@ #include #include +#include namespace google { namespace protobuf { @@ -66,15 +67,11 @@ namespace java { // and mutable API. Currently only descriptors are shared. class SharedCodeGenerator { public: - explicit SharedCodeGenerator(const FileDescriptor* file); + SharedCodeGenerator(const FileDescriptor* file, const Options& options); ~SharedCodeGenerator(); - void Generate(GeneratorContext* generator_context, - vector* file_list); - - void SetEnforceLite(bool value) { - enforce_lite_ = value; - } + void Generate(GeneratorContext* generator_context, vector* file_list, + vector* annotation_file_list); void GenerateDescriptors(io::Printer* printer); @@ -85,8 +82,8 @@ class SharedCodeGenerator { bool ShouldIncludeDependency(const FileDescriptor* descriptor); google::protobuf::scoped_ptr name_resolver_; - bool enforce_lite_; const FileDescriptor* file_; + const Options options_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SharedCodeGenerator); }; diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc index b67eeb53..b74c7447 100644 --- a/src/google/protobuf/compiler/java/java_string_field.cc +++ b/src/google/protobuf/compiler/java/java_string_field.cc @@ -712,7 +712,13 @@ void RepeatedImmutableStringFieldGenerator:: GenerateInterfaceMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$com.google.protobuf.ProtocolStringList\n" + // NOTE: the same method in the implementation class actually returns + // com.google.protobuf.ProtocolStringList (a subclass of List). It's + // changed between protobuf 2.5.0 release and protobuf 2.6.1 release. + // To retain binary compatibilty with both 2.5.0 and 2.6.1 generated + // code, we make this interface method return List so both methods + // with different return types exist in the compiled byte code. + "$deprecation$java.util.List\n" " get$capitalized_name$List();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index 8fb24bed..f5185ab1 100755 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -28,7 +28,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include "google/protobuf/compiler/js/js_generator.h" #include #include @@ -444,6 +444,11 @@ bool IgnoreField(const FieldDescriptor* field) { } +// Do we ignore this message type? +bool IgnoreMessage(const GeneratorOptions& options, const Descriptor* d) { + return d->options().map_entry(); +} + // Does JSPB ignore this entire oneof? True only if all fields are ignored. bool IgnoreOneof(const OneofDescriptor* oneof) { for (int i = 0; i < oneof->field_count(); i++) { @@ -454,7 +459,8 @@ bool IgnoreOneof(const OneofDescriptor* oneof) { return true; } -string JSIdent(const FieldDescriptor* field, +string JSIdent(const GeneratorOptions& options, + const FieldDescriptor* field, bool is_upper_camel, bool is_map) { string result; @@ -467,16 +473,20 @@ string JSIdent(const FieldDescriptor* field, ToUpperCamel(ParseLowerUnderscore(field->name())) : ToLowerCamel(ParseLowerUnderscore(field->name())); } - if (is_map) { + if (is_map || (field->is_map())) { + // JSPB-style or proto3-style map. result += "Map"; } else if (field->is_repeated()) { + // Repeated field. result += "List"; } return result; } -string JSObjectFieldName(const FieldDescriptor* field) { +string JSObjectFieldName(const GeneratorOptions& options, + const FieldDescriptor* field) { string name = JSIdent( + options, field, /* is_upper_camel = */ false, /* is_map = */ false); @@ -502,9 +512,10 @@ string JSByteGetterSuffix(BytesMode bytes_mode) { // Returns the field name as a capitalized portion of a getter/setter method // name, e.g. MyField for .getMyField(). -string JSGetterName(const FieldDescriptor* field, +string JSGetterName(const GeneratorOptions& options, + const FieldDescriptor* field, BytesMode bytes_mode = BYTES_DEFAULT) { - string name = JSIdent(field, + string name = JSIdent(options, field, /* is_upper_camel = */ true, /* is_map = */ false); if (field->type() == FieldDescriptor::TYPE_BYTES) { @@ -520,8 +531,9 @@ string JSGetterName(const FieldDescriptor* field, return name; } -string JSMapGetterName(const FieldDescriptor* field) { - return JSIdent(field, +string JSMapGetterName(const GeneratorOptions& options, + const FieldDescriptor* field) { + return JSIdent(options, field, /* is_upper_camel = */ true, /* is_map = */ true); } @@ -967,12 +979,24 @@ string JSBinaryReadWriteMethodName(const FieldDescriptor* field, return name; } -string JSBinaryReaderMethodName(const FieldDescriptor* field) { - return "read" + JSBinaryReadWriteMethodName(field, /* is_writer = */ false); +string JSBinaryReaderMethodName(const GeneratorOptions& options, + const FieldDescriptor* field) { + if (options.binary) { + return "jspb.BinaryReader.prototype.read" + + JSBinaryReadWriteMethodName(field, /* is_writer = */ false); + } else { + return "null"; + } } -string JSBinaryWriterMethodName(const FieldDescriptor* field) { - return "write" + JSBinaryReadWriteMethodName(field, /* is_writer = */ true); +string JSBinaryWriterMethodName(const GeneratorOptions& options, + const FieldDescriptor* field) { + if (options.binary) { + return "jspb.BinaryWriter.prototype.write" + + JSBinaryReadWriteMethodName(field, /* is_writer = */ true); + } else { + return "null"; + } } string JSReturnClause(const FieldDescriptor* desc) { @@ -986,7 +1010,7 @@ string JSReturnDoc(const GeneratorOptions& options, bool HasRepeatedFields(const Descriptor* desc) { for (int i = 0; i < desc->field_count(); i++) { - if (desc->field(i)->is_repeated()) { + if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) { return true; } } @@ -1021,7 +1045,7 @@ string OneofFieldsArrayName(const GeneratorOptions& options, string RepeatedFieldNumberList(const Descriptor* desc) { std::vector numbers; for (int i = 0; i < desc->field_count(); i++) { - if (desc->field(i)->is_repeated()) { + if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) { numbers.push_back(JSFieldIndex(desc->field(i))); } } @@ -1092,27 +1116,58 @@ string JSExtensionsObjectName(const GeneratorOptions& options, } } +static const int kMapKeyField = 1; +static const int kMapValueField = 2; + +const FieldDescriptor* MapFieldKey(const FieldDescriptor* field) { + assert(field->is_map()); + return field->message_type()->FindFieldByNumber(kMapKeyField); +} + +const FieldDescriptor* MapFieldValue(const FieldDescriptor* field) { + assert(field->is_map()); + return field->message_type()->FindFieldByNumber(kMapValueField); +} + string FieldDefinition(const GeneratorOptions& options, const FieldDescriptor* field) { - string qualifier = field->is_repeated() ? "repeated" : - (field->is_optional() ? "optional" : "required"); - string type, name; - if (field->type() == FieldDescriptor::TYPE_ENUM || - field->type() == FieldDescriptor::TYPE_MESSAGE) { - type = RelativeTypeName(field); - name = field->name(); - } else if (field->type() == FieldDescriptor::TYPE_GROUP) { - type = "group"; - name = field->message_type()->name(); + if (field->is_map()) { + const FieldDescriptor* key_field = MapFieldKey(field); + const FieldDescriptor* value_field = MapFieldValue(field); + string key_type = ProtoTypeName(options, key_field); + string value_type; + if (value_field->type() == FieldDescriptor::TYPE_ENUM || + value_field->type() == FieldDescriptor::TYPE_MESSAGE) { + value_type = RelativeTypeName(value_field); + } else { + value_type = ProtoTypeName(options, value_field); + } + return StringPrintf("map<%s, %s> %s = %d;", + key_type.c_str(), + value_type.c_str(), + field->name().c_str(), + field->number()); } else { - type = ProtoTypeName(options, field); - name = field->name(); + string qualifier = field->is_repeated() ? "repeated" : + (field->is_optional() ? "optional" : "required"); + string type, name; + if (field->type() == FieldDescriptor::TYPE_ENUM || + field->type() == FieldDescriptor::TYPE_MESSAGE) { + type = RelativeTypeName(field); + name = field->name(); + } else if (field->type() == FieldDescriptor::TYPE_GROUP) { + type = "group"; + name = field->message_type()->name(); + } else { + type = ProtoTypeName(options, field); + name = field->name(); + } + return StringPrintf("%s %s %s = %d;", + qualifier.c_str(), + type.c_str(), + name.c_str(), + field->number()); } - return StringPrintf("%s %s %s = %d;", - qualifier.c_str(), - type.c_str(), - name.c_str(), - field->number()); } string FieldComments(const FieldDescriptor* field, BytesMode bytes_mode) { @@ -1417,6 +1472,10 @@ void Generator::FindProvidesForMessage( io::Printer* printer, const Descriptor* desc, std::set* provided) const { + if (IgnoreMessage(options, desc)) { + return; + } + string name = GetPath(options, desc); provided->insert(name); @@ -1451,7 +1510,8 @@ void Generator::FindProvidesForFields( } string name = - GetPath(options, field->file()) + "." + JSObjectFieldName(field); + GetPath(options, field->file()) + "." + + JSObjectFieldName(options, field); provided->insert(name); } } @@ -1494,10 +1554,13 @@ void Generator::GenerateRequiresForLibrary( for (int i = 0; i < files.size(); i++) { for (int j = 0; j < files[i]->message_type_count(); j++) { - FindRequiresForMessage(options, - files[i]->message_type(j), - &required, &forwards, &have_message); + const Descriptor* desc = files[i]->message_type(j); + if (!IgnoreMessage(options, desc)) { + FindRequiresForMessage(options, desc, &required, &forwards, + &have_message); + } } + if (!have_extensions && HasExtensions(files[i])) { have_extensions = true; } @@ -1632,7 +1695,9 @@ void Generator::FindRequiresForField(const GeneratorOptions& options, forwards->insert(GetPath(options, field->enum_type())); } } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - required->insert(GetPath(options, field->message_type())); + if (!IgnoreMessage(options, field->message_type())) { + required->insert(GetPath(options, field->message_type())); + } } } @@ -1668,6 +1733,10 @@ void Generator::GenerateClassesAndEnums(const GeneratorOptions& options, void Generator::GenerateClass(const GeneratorOptions& options, io::Printer* printer, const Descriptor* desc) const { + if (IgnoreMessage(options, desc)) { + return; + } + if (!NamespaceOnly(desc)) { printer->Print("\n"); GenerateClassConstructor(options, printer, desc); @@ -1932,21 +2001,24 @@ void Generator::GenerateClassFieldToObject(const GeneratorOptions& options, io::Printer* printer, const FieldDescriptor* field) const { printer->Print("$fieldname$: ", - "fieldname", JSObjectFieldName(field)); + "fieldname", JSObjectFieldName(options, field)); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (field->is_map()) { + printer->Print("(f = msg.get$name$(true)) ? f.toArray() : []", + "name", JSGetterName(options, field)); + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { // Message field. if (field->is_repeated()) { { printer->Print("jspb.Message.toObjectList(msg.get$getter$(),\n" " $type$.toObject, includeInstance)", - "getter", JSGetterName(field), + "getter", JSGetterName(options, field), "type", SubmessageTypeRef(options, field)); } } else { printer->Print("(f = msg.get$getter$()) && " "$type$.toObject(includeInstance, f)", - "getter", JSGetterName(field), + "getter", JSGetterName(options, field), "type", SubmessageTypeRef(options, field)); } } else { @@ -1956,7 +2028,7 @@ void Generator::GenerateClassFieldToObject(const GeneratorOptions& options, // Delegate to the generated get() method in order not to duplicate // the proto3-field-default-value or byte-coercion logic here. printer->Print("msg.get$getter$()", - "getter", JSGetterName(field, BYTES_B64)); + "getter", JSGetterName(options, field, BYTES_B64)); } else { if (field->has_default_value()) { printer->Print("jspb.Message.getField(msg, $index$) == null ? " @@ -2017,7 +2089,17 @@ void Generator::GenerateClassFieldFromObject( const GeneratorOptions& options, io::Printer* printer, const FieldDescriptor* field) const { - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + + if (field->is_map()) { + // `msg` is a newly-constructed message object that has not yet built any + // map containers wrapping underlying arrays, so we can simply directly set + // the array here without fear of a stale wrapper. + printer->Print( + " goog.isDef(obj.$name$) && " + "jspb.Message.setField(msg, $index$, obj.$name$);\n", + "name", JSObjectFieldName(options, field), + "index", JSFieldIndex(field)); + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { // Message field (singular or repeated) if (field->is_repeated()) { { @@ -2027,7 +2109,7 @@ void Generator::GenerateClassFieldFromObject( " msg, $index$, goog.array.map(obj.$name$, function(i) {\n" " return $fieldclass$.fromObject(i);\n" " }));\n", - "name", JSObjectFieldName(field), + "name", JSObjectFieldName(options, field), "index", JSFieldIndex(field), "fieldclass", SubmessageTypeRef(options, field)); } @@ -2035,7 +2117,7 @@ void Generator::GenerateClassFieldFromObject( printer->Print( " goog.isDef(obj.$name$) && jspb.Message.setWrapperField(\n" " msg, $index$, $fieldclass$.fromObject(obj.$name$));\n", - "name", JSObjectFieldName(field), + "name", JSObjectFieldName(options, field), "index", JSFieldIndex(field), "fieldclass", SubmessageTypeRef(options, field)); } @@ -2044,7 +2126,7 @@ void Generator::GenerateClassFieldFromObject( printer->Print( " goog.isDef(obj.$name$) && jspb.Message.setField(msg, $index$, " "obj.$name$);\n", - "name", JSObjectFieldName(field), + "name", JSObjectFieldName(options, field), "index", JSFieldIndex(field)); } } @@ -2114,17 +2196,93 @@ void GenerateBytesWrapper(const GeneratorOptions& options, "comment", FieldComments(field, bytes_mode), "type", type, "class", GetPath(options, field->containing_type()), - "name", JSGetterName(field, bytes_mode), + "name", JSGetterName(options, field, bytes_mode), "list", field->is_repeated() ? "List" : "", "suffix", JSByteGetterSuffix(bytes_mode), - "defname", JSGetterName(field, BYTES_DEFAULT)); + "defname", JSGetterName(options, field, BYTES_DEFAULT)); } void Generator::GenerateClassField(const GeneratorOptions& options, io::Printer* printer, const FieldDescriptor* field) const { - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (field->is_map()) { + const FieldDescriptor* key_field = MapFieldKey(field); + const FieldDescriptor* value_field = MapFieldValue(field); + // Map field: special handling to instantiate the map object on demand. + string key_type = + JSFieldTypeAnnotation( + options, key_field, + /* force_optional = */ false, + /* force_present = */ true, + /* singular_if_not_packed = */ false); + string value_type = + JSFieldTypeAnnotation( + options, value_field, + /* force_optional = */ false, + /* force_present = */ true, + /* singular_if_not_packed = */ false); + + printer->Print( + "/**\n" + " * $fielddef$\n" + " * @param {boolean=} opt_noLazyCreate Do not create the map if\n" + " * empty, instead returning `undefined`\n" + " * @return {!jspb.Map<$keytype$,$valuetype$>}\n" + " */\n", + "fielddef", FieldDefinition(options, field), + "keytype", key_type, + "valuetype", value_type); + printer->Print( + "$class$.prototype.get$name$ = function(opt_noLazyCreate) {\n" + " return /** @type {!jspb.Map<$keytype$,$valuetype$>} */ (\n", + "class", GetPath(options, field->containing_type()), + "name", JSGetterName(options, field), + "keytype", key_type, + "valuetype", value_type); + printer->Print( + " jspb.Message.getMapField(this, $index$, opt_noLazyCreate", + "index", JSFieldIndex(field)); + + if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { + printer->Print(",\n" + " $messageType$", + "messageType", GetPath(options, value_field->message_type())); + } else if (options.binary) { + printer->Print(",\n" + " null"); + } + + if (options.binary) { + printer->Print(",\n" + " $keyWriterFn$,\n" + " $keyReaderFn$,\n" + " $valueWriterFn$,\n" + " $valueReaderFn$", + "keyWriterFn", JSBinaryWriterMethodName(options, key_field), + "keyReaderFn", JSBinaryReaderMethodName(options, key_field), + "valueWriterFn", JSBinaryWriterMethodName(options, value_field), + "valueReaderFn", JSBinaryReaderMethodName(options, value_field)); + + if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { + printer->Print(",\n" + " $messageType$.serializeBinaryToWriter,\n" + " $messageType$.deserializeBinaryFromReader", + "messageType", GetPath(options, value_field->message_type())); + } + } + + printer->Print( + "));\n"); + + printer->Print( + "};\n" + "\n" + "\n"); + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + // Message field: special handling in order to wrap the underlying data + // array with a message object. + printer->Print( "/**\n" " * $fielddef$\n" @@ -2146,7 +2304,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "\n" "\n", "class", GetPath(options, field->containing_type()), - "name", JSGetterName(field), + "name", JSGetterName(options, field), "type", JSFieldTypeAnnotation(options, field, /* force_optional = */ false, /* force_present = */ false, @@ -2167,7 +2325,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, /* singular_if_not_packed = */ false), "returndoc", JSReturnDoc(options, field), "class", GetPath(options, field->containing_type()), - "name", JSGetterName(field), + "name", JSGetterName(options, field), "oneoftag", (field->containing_oneof() ? "Oneof" : ""), "repeatedtag", (field->is_repeated() ? "Repeated" : "")); @@ -2188,7 +2346,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "\n" "\n", "class", GetPath(options, field->containing_type()), - "name", JSGetterName(field), + "name", JSGetterName(options, field), "clearedvalue", (field->is_repeated() ? "[]" : "undefined"), "returnvalue", JSReturnClause(field)); @@ -2230,7 +2388,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, printer->Print( "$class$.prototype.get$name$ = function() {\n", "class", GetPath(options, field->containing_type()), - "name", JSGetterName(field)); + "name", JSGetterName(options, field)); if (untyped) { printer->Print( @@ -2315,7 +2473,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "$class$.prototype.set$name$ = function(value) {\n" " jspb.Message.set$oneoftag$Field(this, $index$", "class", GetPath(options, field->containing_type()), - "name", JSGetterName(field), + "name", JSGetterName(options, field), "oneoftag", (field->containing_oneof() ? "Oneof" : ""), "index", JSFieldIndex(field)); printer->Print( @@ -2345,7 +2503,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "$class$.prototype.clear$name$ = function() {\n" " jspb.Message.set$oneoftag$Field(this, $index$$oneofgroup$, ", "class", GetPath(options, field->containing_type()), - "name", JSGetterName(field), + "name", JSGetterName(options, field), "oneoftag", (field->containing_oneof() ? "Oneof" : ""), "oneofgroup", (field->containing_oneof() ? (", " + JSOneofArray(options, field)) : ""), @@ -2461,40 +2619,49 @@ void Generator::GenerateClassDeserializeBinaryField( printer->Print(" case $num$:\n", "num", SimpleItoa(field->number())); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - printer->Print( - " var value = new $fieldclass$;\n" - " reader.read$msgOrGroup$($grpfield$value," - "$fieldclass$.deserializeBinaryFromReader);\n", - "fieldclass", SubmessageTypeRef(options, field), - "msgOrGroup", (field->type() == FieldDescriptor::TYPE_GROUP) ? - "Group" : "Message", - "grpfield", (field->type() == FieldDescriptor::TYPE_GROUP) ? - (SimpleItoa(field->number()) + ", ") : ""); - } else { + if (field->is_map()) { printer->Print( - " var value = /** @type {$fieldtype$} */ (reader.$reader$());\n", - "fieldtype", JSFieldTypeAnnotation(options, field, false, true, - /* singular_if_not_packed = */ true, - BYTES_U8), - "reader", JSBinaryReaderMethodName(field)); - } - - if (field->is_repeated() && !field->is_packed()) { - // Repeated fields receive a |value| one at at a time; append to array - // returned by get$name$(). Annoyingly, we have to call 'set' after - // changing the array. - printer->Print(" msg.get$name$().push(value);\n", "name", - JSGetterName(field)); - printer->Print(" msg.set$name$(msg.get$name$());\n", "name", - JSGetterName(field)); + " var value = msg.get$name$();\n" + " reader.readMessage(value, jspb.Map.deserializeBinary);\n", + "name", JSGetterName(options, field)); } else { - // Singular fields, and packed repeated fields, receive a |value| either as - // the field's value or as the array of all the field's values; set this as - // the field's value directly. - printer->Print( - " msg.set$name$(value);\n", - "name", JSGetterName(field)); + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer->Print( + " var value = new $fieldclass$;\n" + " reader.read$msgOrGroup$($grpfield$value," + "$fieldclass$.deserializeBinaryFromReader);\n", + "fieldclass", SubmessageTypeRef(options, field), + "msgOrGroup", (field->type() == FieldDescriptor::TYPE_GROUP) ? + "Group" : "Message", + "grpfield", (field->type() == FieldDescriptor::TYPE_GROUP) ? + (SimpleItoa(field->number()) + ", ") : ""); + } else { + printer->Print( + " var value = /** @type {$fieldtype$} */ " + "(reader.read$reader$());\n", + "fieldtype", JSFieldTypeAnnotation(options, field, false, true, + /* singular_if_not_packed */ true, + BYTES_U8), + "reader", + JSBinaryReadWriteMethodName(field, /* is_writer = */ false)); + } + + if (field->is_repeated() && !field->is_packed()) { + // Repeated fields receive a |value| one at at a time; append to array + // returned by get$name$(). Annoyingly, we have to call 'set' after + // changing the array. + printer->Print(" msg.get$name$().push(value);\n", "name", + JSGetterName(options, field)); + printer->Print(" msg.set$name$(msg.get$name$());\n", "name", + JSGetterName(options, field)); + } else { + // Singular fields, and packed repeated fields, receive a |value| either + // as the field's value or as the array of all the field's values; set + // this as the field's value directly. + printer->Print( + " msg.set$name$(value);\n", + "name", JSGetterName(options, field)); + } } printer->Print(" break;\n"); @@ -2559,10 +2726,18 @@ void Generator::GenerateClassSerializeBinaryField( io::Printer* printer, const FieldDescriptor* field) const { printer->Print( - " f = this.get$name$();\n", - "name", JSGetterName(field, BYTES_U8)); + " f = this.get$name$($nolazy$);\n", + "name", JSGetterName(options, field, BYTES_U8), + // No lazy creation for maps containers -- fastpath the empty case. + "nolazy", (field->is_map()) ? "true" : ""); - if (field->is_repeated()) { + + // Print an `if (condition)` statement that evaluates to true if the field + // goes on the wire. + if (field->is_map()) { + printer->Print( + " if (f && f.getLength() > 0) {\n"); + } else if (field->is_repeated()) { printer->Print( " if (f.length > 0) {\n"); } else { @@ -2605,23 +2780,35 @@ void Generator::GenerateClassSerializeBinaryField( } } - printer->Print( - " writer.$writer$(\n" - " $index$,\n" - " f", - "writer", JSBinaryWriterMethodName(field), - "index", SimpleItoa(field->number())); - - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + // Write the field on the wire. + if (field->is_map()) { printer->Print( - ",\n" - " $submsg$.serializeBinaryToWriter\n", - "submsg", SubmessageTypeRef(options, field)); + " f.serializeBinary($index$, writer);\n", + "index", SimpleItoa(field->number())); } else { - printer->Print("\n"); + printer->Print( + " writer.write$method$(\n" + " $index$,\n" + " f", + "method", JSBinaryReadWriteMethodName(field, /* is_writer = */ true), + "index", SimpleItoa(field->number())); + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + !(field->is_map())) { + printer->Print( + ",\n" + " $submsg$.serializeBinaryToWriter\n", + "submsg", SubmessageTypeRef(options, field)); + } else { + printer->Print("\n"); + } + + printer->Print( + " );\n"); } + + // Close the `if`. printer->Print( - " );\n" " }\n"); } @@ -2665,7 +2852,7 @@ void Generator::GenerateExtension(const GeneratorOptions& options, " * @type {!jspb.ExtensionFieldInfo.<$extensionType$>}\n" " */\n" "$class$.$name$ = new jspb.ExtensionFieldInfo(\n", - "name", JSObjectFieldName(field), + "name", JSObjectFieldName(options, field), "class", extension_scope, "extensionType", JSFieldTypeAnnotation( options, field, @@ -2681,7 +2868,7 @@ void Generator::GenerateExtension(const GeneratorOptions& options, " $toObject$),\n" " $repeated$", "index", SimpleItoa(field->number()), - "name", JSObjectFieldName(field), + "name", JSObjectFieldName(options, field), "ctor", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ? SubmessageTypeRef(options, field) : string("null")), "toObject", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ? @@ -2692,13 +2879,13 @@ void Generator::GenerateExtension(const GeneratorOptions& options, if (options.binary) { printer->Print( ",\n" - " jspb.BinaryReader.prototype.$binaryReaderFn$,\n" - " jspb.BinaryWriter.prototype.$binaryWriterFn$,\n" + " $binaryReaderFn$,\n" + " $binaryWriterFn$,\n" " $binaryMessageSerializeFn$,\n" " $binaryMessageDeserializeFn$,\n" " $isPacked$);\n", - "binaryReaderFn", JSBinaryReaderMethodName(field), - "binaryWriterFn", JSBinaryWriterMethodName(field), + "binaryReaderFn", JSBinaryReaderMethodName(options, field), + "binaryWriterFn", JSBinaryWriterMethodName(options, field), "binaryMessageSerializeFn", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ? (SubmessageTypeRef(options, field) + @@ -2721,7 +2908,7 @@ void Generator::GenerateExtension(const GeneratorOptions& options, field->containing_type()), "index", SimpleItoa(field->number()), "class", extension_scope, - "name", JSObjectFieldName(field)); + "name", JSObjectFieldName(options, field)); } bool GeneratorOptions::ParseFromOptions( diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc index 66ad13b7..2f3c5b8f 100644 --- a/src/google/protobuf/compiler/main.cc +++ b/src/google/protobuf/compiler/main.cc @@ -35,6 +35,8 @@ #include #include #include +// TODO(teboring): Add it back when php implementation is ready +// #include #include #include #include @@ -66,6 +68,12 @@ int main(int argc, char* argv[]) { cli.RegisterGenerator("--javanano_out", &javanano_generator, "Generate Java Nano source file."); + // TODO(teboring): Add it back when php implementation is ready + // PHP + // google::protobuf::compiler::php::Generator php_generator; + // cli.RegisterGenerator("--php_out", &php_generator, + // "Generate PHP source file."); + // Ruby google::protobuf::compiler::ruby::Generator rb_generator; cli.RegisterGenerator("--ruby_out", &rb_generator, diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index 90ded4de..214d7c9c 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -1630,6 +1630,16 @@ bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl, return false; } + if (LookingAt("option")) { + LocationRecorder option_location( + oneof_location, OneofDescriptorProto::kOptionsFieldNumber); + if (!ParseOption(oneof_decl->mutable_options(), option_location, + containing_file, OPTION_STATEMENT)) { + return false; + } + continue; + } + // Print a nice error if the user accidentally tries to place a label // on an individual member of a oneof. if (LookingAt("required") || diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index e9d50a1d..c4d48fc6 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -373,8 +373,8 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorRequest) } -::google::protobuf::uint8* CodeGeneratorRequest::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* CodeGeneratorRequest::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorRequest) // repeated string file_to_generate = 1; for (int i = 0; i < this->file_to_generate_size(); i++) { @@ -400,8 +400,8 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( // repeated .google.protobuf.FileDescriptorProto proto_file = 15; for (unsigned int i = 0, n = this->proto_file_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 15, this->proto_file(i), target); + InternalWriteMessageNoVirtualToArray( + 15, this->proto_file(i), false, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -878,8 +878,8 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorResponse.File) } -::google::protobuf::uint8* CodeGeneratorResponse_File::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* CodeGeneratorResponse_File::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse.File) // optional string name = 1; if (has_name()) { @@ -1208,8 +1208,8 @@ void CodeGeneratorResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorResponse) } -::google::protobuf::uint8* CodeGeneratorResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* CodeGeneratorResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse) // optional string error = 1; if (has_error()) { @@ -1225,8 +1225,8 @@ void CodeGeneratorResponse::SerializeWithCachedSizes( // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; for (unsigned int i = 0, n = this->file_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 15, this->file(i), target); + InternalWriteMessageNoVirtualToArray( + 15, this->file(i), false, target); } if (_internal_metadata_.have_unknown_fields()) { diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 510202f0..13eeb69f 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -45,7 +45,7 @@ class CodeGeneratorResponse_File; // =================================================================== -class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message { +class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorRequest) */ { public: CodeGeneratorRequest(); virtual ~CodeGeneratorRequest(); @@ -87,7 +87,11 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -169,7 +173,7 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message }; // ------------------------------------------------------------------- -class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::Message { +class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse.File) */ { public: CodeGeneratorResponse_File(); virtual ~CodeGeneratorResponse_File(); @@ -211,7 +215,11 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -293,7 +301,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M }; // ------------------------------------------------------------------- -class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Message { +class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse) */ { public: CodeGeneratorResponse(); virtual ~CodeGeneratorResponse(); @@ -335,7 +343,11 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc index 0553dd0d..cc54a8ab 100644 --- a/src/google/protobuf/compiler/python/python_generator.cc +++ b/src/google/protobuf/compiler/python/python_generator.cc @@ -707,11 +707,18 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { m["name"] = desc->name(); m["full_name"] = desc->full_name(); m["index"] = SimpleItoa(desc->index()); + string options_string = + OptionsValue("OneofOptions", desc->options().SerializeAsString()); + if (options_string == "None") { + m["options"] = ""; + } else { + m["options"] = ", options=" + options_string; + } printer_->Print( m, "_descriptor.OneofDescriptor(\n" " name='$name$', full_name='$full_name$',\n" - " index=$index$, containing_type=None, fields=[]),\n"); + " index=$index$, containing_type=None, fields=[]$options$),\n"); } printer_->Outdent(); printer_->Print("],\n"); @@ -1235,6 +1242,18 @@ void Generator::FixAllDescriptorOptions() const { } } +void Generator::FixOptionsForOneof(const OneofDescriptor& oneof) const { + string oneof_options = OptionsValue( + "OneofOptions", oneof.options().SerializeAsString()); + if (oneof_options != "None") { + string oneof_name = strings::Substitute( + "$0.$1['$2']", + ModuleLevelDescriptorName(*oneof.containing_type()), + "oneofs_by_name", oneof.name()); + PrintDescriptorOptionsFixingCode(oneof_name, oneof_options, printer_); + } +} + // Prints expressions that set the options for an enum descriptor and its // value descriptors. void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const { @@ -1288,6 +1307,10 @@ void Generator::FixOptionsForMessage(const Descriptor& descriptor) const { for (int i = 0; i < descriptor.nested_type_count(); ++i) { FixOptionsForMessage(*descriptor.nested_type(i)); } + // Oneofs. + for (int i = 0; i < descriptor.oneof_decl_count(); ++i) { + FixOptionsForOneof(*descriptor.oneof_decl(i)); + } // Enums. for (int i = 0; i < descriptor.enum_type_count(); ++i) { FixOptionsForEnum(*descriptor.enum_type(i)); diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h index aa0f5fce..7583aa65 100644 --- a/src/google/protobuf/compiler/python/python_generator.h +++ b/src/google/protobuf/compiler/python/python_generator.h @@ -48,6 +48,7 @@ class Descriptor; class EnumDescriptor; class EnumValueDescriptor; class FieldDescriptor; +class OneofDescriptor; class ServiceDescriptor; namespace io { class Printer; } @@ -148,6 +149,7 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator { void FixAllDescriptorOptions() const; void FixOptionsForField(const FieldDescriptor& field) const; + void FixOptionsForOneof(const OneofDescriptor& oneof) const; void FixOptionsForEnum(const EnumDescriptor& descriptor) const; void FixOptionsForMessage(const Descriptor& descriptor) const; diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc index 1b04cb32..c0acb407 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc @@ -45,22 +45,8 @@ namespace compiler { namespace ruby { namespace { -string FindRubyTestDir(const string& file) { - // Inspired by TestSourceDir() in src/google/protobuf/testing/googletest.cc. -#ifndef GOOGLE_THIRD_PARTY_PROTOBUF - string prefix = "."; - while (!File::Exists(prefix + "/src/google/protobuf/compiler/ruby" + file)) { - if (!File::Exists(prefix)) { - GOOGLE_LOG(FATAL) - << "Could not find Ruby test directory. Please run tests from " - "somewhere within the protobuf source package."; - } - prefix += "/.."; - } - return prefix + "/src/google/protobuf/compiler/ruby"; -#else - return "third_party/protobuf/src/google/protobuf/compiler/ruby"; -#endif // GOOGLE_THIRD_PARTY_PROTOBUF +string FindRubyTestDir() { + return TestSourceDir() + "/google/protobuf/compiler/ruby"; } // This test is a simple golden-file test over the output of the Ruby code @@ -71,7 +57,7 @@ string FindRubyTestDir(const string& file) { // extensions to the point where we can do this test in a more automated way. TEST(RubyGeneratorTest, GeneratorTest) { - string ruby_tests = FindRubyTestDir("/ruby_generated_code.proto"); + string ruby_tests = FindRubyTestDir(); google::protobuf::compiler::CommandLineInterface cli; cli.SetInputsAreProtoPathRelative(true); diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 56e11fa9..9b20946c 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -1896,6 +1896,9 @@ void FieldDescriptor::CopyJsonNameTo(FieldDescriptorProto* proto) const { void OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const { proto->set_name(name()); + if (&options() != &OneofOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } } void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const { @@ -2435,6 +2438,9 @@ void OneofDescriptor::DebugString(int depth, string* contents, comment_printer.AddPreComment(contents); strings::SubstituteAndAppend( contents, "$0 oneof $1 {", prefix, name()); + + FormatLineOptions(depth, options(), contents); + if (debug_string_options.elide_oneof_body) { contents->append(" ... }\n"); } else { @@ -4523,6 +4529,13 @@ void DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto, result->field_count_ = 0; result->fields_ = NULL; + // Copy options. + if (!proto.has_options()) { + result->options_ = NULL; // Will set to default_instance later. + } else { + AllocateOptions(proto.options(), result); + } + AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result)); } @@ -4783,6 +4796,10 @@ void DescriptorBuilder::CrossLinkMessage( oneof_decl->fields_ = tables_->AllocateArray(oneof_decl->field_count_); oneof_decl->field_count_ = 0; + + if (oneof_decl->options_ == NULL) { + oneof_decl->options_ = &OneofOptions::default_instance(); + } } // Then fill them in. @@ -5181,7 +5198,7 @@ void DescriptorBuilder::ValidateProto3Message( if (name_to_field.find(lowercase_name) != name_to_field.end()) { AddError(message->full_name(), proto, DescriptorPool::ErrorCollector::OTHER, - "The JSON camcel-case name of field \"" + + "The JSON camel-case name of field \"" + message->field(i)->name() + "\" conflicts with field \"" + name_to_field[lowercase_name]->name() + "\". This is not " + "allowed in proto3."); @@ -5237,6 +5254,7 @@ void DescriptorBuilder::ValidateProto3Enum( } } + void DescriptorBuilder::ValidateMessageOptions(Descriptor* message, const DescriptorProto& proto) { VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field); @@ -5257,6 +5275,7 @@ void DescriptorBuilder::ValidateMessageOptions(Descriptor* message, max_extension_range)); } } + } void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field, diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index 3ecc0a9c..b040b62c 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -62,7 +62,6 @@ #include #include #include -#include // TYPE_BOOL is defined in the MacOS's ConditionalMacros.h. #ifdef TYPE_BOOL @@ -95,6 +94,7 @@ class MethodDescriptorProto; class FileDescriptorProto; class MessageOptions; class FieldOptions; +class OneofOptions; class EnumOptions; class EnumValueOptions; class ServiceOptions; @@ -750,6 +750,8 @@ class LIBPROTOBUF_EXPORT OneofDescriptor { // .proto file. Does not include extensions. const FieldDescriptor* field(int index) const; + const OneofOptions& options() const; + // See Descriptor::CopyTo(). void CopyTo(OneofDescriptorProto* proto) const; @@ -767,6 +769,8 @@ class LIBPROTOBUF_EXPORT OneofDescriptor { bool GetSourceLocation(SourceLocation* out_location) const; private: + typedef OneofOptions OptionsType; + // Allows access to GetLocationPath for annotations. friend class ::google::protobuf::io::Printer; @@ -784,6 +788,8 @@ class LIBPROTOBUF_EXPORT OneofDescriptor { bool is_extendable_; int field_count_; const FieldDescriptor** fields_; + const OneofOptions* options_; + // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate() and AllocateArray() // in descriptor.cc and update them to initialize the field. @@ -1708,6 +1714,7 @@ PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, name) PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, full_name) PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, containing_type, const Descriptor*) PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, field_count, int) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(OneofDescriptor, OneofOptions) PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, name) PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, full_name) diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 4d5c4d99..4e2c9dcf 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -69,6 +69,9 @@ const ::google::protobuf::internal::GeneratedMessageReflection* FieldOptions_reflection_ = NULL; const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor_ = NULL; const ::google::protobuf::EnumDescriptor* FieldOptions_JSType_descriptor_ = NULL; +const ::google::protobuf::Descriptor* OneofOptions_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + OneofOptions_reflection_ = NULL; const ::google::protobuf::Descriptor* EnumOptions_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* EnumOptions_reflection_ = NULL; @@ -233,8 +236,9 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0); FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1); OneofDescriptorProto_descriptor_ = file->message_type(4); - static const int OneofDescriptorProto_offsets_[1] = { + static const int OneofDescriptorProto_offsets_[2] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, options_), }; OneofDescriptorProto_reflection_ = ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( @@ -390,7 +394,22 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { -1); FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0); FieldOptions_JSType_descriptor_ = FieldOptions_descriptor_->enum_type(1); - EnumOptions_descriptor_ = file->message_type(12); + OneofOptions_descriptor_ = file->message_type(12); + static const int OneofOptions_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, uninterpreted_option_), + }; + OneofOptions_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + OneofOptions_descriptor_, + OneofOptions::default_instance_, + OneofOptions_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, _has_bits_[0]), + -1, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, _extensions_), + sizeof(OneofOptions), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, _internal_metadata_), + -1); + EnumOptions_descriptor_ = file->message_type(13); static const int EnumOptions_offsets_[3] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, allow_alias_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, deprecated_), @@ -407,7 +426,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { sizeof(EnumOptions), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _internal_metadata_), -1); - EnumValueOptions_descriptor_ = file->message_type(13); + EnumValueOptions_descriptor_ = file->message_type(14); static const int EnumValueOptions_offsets_[2] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, deprecated_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, uninterpreted_option_), @@ -423,7 +442,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { sizeof(EnumValueOptions), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _internal_metadata_), -1); - ServiceOptions_descriptor_ = file->message_type(14); + ServiceOptions_descriptor_ = file->message_type(15); static const int ServiceOptions_offsets_[2] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, deprecated_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, uninterpreted_option_), @@ -439,7 +458,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { sizeof(ServiceOptions), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _internal_metadata_), -1); - MethodOptions_descriptor_ = file->message_type(15); + MethodOptions_descriptor_ = file->message_type(16); static const int MethodOptions_offsets_[2] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, deprecated_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, uninterpreted_option_), @@ -455,7 +474,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { sizeof(MethodOptions), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _internal_metadata_), -1); - UninterpretedOption_descriptor_ = file->message_type(16); + UninterpretedOption_descriptor_ = file->message_type(17); static const int UninterpretedOption_offsets_[7] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_), @@ -492,7 +511,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { sizeof(UninterpretedOption_NamePart), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _internal_metadata_), -1); - SourceCodeInfo_descriptor_ = file->message_type(17); + SourceCodeInfo_descriptor_ = file->message_type(18); static const int SourceCodeInfo_offsets_[1] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_), }; @@ -526,7 +545,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { sizeof(SourceCodeInfo_Location), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _internal_metadata_), -1); - GeneratedCodeInfo_descriptor_ = file->message_type(18); + GeneratedCodeInfo_descriptor_ = file->message_type(19); static const int GeneratedCodeInfo_offsets_[1] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo, annotation_), }; @@ -599,6 +618,8 @@ void protobuf_RegisterTypes(const ::std::string&) { MessageOptions_descriptor_, &MessageOptions::default_instance()); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( FieldOptions_descriptor_, &FieldOptions::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + OneofOptions_descriptor_, &OneofOptions::default_instance()); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( EnumOptions_descriptor_, &EnumOptions::default_instance()); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( @@ -652,6 +673,8 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() { delete MessageOptions_reflection_; delete FieldOptions::default_instance_; delete FieldOptions_reflection_; + delete OneofOptions::default_instance_; + delete OneofOptions_reflection_; delete EnumOptions::default_instance_; delete EnumOptions_reflection_; delete EnumValueOptions::default_instance_; @@ -729,87 +752,91 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { "SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SI" "NT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LABE" "L_OPTIONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LABE" - "L_REPEATED\020\003\"$\n\024OneofDescriptorProto\022\014\n\004" - "name\030\001 \001(\t\"\214\001\n\023EnumDescriptorProto\022\014\n\004na" - "me\030\001 \001(\t\0228\n\005value\030\002 \003(\0132).google.protobu" - "f.EnumValueDescriptorProto\022-\n\007options\030\003 " - "\001(\0132\034.google.protobuf.EnumOptions\"l\n\030Enu" - "mValueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006n" - "umber\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google.pr" - "otobuf.EnumValueOptions\"\220\001\n\026ServiceDescr" - "iptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\013" - "2&.google.protobuf.MethodDescriptorProto" - "\0220\n\007options\030\003 \001(\0132\037.google.protobuf.Serv" - "iceOptions\"\301\001\n\025MethodDescriptorProto\022\014\n\004" - "name\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.pr" - "otobuf.MethodOptions\022\037\n\020client_streaming" - "\030\005 \001(\010:\005false\022\037\n\020server_streaming\030\006 \001(\010:" - "\005false\"\207\005\n\013FileOptions\022\024\n\014java_package\030\001" - " \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023ja" - "va_multiple_files\030\n \001(\010:\005false\022,\n\035java_g" - "enerate_equals_and_hash\030\024 \001(\010:\005false\022%\n\026" - "java_string_check_utf8\030\033 \001(\010:\005false\022F\n\014o" - "ptimize_for\030\t \001(\0162).google.protobuf.File" - "Options.OptimizeMode:\005SPEED\022\022\n\ngo_packag" - "e\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(\010:\005fa" - "lse\022$\n\025java_generic_services\030\021 \001(\010:\005fals" - "e\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022\031\n" - "\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_enable_ar" - "enas\030\037 \001(\010:\005false\022\031\n\021objc_class_prefix\030$" - " \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022C\n\024uninte" - "rpreted_option\030\347\007 \003(\0132$.google.protobuf." - "UninterpretedOption\":\n\014OptimizeMode\022\t\n\005S" - "PEED\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\002J\004\010&\020\'\"\346\001\n\016MessageOptions\022&\n\027m" - "essage_set_wire_format\030\001 \001(\010:\005false\022.\n\037n" - "o_standard_descriptor_accessor\030\002 \001(\010:\005fa" - "lse\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\021\n\tmap_en" - "try\030\007 \001(\010\022C\n\024uninterpreted_option\030\347\007 \003(\013" - "2$.google.protobuf.UninterpretedOption*\t" - "\010\350\007\020\200\200\200\200\002\"\230\003\n\014FieldOptions\022:\n\005ctype\030\001 \001(" - "\0162#.google.protobuf.FieldOptions.CType:\006" - "STRING\022\016\n\006packed\030\002 \001(\010\022\?\n\006jstype\030\006 \001(\0162$" - ".google.protobuf.FieldOptions.JSType:\tJS" - "_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005false\022\031\n\ndeprecat" - "ed\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001(\010:\005false\022C\n\024" - "uninterpreted_option\030\347\007 \003(\0132$.google.pro" - "tobuf.UninterpretedOption\"/\n\005CType\022\n\n\006ST" - "RING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020\002\"5\n\006JS" - "Type\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS_STRING\020\001\022\r\n\tJS" - "_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOptions\022\023\n\013" - "allow_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005f" + "L_REPEATED\020\003\"T\n\024OneofDescriptorProto\022\014\n\004" + "name\030\001 \001(\t\022.\n\007options\030\002 \001(\0132\035.google.pro" + "tobuf.OneofOptions\"\214\001\n\023EnumDescriptorPro" + "to\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132).google" + ".protobuf.EnumValueDescriptorProto\022-\n\007op" + "tions\030\003 \001(\0132\034.google.protobuf.EnumOption" + "s\"l\n\030EnumValueDescriptorProto\022\014\n\004name\030\001 " + "\001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.g" + "oogle.protobuf.EnumValueOptions\"\220\001\n\026Serv" + "iceDescriptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006meth" + "od\030\002 \003(\0132&.google.protobuf.MethodDescrip" + "torProto\0220\n\007options\030\003 \001(\0132\037.google.proto" + "buf.ServiceOptions\"\301\001\n\025MethodDescriptorP" + "roto\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.g" + "oogle.protobuf.MethodOptions\022\037\n\020client_s" + "treaming\030\005 \001(\010:\005false\022\037\n\020server_streamin" + "g\030\006 \001(\010:\005false\"\207\005\n\013FileOptions\022\024\n\014java_p" + "ackage\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," + "\n\035java_generate_equals_and_hash\030\024 \001(\010:\005f" + "alse\022%\n\026java_string_check_utf8\030\033 \001(\010:\005fa" + "lse\022F\n\014optimize_for\030\t \001(\0162).google.proto" + "buf.FileOptions.OptimizeMode:\005SPEED\022\022\n\ng" + "o_package\030\013 \001(\t\022\"\n\023cc_generic_services\030\020" + " \001(\010:\005false\022$\n\025java_generic_services\030\021 \001" + "(\010:\005false\022\"\n\023py_generic_services\030\022 \001(\010:\005" + "false\022\031\n\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_e" + "nable_arenas\030\037 \001(\010:\005false\022\031\n\021objc_class_" + "prefix\030$ \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022C" + "\n\024uninterpreted_option\030\347\007 \003(\0132$.google.p" + "rotobuf.UninterpretedOption\":\n\014OptimizeM" + "ode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RU" + "NTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\346\001\n\016MessageOpti" + "ons\022&\n\027message_set_wire_format\030\001 \001(\010:\005fa" + "lse\022.\n\037no_standard_descriptor_accessor\030\002" + " \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\021" + "\n\tmap_entry\030\007 \001(\010\022C\n\024uninterpreted_optio" + "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted" + "Option*\t\010\350\007\020\200\200\200\200\002\"\230\003\n\014FieldOptions\022:\n\005ct" + "ype\030\001 \001(\0162#.google.protobuf.FieldOptions" + ".CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\?\n\006jstype" + "\030\006 \001(\0162$.google.protobuf.FieldOptions.JS" + "Type:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005false\022\031\n\n" + "deprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001(\010:\005f" + "alse\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go" + "ogle.protobuf.UninterpretedOption\"/\n\005CTy" + "pe\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE" + "\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS_STRING" + "\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002\"^\n\014OneofOpt" + "ions\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go" + "ogle.protobuf.UninterpretedOption*\t\010\350\007\020\200" + "\200\200\200\002\"\215\001\n\013EnumOptions\022\023\n\013allow_alias\030\002 \001(" + "\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022C\n\024uninterp" + "reted_option\030\347\007 \003(\0132$.google.protobuf.Un" + "interpretedOption*\t\010\350\007\020\200\200\200\200\002\"}\n\020EnumValu" + "eOptions\022\031\n\ndeprecated\030\001 \001(\010:\005false\022C\n\024u" + "ninterpreted_option\030\347\007 \003(\0132$.google.prot" + "obuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016S" + "erviceOptions\022\031\n\ndeprecated\030! \001(\010:\005false" + "\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.google" + ".protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002" + "\"z\n\rMethodOptions\022\031\n\ndeprecated\030! \001(\010:\005f" "alse\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go" "ogle.protobuf.UninterpretedOption*\t\010\350\007\020\200" - "\200\200\200\002\"}\n\020EnumValueOptions\022\031\n\ndeprecated\030\001" - " \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003" - "(\0132$.google.protobuf.UninterpretedOption" - "*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndepreca" - "ted\030! \001(\010:\005false\022C\n\024uninterpreted_option" - "\030\347\007 \003(\0132$.google.protobuf.UninterpretedO" - "ption*\t\010\350\007\020\200\200\200\200\002\"z\n\rMethodOptions\022\031\n\ndep" - "recated\030! \001(\010:\005false\022C\n\024uninterpreted_op" - "tion\030\347\007 \003(\0132$.google.protobuf.Uninterpre" - "tedOption*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023UninterpretedOp" - "tion\022;\n\004name\030\002 \003(\0132-.google.protobuf.Uni" - "nterpretedOption.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_va" - "lue\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017aggre" - "gate_value\030\010 \001(\t\0323\n\010NamePart\022\021\n\tname_par" - "t\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\325\001\n\016Source" - "CodeInfo\022:\n\010location\030\001 \003(\0132(.google.prot" - "obuf.SourceCodeInfo.Location\032\206\001\n\010Locatio" - "n\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n" - "\020leading_comments\030\003 \001(\t\022\031\n\021trailing_comm" - "ents\030\004 \001(\t\022!\n\031leading_detached_comments\030" - "\006 \003(\t\"\247\001\n\021GeneratedCodeInfo\022A\n\nannotatio" - "n\030\001 \003(\0132-.google.protobuf.GeneratedCodeI" - "nfo.Annotation\032O\n\nAnnotation\022\020\n\004path\030\001 \003" - "(\005B\002\020\001\022\023\n\013source_file\030\002 \001(\t\022\r\n\005begin\030\003 \001" - "(\005\022\013\n\003end\030\004 \001(\005BX\n\023com.google.protobufB\020" - "DescriptorProtosH\001Z\ndescriptor\242\002\003GPB\252\002\032G" - "oogle.Protobuf.Reflection", 5145); + "\200\200\200\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003" + "(\0132-.google.protobuf.UninterpretedOption" + ".NamePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022p" + "ositive_int_value\030\004 \001(\004\022\032\n\022negative_int_" + "value\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014str" + "ing_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t" + "\0323\n\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_ex" + "tension\030\002 \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010loca" + "tion\030\001 \003(\0132(.google.protobuf.SourceCodeI" + "nfo.Location\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B" + "\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leading_comment" + "s\030\003 \001(\t\022\031\n\021trailing_comments\030\004 \001(\t\022!\n\031le" + "ading_detached_comments\030\006 \003(\t\"\247\001\n\021Genera" + "tedCodeInfo\022A\n\nannotation\030\001 \003(\0132-.google" + ".protobuf.GeneratedCodeInfo.Annotation\032O" + "\n\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source" + "_file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B" + "X\n\023com.google.protobufB\020DescriptorProtos" + "H\001Z\ndescriptor\242\002\003GPB\252\002\032Google.Protobuf.R" + "eflection", 5289); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/descriptor.proto", &protobuf_RegisterTypes); FileDescriptorSet::default_instance_ = new FileDescriptorSet(); @@ -826,6 +853,7 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { FileOptions::default_instance_ = new FileOptions(); MessageOptions::default_instance_ = new MessageOptions(); FieldOptions::default_instance_ = new FieldOptions(); + OneofOptions::default_instance_ = new OneofOptions(); EnumOptions::default_instance_ = new EnumOptions(); EnumValueOptions::default_instance_ = new EnumValueOptions(); ServiceOptions::default_instance_ = new ServiceOptions(); @@ -850,6 +878,7 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { FileOptions::default_instance_->InitAsDefaultInstance(); MessageOptions::default_instance_->InitAsDefaultInstance(); FieldOptions::default_instance_->InitAsDefaultInstance(); + OneofOptions::default_instance_->InitAsDefaultInstance(); EnumOptions::default_instance_->InitAsDefaultInstance(); EnumValueOptions::default_instance_->InitAsDefaultInstance(); ServiceOptions::default_instance_->InitAsDefaultInstance(); @@ -1016,14 +1045,14 @@ void FileDescriptorSet::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorSet) } -::google::protobuf::uint8* FileDescriptorSet::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* FileDescriptorSet::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorSet) // repeated .google.protobuf.FileDescriptorProto file = 1; for (unsigned int i = 0, n = this->file_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, this->file(i), target); + InternalWriteMessageNoVirtualToArray( + 1, this->file(i), false, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -1604,8 +1633,8 @@ void FileDescriptorProto::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorProto) } -::google::protobuf::uint8* FileDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* FileDescriptorProto::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorProto) // optional string name = 1; if (has_name()) { @@ -1642,43 +1671,43 @@ void FileDescriptorProto::SerializeWithCachedSizes( // repeated .google.protobuf.DescriptorProto message_type = 4; for (unsigned int i = 0, n = this->message_type_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 4, this->message_type(i), target); + InternalWriteMessageNoVirtualToArray( + 4, this->message_type(i), false, target); } // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; for (unsigned int i = 0, n = this->enum_type_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, this->enum_type(i), target); + InternalWriteMessageNoVirtualToArray( + 5, this->enum_type(i), false, target); } // repeated .google.protobuf.ServiceDescriptorProto service = 6; for (unsigned int i = 0, n = this->service_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 6, this->service(i), target); + InternalWriteMessageNoVirtualToArray( + 6, this->service(i), false, target); } // repeated .google.protobuf.FieldDescriptorProto extension = 7; for (unsigned int i = 0, n = this->extension_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 7, this->extension(i), target); + InternalWriteMessageNoVirtualToArray( + 7, this->extension(i), false, target); } // optional .google.protobuf.FileOptions options = 8; if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 8, *this->options_, target); + InternalWriteMessageNoVirtualToArray( + 8, *this->options_, false, target); } // optional .google.protobuf.SourceCodeInfo source_code_info = 9; if (has_source_code_info()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 9, *this->source_code_info_, target); + InternalWriteMessageNoVirtualToArray( + 9, *this->source_code_info_, false, target); } // repeated int32 public_dependency = 10; @@ -2599,8 +2628,8 @@ void DescriptorProto_ExtensionRange::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto.ExtensionRange) } -::google::protobuf::uint8* DescriptorProto_ExtensionRange::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* DescriptorProto_ExtensionRange::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ExtensionRange) // optional int32 start = 1; if (has_start()) { @@ -2898,8 +2927,8 @@ void DescriptorProto_ReservedRange::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto.ReservedRange) } -::google::protobuf::uint8* DescriptorProto_ReservedRange::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* DescriptorProto_ReservedRange::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ReservedRange) // optional int32 start = 1; if (has_start()) { @@ -3395,8 +3424,8 @@ void DescriptorProto::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto) } -::google::protobuf::uint8* DescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* DescriptorProto::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto) // optional string name = 1; if (has_name()) { @@ -3412,57 +3441,57 @@ void DescriptorProto::SerializeWithCachedSizes( // repeated .google.protobuf.FieldDescriptorProto field = 2; for (unsigned int i = 0, n = this->field_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, this->field(i), target); + InternalWriteMessageNoVirtualToArray( + 2, this->field(i), false, target); } // repeated .google.protobuf.DescriptorProto nested_type = 3; for (unsigned int i = 0, n = this->nested_type_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 3, this->nested_type(i), target); + InternalWriteMessageNoVirtualToArray( + 3, this->nested_type(i), false, target); } // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; for (unsigned int i = 0, n = this->enum_type_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 4, this->enum_type(i), target); + InternalWriteMessageNoVirtualToArray( + 4, this->enum_type(i), false, target); } // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; for (unsigned int i = 0, n = this->extension_range_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, this->extension_range(i), target); + InternalWriteMessageNoVirtualToArray( + 5, this->extension_range(i), false, target); } // repeated .google.protobuf.FieldDescriptorProto extension = 6; for (unsigned int i = 0, n = this->extension_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 6, this->extension(i), target); + InternalWriteMessageNoVirtualToArray( + 6, this->extension(i), false, target); } // optional .google.protobuf.MessageOptions options = 7; if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 7, *this->options_, target); + InternalWriteMessageNoVirtualToArray( + 7, *this->options_, false, target); } // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; for (unsigned int i = 0, n = this->oneof_decl_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 8, this->oneof_decl(i), target); + InternalWriteMessageNoVirtualToArray( + 8, this->oneof_decl(i), false, target); } // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; for (unsigned int i = 0, n = this->reserved_range_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 9, this->reserved_range(i), target); + InternalWriteMessageNoVirtualToArray( + 9, this->reserved_range(i), false, target); } // repeated string reserved_name = 10; @@ -3637,6 +3666,7 @@ bool DescriptorProto::IsInitialized() const { if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false; if (!::google::protobuf::internal::AllAreInitialized(this->nested_type())) return false; if (!::google::protobuf::internal::AllAreInitialized(this->enum_type())) return false; + if (!::google::protobuf::internal::AllAreInitialized(this->oneof_decl())) return false; if (has_options()) { if (!this->options_->IsInitialized()) return false; } @@ -4630,8 +4660,8 @@ void FieldDescriptorProto::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.FieldDescriptorProto) } -::google::protobuf::uint8* FieldDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* FieldDescriptorProto::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldDescriptorProto) // optional string name = 1; if (has_name()) { @@ -4697,8 +4727,8 @@ void FieldDescriptorProto::SerializeWithCachedSizes( // optional .google.protobuf.FieldOptions options = 8; if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 8, *this->options_, target); + InternalWriteMessageNoVirtualToArray( + 8, *this->options_, false, target); } // optional int32 oneof_index = 9; @@ -5345,6 +5375,7 @@ void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOption #if !defined(_MSC_VER) || _MSC_VER >= 1900 const int OneofDescriptorProto::kNameFieldNumber; +const int OneofDescriptorProto::kOptionsFieldNumber; #endif // !defined(_MSC_VER) || _MSC_VER >= 1900 OneofDescriptorProto::OneofDescriptorProto() @@ -5354,6 +5385,7 @@ OneofDescriptorProto::OneofDescriptorProto() } void OneofDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::OneofOptions*>(&::google::protobuf::OneofOptions::default_instance()); } OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto& from) @@ -5368,6 +5400,7 @@ void OneofDescriptorProto::SharedCtor() { ::google::protobuf::internal::GetEmptyString(); _cached_size_ = 0; name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + options_ = NULL; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -5379,6 +5412,7 @@ OneofDescriptorProto::~OneofDescriptorProto() { void OneofDescriptorProto::SharedDtor() { name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); if (this != default_instance_) { + delete options_; } } @@ -5409,8 +5443,13 @@ OneofDescriptorProto* OneofDescriptorProto::New(::google::protobuf::Arena* arena void OneofDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.OneofDescriptorProto) - if (has_name()) { - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (_has_bits_[0 / 32] & 3u) { + if (has_name()) { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + if (has_options()) { + if (options_ != NULL) options_->::google::protobuf::OneofOptions::Clear(); + } } ::memset(_has_bits_, 0, sizeof(_has_bits_)); if (_internal_metadata_.have_unknown_fields()) { @@ -5440,6 +5479,19 @@ bool OneofDescriptorProto::MergePartialFromCodedStream( } else { goto handle_unusual; } + if (input->ExpectTag(18)) goto parse_options; + break; + } + + // optional .google.protobuf.OneofOptions options = 2; + case 2: { + if (tag == 18) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { + goto handle_unusual; + } if (input->ExpectAtEnd()) goto success; break; } @@ -5479,6 +5531,12 @@ void OneofDescriptorProto::SerializeWithCachedSizes( 1, this->name(), output); } + // optional .google.protobuf.OneofOptions options = 2; + if (has_options()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, *this->options_, output); + } + if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( unknown_fields(), output); @@ -5486,8 +5544,8 @@ void OneofDescriptorProto::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.OneofDescriptorProto) } -::google::protobuf::uint8* OneofDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* OneofDescriptorProto::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofDescriptorProto) // optional string name = 1; if (has_name()) { @@ -5500,6 +5558,13 @@ void OneofDescriptorProto::SerializeWithCachedSizes( 1, this->name(), target); } + // optional .google.protobuf.OneofOptions options = 2; + if (has_options()) { + target = ::google::protobuf::internal::WireFormatLite:: + InternalWriteMessageNoVirtualToArray( + 2, *this->options_, false, target); + } + if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( unknown_fields(), target); @@ -5512,13 +5577,22 @@ int OneofDescriptorProto::ByteSize() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.OneofDescriptorProto) int total_size = 0; - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } + if (_has_bits_[0 / 32] & 3u) { + // optional string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional .google.protobuf.OneofOptions options = 2; + if (has_options()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *this->options_); + } + } if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( @@ -5553,6 +5627,9 @@ void OneofDescriptorProto::MergeFrom(const OneofDescriptorProto& from) { set_has_name(); name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); } + if (from.has_options()) { + mutable_options()->::google::protobuf::OneofOptions::MergeFrom(from.options()); + } } if (from._internal_metadata_.have_unknown_fields()) { mutable_unknown_fields()->MergeFrom(from.unknown_fields()); @@ -5575,6 +5652,9 @@ void OneofDescriptorProto::CopyFrom(const OneofDescriptorProto& from) { bool OneofDescriptorProto::IsInitialized() const { + if (has_options()) { + if (!this->options_->IsInitialized()) return false; + } return true; } @@ -5584,6 +5664,7 @@ void OneofDescriptorProto::Swap(OneofDescriptorProto* other) { } void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) { name_.Swap(&other->name_); + std::swap(options_, other->options_); std::swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); std::swap(_cached_size_, other->_cached_size_); @@ -5654,6 +5735,50 @@ void OneofDescriptorProto::clear_name() { // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name) } +// optional .google.protobuf.OneofOptions options = 2; +bool OneofDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void OneofDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000002u; +} +void OneofDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000002u; +} +void OneofDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::OneofOptions::Clear(); + clear_has_options(); +} +const ::google::protobuf::OneofOptions& OneofDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options) + return options_ != NULL ? *options_ : *default_instance_->options_; +} +::google::protobuf::OneofOptions* OneofDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) { + options_ = new ::google::protobuf::OneofOptions; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.options) + return options_; +} +::google::protobuf::OneofOptions* OneofDescriptorProto::release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.options) + clear_has_options(); + ::google::protobuf::OneofOptions* temp = options_; + options_ = NULL; + return temp; +} +void OneofDescriptorProto::set_allocated_options(::google::protobuf::OneofOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.options) +} + #endif // PROTOBUF_INLINE_NOT_IN_HEADERS // =================================================================== @@ -5854,8 +5979,8 @@ void EnumDescriptorProto::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.EnumDescriptorProto) } -::google::protobuf::uint8* EnumDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* EnumDescriptorProto::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto) // optional string name = 1; if (has_name()) { @@ -5871,15 +5996,15 @@ void EnumDescriptorProto::SerializeWithCachedSizes( // repeated .google.protobuf.EnumValueDescriptorProto value = 2; for (unsigned int i = 0, n = this->value_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, this->value(i), target); + InternalWriteMessageNoVirtualToArray( + 2, this->value(i), false, target); } // optional .google.protobuf.EnumOptions options = 3; if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 3, *this->options_, target); + InternalWriteMessageNoVirtualToArray( + 3, *this->options_, false, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -6335,8 +6460,8 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueDescriptorProto) } -::google::protobuf::uint8* EnumValueDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* EnumValueDescriptorProto::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueDescriptorProto) // optional string name = 1; if (has_name()) { @@ -6357,8 +6482,8 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( // optional .google.protobuf.EnumValueOptions options = 3; if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 3, *this->options_, target); + InternalWriteMessageNoVirtualToArray( + 3, *this->options_, false, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -6810,8 +6935,8 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.ServiceDescriptorProto) } -::google::protobuf::uint8* ServiceDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ServiceDescriptorProto::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceDescriptorProto) // optional string name = 1; if (has_name()) { @@ -6827,15 +6952,15 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( // repeated .google.protobuf.MethodDescriptorProto method = 2; for (unsigned int i = 0, n = this->method_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, this->method(i), target); + InternalWriteMessageNoVirtualToArray( + 2, this->method(i), false, target); } // optional .google.protobuf.ServiceOptions options = 3; if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 3, *this->options_, target); + InternalWriteMessageNoVirtualToArray( + 3, *this->options_, false, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -7399,8 +7524,8 @@ void MethodDescriptorProto::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.MethodDescriptorProto) } -::google::protobuf::uint8* MethodDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* MethodDescriptorProto::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodDescriptorProto) // optional string name = 1; if (has_name()) { @@ -7438,8 +7563,8 @@ void MethodDescriptorProto::SerializeWithCachedSizes( // optional .google.protobuf.MethodOptions options = 4; if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 4, *this->options_, target); + InternalWriteMessageNoVirtualToArray( + 4, *this->options_, false, target); } // optional bool client_streaming = 5 [default = false]; @@ -8432,8 +8557,8 @@ void FileOptions::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.FileOptions) } -::google::protobuf::uint8* FileOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* FileOptions::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileOptions) // optional string java_package = 1; if (has_java_package()) { @@ -8539,13 +8664,13 @@ void FileOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); + InternalWriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), false, target); } // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); + target = _extensions_.InternalSerializeWithCachedSizesToArray( + 1000, 536870912, false, target); if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( @@ -9573,8 +9698,8 @@ void MessageOptions::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.MessageOptions) } -::google::protobuf::uint8* MessageOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* MessageOptions::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MessageOptions) // optional bool message_set_wire_format = 1 [default = false]; if (has_message_set_wire_format()) { @@ -9599,13 +9724,13 @@ void MessageOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); + InternalWriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), false, target); } // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); + target = _extensions_.InternalSerializeWithCachedSizesToArray( + 1000, 536870912, false, target); if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( @@ -10237,8 +10362,8 @@ void FieldOptions::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.FieldOptions) } -::google::protobuf::uint8* FieldOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* FieldOptions::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldOptions) // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; if (has_ctype()) { @@ -10275,13 +10400,13 @@ void FieldOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); + InternalWriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), false, target); } // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); + target = _extensions_.InternalSerializeWithCachedSizesToArray( + 1000, 536870912, false, target); if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( @@ -10625,6 +10750,300 @@ FieldOptions::uninterpreted_option() const { // =================================================================== +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int OneofOptions::kUninterpretedOptionFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +OneofOptions::OneofOptions() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.OneofOptions) +} + +void OneofOptions::InitAsDefaultInstance() { +} + +OneofOptions::OneofOptions(const OneofOptions& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofOptions) +} + +void OneofOptions::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +OneofOptions::~OneofOptions() { + // @@protoc_insertion_point(destructor:google.protobuf.OneofOptions) + SharedDtor(); +} + +void OneofOptions::SharedDtor() { + if (this != default_instance_) { + } +} + +void OneofOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* OneofOptions::descriptor() { + protobuf_AssignDescriptorsOnce(); + return OneofOptions_descriptor_; +} + +const OneofOptions& OneofOptions::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +OneofOptions* OneofOptions::default_instance_ = NULL; + +OneofOptions* OneofOptions::New(::google::protobuf::Arena* arena) const { + OneofOptions* n = new OneofOptions; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void OneofOptions::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofOptions) + _extensions_.Clear(); + uninterpreted_option_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool OneofOptions::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.OneofOptions) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: { + if (tag == 7994) { + DO_(input->IncrementRecursionDepth()); + parse_loop_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_uninterpreted_option())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(7994)) goto parse_loop_uninterpreted_option; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + if ((8000u <= tag)) { + DO_(_extensions_.ParseField(tag, input, default_instance_, + mutable_unknown_fields())); + continue; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.OneofOptions) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.OneofOptions) + return false; +#undef DO_ +} + +void OneofOptions::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.OneofOptions) + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 999, this->uninterpreted_option(i), output); + } + + // Extension range [1000, 536870912) + _extensions_.SerializeWithCachedSizes( + 1000, 536870912, output); + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:google.protobuf.OneofOptions) +} + +::google::protobuf::uint8* OneofOptions::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofOptions) + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + InternalWriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), false, target); + } + + // Extension range [1000, 536870912) + target = _extensions_.InternalSerializeWithCachedSizesToArray( + 1000, 536870912, false, target); + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofOptions) + return target; +} + +int OneofOptions::ByteSize() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.OneofOptions) + int total_size = 0; + + // 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::WireFormatLite::MessageSizeNoVirtual( + this->uninterpreted_option(i)); + } + + total_size += _extensions_.ByteSize(); + + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void OneofOptions::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.OneofOptions) + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const OneofOptions* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.OneofOptions) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.OneofOptions) + MergeFrom(*source); + } +} + +void OneofOptions::MergeFrom(const OneofOptions& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofOptions) + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + _extensions_.MergeFrom(from._extensions_); + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void OneofOptions::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.OneofOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void OneofOptions::CopyFrom(const OneofOptions& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.OneofOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool OneofOptions::IsInitialized() const { + + if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false; + + if (!_extensions_.IsInitialized()) return false; return true; +} + +void OneofOptions::Swap(OneofOptions* other) { + if (other == this) return; + InternalSwap(other); +} +void OneofOptions::InternalSwap(OneofOptions* other) { + uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); + _extensions_.Swap(&other->_extensions_); +} + +::google::protobuf::Metadata OneofOptions::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = OneofOptions_descriptor_; + metadata.reflection = OneofOptions_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// OneofOptions + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +int OneofOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +void OneofOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +const ::google::protobuf::UninterpretedOption& OneofOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_.Get(index); +} +::google::protobuf::UninterpretedOption* OneofOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +::google::protobuf::UninterpretedOption* OneofOptions::add_uninterpreted_option() { + // @@protoc_insertion_point(field_add:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_.Add(); +} +::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +OneofOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.OneofOptions.uninterpreted_option) + return &uninterpreted_option_; +} +const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +OneofOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_; +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + #if !defined(_MSC_VER) || _MSC_VER >= 1900 const int EnumOptions::kAllowAliasFieldNumber; const int EnumOptions::kDeprecatedFieldNumber; @@ -10834,8 +11253,8 @@ void EnumOptions::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.EnumOptions) } -::google::protobuf::uint8* EnumOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* EnumOptions::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumOptions) // optional bool allow_alias = 2; if (has_allow_alias()) { @@ -10850,13 +11269,13 @@ void EnumOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); + InternalWriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), false, target); } // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); + target = _extensions_.InternalSerializeWithCachedSizesToArray( + 1000, 536870912, false, target); if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( @@ -11231,8 +11650,8 @@ void EnumValueOptions::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueOptions) } -::google::protobuf::uint8* EnumValueOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* EnumValueOptions::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueOptions) // optional bool deprecated = 1 [default = false]; if (has_deprecated()) { @@ -11242,13 +11661,13 @@ void EnumValueOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); + InternalWriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), false, target); } // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); + target = _extensions_.InternalSerializeWithCachedSizesToArray( + 1000, 536870912, false, target); if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( @@ -11588,8 +12007,8 @@ void ServiceOptions::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.ServiceOptions) } -::google::protobuf::uint8* ServiceOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ServiceOptions::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceOptions) // optional bool deprecated = 33 [default = false]; if (has_deprecated()) { @@ -11599,13 +12018,13 @@ void ServiceOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); + InternalWriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), false, target); } // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); + target = _extensions_.InternalSerializeWithCachedSizesToArray( + 1000, 536870912, false, target); if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( @@ -11945,8 +12364,8 @@ void MethodOptions::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.MethodOptions) } -::google::protobuf::uint8* MethodOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* MethodOptions::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodOptions) // optional bool deprecated = 33 [default = false]; if (has_deprecated()) { @@ -11956,13 +12375,13 @@ void MethodOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); + InternalWriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), false, target); } // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); + target = _extensions_.InternalSerializeWithCachedSizesToArray( + 1000, 536870912, false, target); if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( @@ -12303,8 +12722,8 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption.NamePart) } -::google::protobuf::uint8* UninterpretedOption_NamePart::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* UninterpretedOption_NamePart::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption.NamePart) // required string name_part = 1; if (has_name_part()) { @@ -12765,14 +13184,14 @@ void UninterpretedOption::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption) } -::google::protobuf::uint8* UninterpretedOption::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* UninterpretedOption::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption) // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; for (unsigned int i = 0, n = this->name_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, this->name(i), target); + InternalWriteMessageNoVirtualToArray( + 2, this->name(i), false, target); } // optional string identifier_value = 3; @@ -13606,8 +14025,8 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo.Location) } -::google::protobuf::uint8* SourceCodeInfo_Location::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* SourceCodeInfo_Location::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo.Location) // repeated int32 path = 1 [packed = true]; if (this->path_size() > 0) { @@ -13964,14 +14383,14 @@ void SourceCodeInfo::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo) } -::google::protobuf::uint8* SourceCodeInfo::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* SourceCodeInfo::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo) // repeated .google.protobuf.SourceCodeInfo.Location location = 1; for (unsigned int i = 0, n = this->location_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, this->location(i), target); + InternalWriteMessageNoVirtualToArray( + 1, this->location(i), false, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -14571,8 +14990,8 @@ void GeneratedCodeInfo_Annotation::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.GeneratedCodeInfo.Annotation) } -::google::protobuf::uint8* GeneratedCodeInfo_Annotation::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* GeneratedCodeInfo_Annotation::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo.Annotation) // repeated int32 path = 1 [packed = true]; if (this->path_size() > 0) { @@ -14886,14 +15305,14 @@ void GeneratedCodeInfo::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.GeneratedCodeInfo) } -::google::protobuf::uint8* GeneratedCodeInfo::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* GeneratedCodeInfo::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo) // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; for (unsigned int i = 0, n = this->annotation_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, this->annotation(i), target); + InternalWriteMessageNoVirtualToArray( + 1, this->annotation(i), false, target); } if (_internal_metadata_.have_unknown_fields()) { diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 92a0a3a7..5a9e12bc 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -56,6 +56,7 @@ class MessageOptions; class MethodDescriptorProto; class MethodOptions; class OneofDescriptorProto; +class OneofOptions; class ServiceDescriptorProto; class ServiceOptions; class SourceCodeInfo; @@ -180,7 +181,7 @@ inline bool FieldOptions_JSType_Parse( } // =================================================================== -class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorSet) */ { public: FileDescriptorSet(); virtual ~FileDescriptorSet(); @@ -222,7 +223,11 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -272,7 +277,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorProto) */ { public: FileDescriptorProto(); virtual ~FileDescriptorProto(); @@ -314,7 +319,11 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -515,7 +524,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ExtensionRange) */ { public: DescriptorProto_ExtensionRange(); virtual ~DescriptorProto_ExtensionRange(); @@ -557,7 +566,11 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -614,7 +627,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ReservedRange) */ { public: DescriptorProto_ReservedRange(); virtual ~DescriptorProto_ReservedRange(); @@ -656,7 +669,11 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protob ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -713,7 +730,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protob }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto) */ { public: DescriptorProto(); virtual ~DescriptorProto(); @@ -755,7 +772,11 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -930,7 +951,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldDescriptorProto) */ { public: FieldDescriptorProto(); virtual ~FieldDescriptorProto(); @@ -972,7 +993,11 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -1222,7 +1247,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofDescriptorProto) */ { public: OneofDescriptorProto(); virtual ~OneofDescriptorProto(); @@ -1264,7 +1289,11 @@ class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Messa ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -1298,15 +1327,27 @@ class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Messa ::std::string* release_name(); void set_allocated_name(::std::string* name); + // optional .google.protobuf.OneofOptions options = 2; + bool has_options() const; + void clear_options(); + static const int kOptionsFieldNumber = 2; + const ::google::protobuf::OneofOptions& options() const; + ::google::protobuf::OneofOptions* mutable_options(); + ::google::protobuf::OneofOptions* release_options(); + void set_allocated_options(::google::protobuf::OneofOptions* options); + // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto) private: inline void set_has_name(); inline void clear_has_name(); + inline void set_has_options(); + inline void clear_has_options(); ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; ::google::protobuf::uint32 _has_bits_[1]; mutable int _cached_size_; ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::OneofOptions* options_; 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(); @@ -1316,7 +1357,7 @@ class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Messa }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto) */ { public: EnumDescriptorProto(); virtual ~EnumDescriptorProto(); @@ -1358,7 +1399,11 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -1435,7 +1480,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueDescriptorProto) */ { public: EnumValueDescriptorProto(); virtual ~EnumValueDescriptorProto(); @@ -1477,7 +1522,11 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -1551,7 +1600,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceDescriptorProto) */ { public: ServiceDescriptorProto(); virtual ~ServiceDescriptorProto(); @@ -1593,7 +1642,11 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -1670,7 +1723,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodDescriptorProto) */ { public: MethodDescriptorProto(); virtual ~MethodDescriptorProto(); @@ -1712,7 +1765,11 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -1826,7 +1883,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileOptions) */ { public: FileOptions(); virtual ~FileOptions(); @@ -1868,7 +1925,11 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -2114,7 +2175,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MessageOptions) */ { public: MessageOptions(); virtual ~MessageOptions(); @@ -2156,7 +2217,11 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -2249,7 +2314,7 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions) */ { public: FieldOptions(); virtual ~FieldOptions(); @@ -2291,7 +2356,11 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -2460,7 +2529,106 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT OneofOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofOptions) */ { + public: + OneofOptions(); + virtual ~OneofOptions(); + + OneofOptions(const OneofOptions& from); + + inline OneofOptions& operator=(const OneofOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const OneofOptions& default_instance(); + + void Swap(OneofOptions* other); + + // implements Message ---------------------------------------------- + + inline OneofOptions* New() const { return New(NULL); } + + OneofOptions* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const OneofOptions& from); + void MergeFrom(const OneofOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(OneofOptions* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(OneofOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions) + private: + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::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(); + + void InitAsDefaultInstance(); + static OneofOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumOptions) */ { public: EnumOptions(); virtual ~EnumOptions(); @@ -2502,7 +2670,11 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -2575,7 +2747,7 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueOptions) */ { public: EnumValueOptions(); virtual ~EnumValueOptions(); @@ -2617,7 +2789,11 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -2680,7 +2856,7 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceOptions) */ { public: ServiceOptions(); virtual ~ServiceOptions(); @@ -2722,7 +2898,11 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -2785,7 +2965,7 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodOptions) */ { public: MethodOptions(); virtual ~MethodOptions(); @@ -2827,7 +3007,11 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -2890,7 +3074,7 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption.NamePart) */ { public: UninterpretedOption_NamePart(); virtual ~UninterpretedOption_NamePart(); @@ -2932,7 +3116,11 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -2997,7 +3185,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption) */ { public: UninterpretedOption(); virtual ~UninterpretedOption(); @@ -3039,7 +3227,11 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -3166,7 +3358,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo.Location) */ { public: SourceCodeInfo_Location(); virtual ~SourceCodeInfo_Location(); @@ -3208,7 +3400,11 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Me ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -3320,7 +3516,7 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Me }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo) */ { public: SourceCodeInfo(); virtual ~SourceCodeInfo(); @@ -3362,7 +3558,11 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -3414,7 +3614,7 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT GeneratedCodeInfo_Annotation : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT GeneratedCodeInfo_Annotation : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo.Annotation) */ { public: GeneratedCodeInfo_Annotation(); virtual ~GeneratedCodeInfo_Annotation(); @@ -3456,7 +3656,11 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo_Annotation : public ::google::protobu ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -3542,7 +3746,7 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo_Annotation : public ::google::protobu }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT GeneratedCodeInfo : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT GeneratedCodeInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo) */ { public: GeneratedCodeInfo(); virtual ~GeneratedCodeInfo(); @@ -3584,7 +3788,11 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo : public ::google::protobuf::Message ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -5106,6 +5314,50 @@ inline void OneofDescriptorProto::set_allocated_name(::std::string* name) { // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name) } +// optional .google.protobuf.OneofOptions options = 2; +inline bool OneofDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void OneofDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000002u; +} +inline void OneofDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000002u; +} +inline void OneofDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::OneofOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::OneofOptions& OneofDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options) + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::OneofOptions* OneofDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) { + options_ = new ::google::protobuf::OneofOptions; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.options) + return options_; +} +inline ::google::protobuf::OneofOptions* OneofDescriptorProto::release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.options) + clear_has_options(); + ::google::protobuf::OneofOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void OneofDescriptorProto::set_allocated_options(::google::protobuf::OneofOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.options) +} + // ------------------------------------------------------------------- // EnumDescriptorProto @@ -6587,6 +6839,40 @@ FieldOptions::uninterpreted_option() const { // ------------------------------------------------------------------- +// OneofOptions + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int OneofOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void OneofOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& OneofOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* OneofOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* OneofOptions::add_uninterpreted_option() { + // @@protoc_insertion_point(field_add:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +OneofOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.OneofOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +OneofOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + // EnumOptions // optional bool allow_alias = 2; @@ -7669,6 +7955,8 @@ GeneratedCodeInfo::annotation() const { // ------------------------------------------------------------------- +// ------------------------------------------------------------------- + // @@protoc_insertion_point(namespace_scope) diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index 08b15554..da853dbc 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -202,6 +202,7 @@ message FieldDescriptorProto { // Describes a oneof. message OneofDescriptorProto { optional string name = 1; + optional OneofOptions options = 2; } // Describes an enum type. @@ -538,6 +539,14 @@ message FieldOptions { extensions 1000 to max; } +message OneofOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + message EnumOptions { // Set this option to true to allow mapping different tag names to the same diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc index 1fc3816e..4f568f7d 100644 --- a/src/google/protobuf/descriptor_database_unittest.cc +++ b/src/google/protobuf/descriptor_database_unittest.cc @@ -48,7 +48,6 @@ #include #include -#include #include #include diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index f937b9ea..4183138f 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -55,7 +55,6 @@ #include #include #include -#include #include #include @@ -2705,6 +2704,7 @@ TEST(CustomOptions, OptionLocations) { protobuf_unittest::TestMessageWithCustomOptions::descriptor(); const FileDescriptor* file = message->file(); const FieldDescriptor* field = message->FindFieldByName("field1"); + const OneofDescriptor* oneof = message->FindOneofByName("AnOneof"); const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum"); // TODO(benjy): Support EnumValue options, once the compiler does. const ServiceDescriptor* service = @@ -2719,6 +2719,8 @@ TEST(CustomOptions, OptionLocations) { field->options().GetExtension(protobuf_unittest::field_opt1)); EXPECT_EQ(42, // Check that we get the default for an option we don't set. field->options().GetExtension(protobuf_unittest::field_opt2)); + EXPECT_EQ(-99, + oneof->options().GetExtension(protobuf_unittest::oneof_opt1)); EXPECT_EQ(-789, enm->options().GetExtension(protobuf_unittest::enum_opt1)); EXPECT_EQ(123, @@ -5027,7 +5029,7 @@ TEST_F(ValidationErrorTest, AggregateValueParseError) { BuildFileWithErrors( EmbedAggregateValue("aggregate_value: \"1+2\""), "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " - "value for \"foo\": Expected identifier.\n"); + "value for \"foo\": Expected identifier, got: 1\n"); } TEST_F(ValidationErrorTest, AggregateValueUnknownFields) { @@ -5834,7 +5836,7 @@ TEST_F(ValidationErrorTest, ValidateProto3JsonName) { " field { name:'name' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" " field { name:'Name' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" "}", - "foo.proto: Foo: OTHER: The JSON camcel-case name of field \"Name\" " + "foo.proto: Foo: OTHER: The JSON camel-case name of field \"Name\" " "conflicts with field \"name\". This is not allowed in proto3.\n"); // Underscores are ignored. BuildFileWithErrors( @@ -5845,7 +5847,7 @@ TEST_F(ValidationErrorTest, ValidateProto3JsonName) { " field { name:'ab' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" "}", - "foo.proto: Foo: OTHER: The JSON camcel-case name of field \"_a__b_\" " + "foo.proto: Foo: OTHER: The JSON camel-case name of field \"_a__b_\" " "conflicts with field \"ab\". This is not allowed in proto3.\n"); } diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index e3639346..b0c641bf 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc @@ -279,8 +279,8 @@ void Duration::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Duration) } -::google::protobuf::uint8* Duration::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Duration::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Duration) // optional int64 seconds = 1; if (this->seconds() != 0) { diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index 215a52c4..ad479639 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h @@ -41,7 +41,7 @@ class Duration; // =================================================================== -class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Duration) */ { public: Duration(); virtual ~Duration(); @@ -75,7 +75,11 @@ class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index 9e83bd29..5d914bf6 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -70,7 +70,6 @@ #endif #include -#include #include #include diff --git a/src/google/protobuf/dynamic_message_unittest.cc b/src/google/protobuf/dynamic_message_unittest.cc index 70e437d7..fe51d8cf 100644 --- a/src/google/protobuf/dynamic_message_unittest.cc +++ b/src/google/protobuf/dynamic_message_unittest.cc @@ -45,8 +45,6 @@ #include #endif -#include -#include #include #include #include @@ -55,6 +53,7 @@ #include #include +#include #include #include diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc index dcf84263..8b461201 100644 --- a/src/google/protobuf/empty.pb.cc +++ b/src/google/protobuf/empty.pb.cc @@ -221,8 +221,8 @@ void Empty::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Empty) } -::google::protobuf::uint8* Empty::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Empty::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Empty) // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Empty) return target; diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h index 868009fc..8e78733b 100644 --- a/src/google/protobuf/empty.pb.h +++ b/src/google/protobuf/empty.pb.h @@ -41,7 +41,7 @@ class Empty; // =================================================================== -class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Empty) */ { public: Empty(); virtual ~Empty(); @@ -80,7 +80,11 @@ class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index 9afb2361..7d20a0f8 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -177,7 +177,8 @@ void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type, // =================================================================== // Constructors and basic methods. -ExtensionSet::ExtensionSet(::google::protobuf::Arena* arena) : arena_(arena) { +ExtensionSet::ExtensionSet(::google::protobuf::Arena* arena) + : arena_(arena) { if (arena_ != NULL) { arena_->OwnDestructor(&extensions_); } @@ -188,7 +189,7 @@ ExtensionSet::ExtensionSet() : arena_(NULL) {} ExtensionSet::~ExtensionSet() { // Deletes all allocated extensions. if (arena_ == NULL) { - for (map::iterator iter = extensions_.begin(); + for (ExtensionMap::iterator iter = extensions_.begin(); iter != extensions_.end(); ++iter) { iter->second.Free(); } @@ -201,7 +202,7 @@ ExtensionSet::~ExtensionSet() { // vector* output) const bool ExtensionSet::Has(int number) const { - map::const_iterator iter = extensions_.find(number); + ExtensionMap::const_iterator iter = extensions_.find(number); if (iter == extensions_.end()) return false; GOOGLE_DCHECK(!iter->second.is_repeated); return !iter->second.is_cleared; @@ -209,7 +210,7 @@ bool ExtensionSet::Has(int number) const { int ExtensionSet::NumExtensions() const { int result = 0; - for (map::const_iterator iter = extensions_.begin(); + for (ExtensionMap::const_iterator iter = extensions_.begin(); iter != extensions_.end(); ++iter) { if (!iter->second.is_cleared) { ++result; @@ -219,13 +220,13 @@ int ExtensionSet::NumExtensions() const { } int ExtensionSet::ExtensionSize(int number) const { - map::const_iterator iter = extensions_.find(number); + ExtensionMap::const_iterator iter = extensions_.find(number); if (iter == extensions_.end()) return false; return iter->second.GetSize(); } FieldType ExtensionSet::ExtensionType(int number) const { - map::const_iterator iter = extensions_.find(number); + ExtensionMap::const_iterator iter = extensions_.find(number); if (iter == extensions_.end()) { GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). "; return 0; @@ -237,7 +238,7 @@ FieldType ExtensionSet::ExtensionType(int number) const { } void ExtensionSet::ClearExtension(int number) { - map::iterator iter = extensions_.find(number); + ExtensionMap::iterator iter = extensions_.find(number); if (iter == extensions_.end()) return; iter->second.Clear(); } @@ -265,7 +266,7 @@ enum Cardinality { \ LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \ LOWERCASE default_value) const { \ - map::const_iterator iter = extensions_.find(number); \ + ExtensionMap::const_iterator iter = extensions_.find(number); \ if (iter == extensions_.end() || iter->second.is_cleared) { \ return default_value; \ } else { \ @@ -290,7 +291,7 @@ void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \ } \ \ LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \ - map::const_iterator iter = extensions_.find(number); \ + ExtensionMap::const_iterator iter = extensions_.find(number); \ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \ GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \ return iter->second.repeated_##LOWERCASE##_value->Get(index); \ @@ -298,7 +299,7 @@ LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \ \ void ExtensionSet::SetRepeated##CAMELCASE( \ int number, int index, LOWERCASE value) { \ - map::iterator iter = extensions_.find(number); \ + ExtensionMap::iterator iter = extensions_.find(number); \ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \ GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \ iter->second.repeated_##LOWERCASE##_value->Set(index, value); \ @@ -334,7 +335,7 @@ PRIMITIVE_ACCESSORS( BOOL, bool, Bool) const void* ExtensionSet::GetRawRepeatedField(int number, const void* default_value) const { - map::const_iterator iter = extensions_.find(number); + ExtensionMap::const_iterator iter = extensions_.find(number); if (iter == extensions_.end()) { return default_value; } @@ -408,7 +409,7 @@ void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type, // Compatible version using old call signature. Does not create extensions when // the don't already exist; instead, just GOOGLE_CHECK-fails. void* ExtensionSet::MutableRawRepeatedField(int number) { - map::iterator iter = extensions_.find(number); + ExtensionMap::iterator iter = extensions_.find(number); GOOGLE_CHECK(iter == extensions_.end()) << "Extension not found."; // We assume that all the RepeatedField<>* pointers have the same // size and alignment within the anonymous union in Extension. @@ -420,7 +421,7 @@ void* ExtensionSet::MutableRawRepeatedField(int number) { // Enums int ExtensionSet::GetEnum(int number, int default_value) const { - map::const_iterator iter = extensions_.find(number); + ExtensionMap::const_iterator iter = extensions_.find(number); if (iter == extensions_.end() || iter->second.is_cleared) { // Not present. Return the default value. return default_value; @@ -445,14 +446,14 @@ void ExtensionSet::SetEnum(int number, FieldType type, int value, } int ExtensionSet::GetRepeatedEnum(int number, int index) const { - map::const_iterator iter = extensions_.find(number); + ExtensionMap::const_iterator iter = extensions_.find(number); GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM); return iter->second.repeated_enum_value->Get(index); } void ExtensionSet::SetRepeatedEnum(int number, int index, int value) { - map::iterator iter = extensions_.find(number); + ExtensionMap::iterator iter = extensions_.find(number); GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM); iter->second.repeated_enum_value->Set(index, value); @@ -481,7 +482,7 @@ void ExtensionSet::AddEnum(int number, FieldType type, const string& ExtensionSet::GetString(int number, const string& default_value) const { - map::const_iterator iter = extensions_.find(number); + ExtensionMap::const_iterator iter = extensions_.find(number); if (iter == extensions_.end() || iter->second.is_cleared) { // Not present. Return the default value. return default_value; @@ -507,14 +508,14 @@ string* ExtensionSet::MutableString(int number, FieldType type, } const string& ExtensionSet::GetRepeatedString(int number, int index) const { - map::const_iterator iter = extensions_.find(number); + ExtensionMap::const_iterator iter = extensions_.find(number); GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING); return iter->second.repeated_string_value->Get(index); } string* ExtensionSet::MutableRepeatedString(int number, int index) { - map::iterator iter = extensions_.find(number); + ExtensionMap::iterator iter = extensions_.find(number); GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING); return iter->second.repeated_string_value->Mutable(index); @@ -541,7 +542,7 @@ string* ExtensionSet::AddString(int number, FieldType type, const MessageLite& ExtensionSet::GetMessage( int number, const MessageLite& default_value) const { - map::const_iterator iter = extensions_.find(number); + ExtensionMap::const_iterator iter = extensions_.find(number); if (iter == extensions_.end()) { // Not present. Return the default value. return default_value; @@ -664,7 +665,7 @@ void ExtensionSet::UnsafeArenaSetAllocatedMessage( MessageLite* ExtensionSet::ReleaseMessage(int number, const MessageLite& prototype) { - map::iterator iter = extensions_.find(number); + ExtensionMap::iterator iter = extensions_.find(number); if (iter == extensions_.end()) { // Not present. Return NULL. return NULL; @@ -693,7 +694,7 @@ MessageLite* ExtensionSet::ReleaseMessage(int number, MessageLite* ExtensionSet::UnsafeArenaReleaseMessage( int number, const MessageLite& prototype) { - map::iterator iter = extensions_.find(number); + ExtensionMap::iterator iter = extensions_.find(number); if (iter == extensions_.end()) { // Not present. Return NULL. return NULL; @@ -720,14 +721,14 @@ MessageLite* ExtensionSet::UnsafeArenaReleaseMessage( const MessageLite& ExtensionSet::GetRepeatedMessage( int number, int index) const { - map::const_iterator iter = extensions_.find(number); + ExtensionMap::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); } MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) { - map::iterator iter = extensions_.find(number); + ExtensionMap::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); @@ -766,7 +767,7 @@ MessageLite* ExtensionSet::AddMessage(int number, FieldType type, #undef GOOGLE_DCHECK_TYPE void ExtensionSet::RemoveLast(int number) { - map::iterator iter = extensions_.find(number); + ExtensionMap::iterator iter = extensions_.find(number); GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; Extension* extension = &iter->second; @@ -807,7 +808,7 @@ void ExtensionSet::RemoveLast(int number) { } MessageLite* ExtensionSet::ReleaseLast(int number) { - map::iterator iter = extensions_.find(number); + ExtensionMap::iterator iter = extensions_.find(number); GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; Extension* extension = &iter->second; @@ -817,7 +818,7 @@ MessageLite* ExtensionSet::ReleaseLast(int number) { } void ExtensionSet::SwapElements(int number, int index1, int index2) { - map::iterator iter = extensions_.find(number); + ExtensionMap::iterator iter = extensions_.find(number); GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; Extension* extension = &iter->second; @@ -860,14 +861,14 @@ void ExtensionSet::SwapElements(int number, int index1, int index2) { // =================================================================== void ExtensionSet::Clear() { - for (map::iterator iter = extensions_.begin(); + for (ExtensionMap::iterator iter = extensions_.begin(); iter != extensions_.end(); ++iter) { iter->second.Clear(); } } void ExtensionSet::MergeFrom(const ExtensionSet& other) { - for (map::const_iterator iter = other.extensions_.begin(); + for (ExtensionMap::const_iterator iter = other.extensions_.begin(); iter != other.extensions_.end(); ++iter) { const Extension& other_extension = iter->second; InternalExtensionMergeFrom(iter->first, other_extension); @@ -1031,8 +1032,8 @@ void ExtensionSet::Swap(ExtensionSet* x) { void ExtensionSet::SwapExtension(ExtensionSet* other, int number) { if (this == other) return; - map::iterator this_iter = extensions_.find(number); - map::iterator other_iter = other->extensions_.find(number); + ExtensionMap::iterator this_iter = extensions_.find(number); + ExtensionMap::iterator other_iter = other->extensions_.find(number); if (this_iter == extensions_.end() && other_iter == other->extensions_.end()) { @@ -1052,7 +1053,7 @@ void ExtensionSet::SwapExtension(ExtensionSet* other, // implemented in ExtensionSet's MergeFrom. ExtensionSet temp; temp.InternalExtensionMergeFrom(number, other_iter->second); - map::iterator temp_iter = temp.extensions_.find(number); + ExtensionMap::iterator temp_iter = temp.extensions_.find(number); other_iter->second.Clear(); other->InternalExtensionMergeFrom(number, this_iter->second); this_iter->second.Clear(); @@ -1085,7 +1086,7 @@ void ExtensionSet::SwapExtension(ExtensionSet* other, bool ExtensionSet::IsInitialized() const { // Extensions are never required. However, we need to check that all // embedded messages are initialized. - for (map::const_iterator iter = extensions_.begin(); + for (ExtensionMap::const_iterator iter = extensions_.begin(); iter != extensions_.end(); ++iter) { const Extension& extension = iter->second; if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) { @@ -1345,7 +1346,7 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, void ExtensionSet::SerializeWithCachedSizes( int start_field_number, int end_field_number, io::CodedOutputStream* output) const { - map::const_iterator iter; + ExtensionMap::const_iterator iter; for (iter = extensions_.lower_bound(start_field_number); iter != extensions_.end() && iter->first < end_field_number; ++iter) { @@ -1356,7 +1357,7 @@ void ExtensionSet::SerializeWithCachedSizes( int ExtensionSet::ByteSize() const { int total_size = 0; - for (map::const_iterator iter = extensions_.begin(); + for (ExtensionMap::const_iterator iter = extensions_.begin(); iter != extensions_.end(); ++iter) { total_size += iter->second.ByteSize(iter->first); } @@ -1370,7 +1371,7 @@ int ExtensionSet::ByteSize() const { bool ExtensionSet::MaybeNewExtension(int number, const FieldDescriptor* descriptor, Extension** result) { - pair::iterator, bool> insert_result = + pair insert_result = extensions_.insert(std::make_pair(number, Extension())); *result = &insert_result.first->second; (*result)->descriptor = descriptor; diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index bca179be..a92c5043 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -273,6 +273,8 @@ class LIBPROTOBUF_EXPORT ExtensionSet { MessageLite* ReleaseMessage(const FieldDescriptor* descriptor, MessageFactory* factory); + MessageLite* UnsafeArenaReleaseMessage(const FieldDescriptor* descriptor, + MessageFactory* factory); #undef desc ::google::protobuf::Arena* GetArenaNoVirtual() const { return arena_; } @@ -403,13 +405,27 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // serialized extensions. // // Returns a pointer past the last written byte. - uint8* SerializeWithCachedSizesToArray(int start_field_number, - int end_field_number, - uint8* target) const; + uint8* InternalSerializeWithCachedSizesToArray(int start_field_number, + int end_field_number, + bool deterministic, + uint8* target) const; // Like above but serializes in MessageSet format. void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const; - uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const; + uint8* InternalSerializeMessageSetWithCachedSizesToArray(bool deterministic, + uint8* target) const; + + // For backward-compatibility, versions of two of the above methods that + // are never forced to serialize deterministically. + uint8* SerializeWithCachedSizesToArray(int start_field_number, + int end_field_number, + uint8* target) const { + return InternalSerializeWithCachedSizesToArray( + start_field_number, end_field_number, false, target); + } + uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const { + return InternalSerializeMessageSetWithCachedSizesToArray(false, target); + } // Returns the total serialized size of all the extensions. int ByteSize() const; @@ -456,6 +472,13 @@ class LIBPROTOBUF_EXPORT ExtensionSet { virtual void WriteMessage(int number, io::CodedOutputStream* output) const = 0; virtual uint8* WriteMessageToArray(int number, uint8* target) const = 0; + virtual uint8* InternalWriteMessageToArray(int number, bool, + uint8* target) const { + // TODO(gpike): make this pure virtual. This is a placeholder because we + // need to update third_party/upb, for example. + return WriteMessageToArray(number, target); + } + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension); }; @@ -522,14 +545,16 @@ class LIBPROTOBUF_EXPORT ExtensionSet { void SerializeFieldWithCachedSizes( int number, io::CodedOutputStream* output) const; - uint8* SerializeFieldWithCachedSizesToArray( + uint8* InternalSerializeFieldWithCachedSizesToArray( int number, + bool deterministic, uint8* target) const; void SerializeMessageSetItemWithCachedSizes( int number, io::CodedOutputStream* output) const; - uint8* SerializeMessageSetItemWithCachedSizesToArray( + uint8* InternalSerializeMessageSetItemWithCachedSizesToArray( int number, + bool deterministic, uint8* target) const; int ByteSize(int number) const; int MessageSetItemByteSize(int number) const; @@ -538,6 +563,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { void Free(); int SpaceUsedExcludingSelf() const; }; + typedef std::map ExtensionMap; // Merges existing Extension from other_extension @@ -608,7 +634,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // only contain a small number of extensions whereas hash_map is optimized // for 100 elements or more. Also, we want AppendToList() to order fields // by field number. - std::map extensions_; + ExtensionMap extensions_; ::google::protobuf::Arena* arena_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet); }; @@ -980,11 +1006,22 @@ class MessageTypeTraits { MutableType message, ExtensionSet* set) { set->SetAllocatedMessage(number, field_type, NULL, message); } + static inline void UnsafeArenaSetAllocated(int number, FieldType field_type, + MutableType message, + ExtensionSet* set) { + set->UnsafeArenaSetAllocatedMessage(number, field_type, NULL, message); + } static inline MutableType Release(int number, FieldType /* field_type */, ExtensionSet* set) { return static_cast(set->ReleaseMessage( number, Type::default_instance())); } + static inline MutableType UnsafeArenaRelease(int number, + FieldType /* field_type */, + ExtensionSet* set) { + return static_cast(set->UnsafeArenaReleaseMessage( + number, Type::default_instance())); + } }; // forward declaration @@ -1175,6 +1212,16 @@ class ExtensionIdentifier { _proto_TypeTraits::SetAllocated(id.number(), _field_type, \ value, &_extensions_); \ } \ + template \ + inline void UnsafeArenaSetAllocatedExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + typename _proto_TypeTraits::Singular::MutableType value) { \ + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, \ + value, &_extensions_); \ + } \ template \ @@ -1183,6 +1230,16 @@ class ExtensionIdentifier { CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ return _proto_TypeTraits::Release(id.number(), _field_type, \ &_extensions_); \ + } \ + template \ + inline typename _proto_TypeTraits::Singular::MutableType \ + UnsafeArenaReleaseExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, \ + &_extensions_); \ } \ \ /* Repeated accessors */ \ diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index 82e3e099..7177d786 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc @@ -95,7 +95,7 @@ void ExtensionSet::AppendToList( const Descriptor* containing_type, const DescriptorPool* pool, std::vector* output) const { - for (map::const_iterator iter = extensions_.begin(); + for (ExtensionMap::const_iterator iter = extensions_.begin(); iter != extensions_.end(); ++iter) { bool has = false; if (iter->second.is_repeated) { @@ -144,7 +144,7 @@ inline WireFormatLite::FieldType field_type(FieldType type) { const MessageLite& ExtensionSet::GetMessage(int number, const Descriptor* message_type, MessageFactory* factory) const { - map::const_iterator iter = extensions_.find(number); + ExtensionMap::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); @@ -187,7 +187,7 @@ MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor, MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor, MessageFactory* factory) { - map::iterator iter = extensions_.find(descriptor->number()); + ExtensionMap::iterator iter = extensions_.find(descriptor->number()); if (iter == extensions_.end()) { // Not present. Return NULL. return NULL; @@ -213,6 +213,29 @@ MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor, } } +MessageLite* ExtensionSet::UnsafeArenaReleaseMessage( + const FieldDescriptor* descriptor, MessageFactory* factory) { + ExtensionMap::iterator iter = extensions_.find(descriptor->number()); + if (iter == extensions_.end()) { + // Not present. Return NULL. + return NULL; + } else { + GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); + MessageLite* ret = NULL; + if (iter->second.is_lazy) { + ret = iter->second.lazymessage_value->UnsafeArenaReleaseMessage( + *factory->GetPrototype(descriptor->message_type())); + if (arena_ == NULL) { + delete iter->second.lazymessage_value; + } + } else { + ret = iter->second.message_value; + } + extensions_.erase(descriptor->number()); + return ret; + } +} + ExtensionSet::Extension* ExtensionSet::MaybeNewRepeatedExtension(const FieldDescriptor* descriptor) { Extension* extension; if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) { @@ -319,7 +342,7 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, int ExtensionSet::SpaceUsedExcludingSelf() const { int total_size = extensions_.size() * sizeof(map::value_type); - for (map::const_iterator iter = extensions_.begin(), + for (ExtensionMap::const_iterator iter = extensions_.begin(), end = extensions_.end(); iter != end; ++iter) { @@ -386,31 +409,31 @@ int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { // The Serialize*ToArray methods are only needed in the heavy library, as // the lite library only generates SerializeWithCachedSizes. -uint8* ExtensionSet::SerializeWithCachedSizesToArray( +uint8* ExtensionSet::InternalSerializeWithCachedSizesToArray( int start_field_number, int end_field_number, - uint8* target) const { - map::const_iterator iter; + bool deterministic, uint8* target) const { + ExtensionMap::const_iterator iter; for (iter = extensions_.lower_bound(start_field_number); iter != extensions_.end() && iter->first < end_field_number; ++iter) { - target = iter->second.SerializeFieldWithCachedSizesToArray(iter->first, - target); + target = iter->second.InternalSerializeFieldWithCachedSizesToArray( + iter->first, deterministic, target); } return target; } -uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray( - uint8* target) const { - map::const_iterator iter; +uint8* ExtensionSet::InternalSerializeMessageSetWithCachedSizesToArray( + bool deterministic, uint8* target) const { + ExtensionMap::const_iterator iter; for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) { - target = iter->second.SerializeMessageSetItemWithCachedSizesToArray( - iter->first, target); + target = iter->second.InternalSerializeMessageSetItemWithCachedSizesToArray( + iter->first, deterministic, target); } return target; } -uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray( - int number, uint8* target) const { +uint8* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray( + int number, bool deterministic, uint8* target) const { if (is_repeated) { if (is_packed) { if (cached_size == 0) return target; @@ -477,6 +500,16 @@ uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray( HANDLE_TYPE( STRING, String, string); HANDLE_TYPE( BYTES, Bytes, string); HANDLE_TYPE( ENUM, Enum, enum); +#undef HANDLE_TYPE +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case FieldDescriptor::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + target = WireFormatLite::InternalWrite##CAMELCASE##ToArray( \ + number, repeated_##LOWERCASE##_value->Get(i), \ + deterministic, target); \ + } \ + break + HANDLE_TYPE( GROUP, Group, message); HANDLE_TYPE( MESSAGE, Message, message); #undef HANDLE_TYPE @@ -510,10 +543,11 @@ uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray( #undef HANDLE_TYPE case FieldDescriptor::TYPE_MESSAGE: if (is_lazy) { - target = lazymessage_value->WriteMessageToArray(number, target); + target = lazymessage_value->InternalWriteMessageToArray( + number, deterministic, target); } else { - target = WireFormatLite::WriteMessageToArray( - number, *message_value, target); + target = WireFormatLite::InternalWriteMessageToArray( + number, *message_value, deterministic, target); } break; } @@ -521,13 +555,14 @@ uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray( return target; } -uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray( - int number, - uint8* target) const { +uint8* +ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray( + int number, bool deterministic, uint8* target) const { if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { // Not a valid MessageSet extension, but serialize it the normal way. GOOGLE_LOG(WARNING) << "Invalid message set extension."; - return SerializeFieldWithCachedSizesToArray(number, target); + return InternalSerializeFieldWithCachedSizesToArray(number, deterministic, + target); } if (is_cleared) return target; @@ -732,7 +767,7 @@ int ExtensionSet::Extension::MessageSetItemByteSize(int number) const { void ExtensionSet::SerializeMessageSetWithCachedSizes( io::CodedOutputStream* output) const { - for (map::const_iterator iter = extensions_.begin(); + for (ExtensionMap::const_iterator iter = extensions_.begin(); iter != extensions_.end(); ++iter) { iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output); } @@ -741,7 +776,7 @@ void ExtensionSet::SerializeMessageSetWithCachedSizes( int ExtensionSet::MessageSetByteSize() const { int total_size = 0; - for (map::const_iterator iter = extensions_.begin(); + for (ExtensionMap::const_iterator iter = extensions_.begin(); iter != extensions_.end(); ++iter) { total_size += iter->second.MessageSetItemByteSize(iter->first); } diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc index f40fcbc2..688afedb 100644 --- a/src/google/protobuf/extension_set_unittest.cc +++ b/src/google/protobuf/extension_set_unittest.cc @@ -205,6 +205,74 @@ TEST(ExtensionSetTest, ReleaseExtension) { delete released_extension; } +TEST(ExtensionSetTest, ArenaUnsafeArenaSetAllocatedAndRelease) { + ::google::protobuf::Arena arena; + unittest::TestAllExtensions* message = + ::google::protobuf::Arena::CreateMessage(&arena); + unittest::ForeignMessage extension; + message->UnsafeArenaSetAllocatedExtension( + unittest::optional_foreign_message_extension, + &extension); + // No copy when set. + unittest::ForeignMessage* mutable_extension = + message->MutableExtension(unittest::optional_foreign_message_extension); + EXPECT_EQ(&extension, mutable_extension); + // No copy when unsafe released. + unittest::ForeignMessage* released_extension = + message->UnsafeArenaReleaseExtension( + unittest::optional_foreign_message_extension); + EXPECT_EQ(&extension, released_extension); + EXPECT_FALSE(message->HasExtension( + unittest::optional_foreign_message_extension)); + // Set the ownership back and let the destructors run. It should not take + // ownership, so this should not crash. + message->UnsafeArenaSetAllocatedExtension( + unittest::optional_foreign_message_extension, + &extension); +} + +TEST(ExtensionSetTest, UnsafeArenaSetAllocatedAndRelease) { + unittest::TestAllExtensions message; + unittest::ForeignMessage* extension = new unittest::ForeignMessage(); + message.UnsafeArenaSetAllocatedExtension( + unittest::optional_foreign_message_extension, + extension); + // No copy when set. + unittest::ForeignMessage* mutable_extension = + message.MutableExtension(unittest::optional_foreign_message_extension); + EXPECT_EQ(extension, mutable_extension); + // No copy when unsafe released. + unittest::ForeignMessage* released_extension = + message.UnsafeArenaReleaseExtension( + unittest::optional_foreign_message_extension); + EXPECT_EQ(extension, released_extension); + EXPECT_FALSE(message.HasExtension( + unittest::optional_foreign_message_extension)); + // Set the ownership back and let the destructors run. It should take + // ownership, so this should not leak. + message.UnsafeArenaSetAllocatedExtension( + unittest::optional_foreign_message_extension, + extension); +} + +TEST(ExtensionSetTest, ArenaUnsafeArenaReleaseOfHeapAlloc) { + ::google::protobuf::Arena arena; + unittest::TestAllExtensions* message = + ::google::protobuf::Arena::CreateMessage(&arena); + unittest::ForeignMessage* extension = new unittest::ForeignMessage; + message->SetAllocatedExtension( + unittest::optional_foreign_message_extension, + extension); + // The arena should maintain ownership of the heap allocated proto because we + // used UnsafeArenaReleaseExtension. The leak checker will ensure this. + unittest::ForeignMessage* released_extension = + message->UnsafeArenaReleaseExtension( + unittest::optional_foreign_message_extension); + EXPECT_EQ(extension, released_extension); + EXPECT_FALSE(message->HasExtension( + unittest::optional_foreign_message_extension)); +} + TEST(ExtensionSetTest, CopyFrom) { unittest::TestAllExtensions message1, message2; diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc index c49ebceb..d197b406 100644 --- a/src/google/protobuf/field_mask.pb.cc +++ b/src/google/protobuf/field_mask.pb.cc @@ -245,8 +245,8 @@ void FieldMask::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.FieldMask) } -::google::protobuf::uint8* FieldMask::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* FieldMask::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldMask) // repeated string paths = 1; for (int i = 0; i < this->paths_size(); i++) { diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index f5e0b655..7a19c4aa 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h @@ -41,7 +41,7 @@ class FieldMask; // =================================================================== -class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldMask) */ { public: FieldMask(); virtual ~FieldMask(); @@ -75,7 +75,11 @@ class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/src/google/protobuf/field_mask.proto b/src/google/protobuf/field_mask.proto index 6af6dbe8..c51de09a 100644 --- a/src/google/protobuf/field_mask.proto +++ b/src/google/protobuf/field_mask.proto @@ -107,6 +107,58 @@ option java_generate_equals_and_hash = true; // describe the updated values, the API ignores the values of all // fields not covered by the mask. // +// If a repeated field is specified for an update operation, the existing +// repeated values in the target resource will be overwritten by the new values. +// Note that a repeated field is only allowed in the last position of a field +// mask. +// +// If a sub-message is specified in the last position of the field mask for an +// update operation, then the existing sub-message in the target resource is +// overwritten. Given the target message: +// +// f { +// b { +// d : 1 +// x : 2 +// } +// c : 1 +// } +// +// And an update message: +// +// f { +// b { +// d : 10 +// } +// } +// +// then if the field mask is: +// +// paths: "f.b" +// +// then the result will be: +// +// f { +// b { +// d : 10 +// } +// c : 1 +// } +// +// However, if the update mask was: +// +// paths: "f.b.d" +// +// then the result would be: +// +// f { +// b { +// d : 10 +// x : 2 +// } +// c : 1 +// } +// // In order to reset a field's value to the default, the field must // be in the mask and set to the default value in the provided resource. // Hence, in order to reset all fields of a resource, provide a default diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 2313181c..347bac5a 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -1579,7 +1579,8 @@ Message* GeneratedMessageReflection::UnsafeArenaReleaseMessage( if (field->is_extension()) { return static_cast( - MutableExtensionSet(message)->ReleaseMessage(field, factory)); + MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field, + factory)); } else { ClearBit(message, field); if (field->containing_oneof()) { diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc index 85ebdef1..6276b667 100644 --- a/src/google/protobuf/generated_message_reflection_unittest.cc +++ b/src/google/protobuf/generated_message_reflection_unittest.cc @@ -795,6 +795,73 @@ TEST(GeneratedMessageReflectionTest, ReleaseOneofMessageTest) { EXPECT_TRUE(released == NULL); } +TEST(GeneratedMessageReflectionTest, ArenaReleaseMessageTest) { + ::google::protobuf::Arena arena; + unittest::TestAllTypes* message = + ::google::protobuf::Arena::CreateMessage(&arena); + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllTypes::descriptor()); + + // When nothing is set, we expect all released messages to be NULL. + reflection_tester.ExpectMessagesReleasedViaReflection( + message, TestUtil::ReflectionTester::IS_NULL); + + // After fields are set we should get non-NULL releases. + reflection_tester.SetAllFieldsViaReflection(message); + reflection_tester.ExpectMessagesReleasedViaReflection( + message, TestUtil::ReflectionTester::NOT_NULL); + + // After Clear() we may or may not get a message from ReleaseMessage(). + // This is implementation specific. + reflection_tester.SetAllFieldsViaReflection(message); + message->Clear(); + reflection_tester.ExpectMessagesReleasedViaReflection( + message, TestUtil::ReflectionTester::CAN_BE_NULL); +} + +TEST(GeneratedMessageReflectionTest, ArenaReleaseExtensionMessageTest) { + ::google::protobuf::Arena arena; + unittest::TestAllExtensions* message = + ::google::protobuf::Arena::CreateMessage(&arena); + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllExtensions::descriptor()); + + // When nothing is set, we expect all released messages to be NULL. + reflection_tester.ExpectMessagesReleasedViaReflection( + message, TestUtil::ReflectionTester::IS_NULL); + + // After fields are set we should get non-NULL releases. + reflection_tester.SetAllFieldsViaReflection(message); + reflection_tester.ExpectMessagesReleasedViaReflection( + message, TestUtil::ReflectionTester::NOT_NULL); + + // After Clear() we may or may not get a message from ReleaseMessage(). + // This is implementation specific. + reflection_tester.SetAllFieldsViaReflection(message); + message->Clear(); + reflection_tester.ExpectMessagesReleasedViaReflection( + message, TestUtil::ReflectionTester::CAN_BE_NULL); +} + +TEST(GeneratedMessageReflectionTest, ArenaReleaseOneofMessageTest) { + ::google::protobuf::Arena arena; + unittest::TestOneof2* message = + ::google::protobuf::Arena::CreateMessage(&arena); + TestUtil::ReflectionTester::SetOneofViaReflection(message); + + const Descriptor* descriptor = unittest::TestOneof2::descriptor(); + const Reflection* reflection = message->GetReflection(); + Message* released = reflection->ReleaseMessage( + message, descriptor->FindFieldByName("foo_lazy_message")); + + EXPECT_TRUE(released != NULL); + delete released; + + released = reflection->ReleaseMessage( + message, descriptor->FindFieldByName("foo_lazy_message")); + EXPECT_TRUE(released == NULL); +} + #ifdef PROTOBUF_HAS_DEATH_TEST TEST(GeneratedMessageReflectionTest, UsageErrors) { diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index d8354c1f..148eee0e 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc @@ -376,6 +376,49 @@ inline ::std::pair ReadVarint32FromArray( return std::make_pair(true, ptr); } +GOOGLE_ATTRIBUTE_ALWAYS_INLINE::std::pair ReadVarint64FromArray( + const uint8* buffer, uint64* value); +inline ::std::pair ReadVarint64FromArray( + const uint8* buffer, uint64* value) { + const uint8* ptr = buffer; + uint32 b; + + // Splitting into 32-bit pieces gives better performance on 32-bit + // processors. + uint32 part0 = 0, part1 = 0, part2 = 0; + + b = *(ptr++); part0 = b ; if (!(b & 0x80)) goto done; + part0 -= 0x80; + b = *(ptr++); part0 += b << 7; if (!(b & 0x80)) goto done; + part0 -= 0x80 << 7; + b = *(ptr++); part0 += b << 14; if (!(b & 0x80)) goto done; + part0 -= 0x80 << 14; + b = *(ptr++); part0 += b << 21; if (!(b & 0x80)) goto done; + part0 -= 0x80 << 21; + b = *(ptr++); part1 = b ; if (!(b & 0x80)) goto done; + part1 -= 0x80; + b = *(ptr++); part1 += b << 7; if (!(b & 0x80)) goto done; + part1 -= 0x80 << 7; + b = *(ptr++); part1 += b << 14; if (!(b & 0x80)) goto done; + part1 -= 0x80 << 14; + b = *(ptr++); part1 += b << 21; if (!(b & 0x80)) goto done; + part1 -= 0x80 << 21; + b = *(ptr++); part2 = b ; if (!(b & 0x80)) goto done; + part2 -= 0x80; + b = *(ptr++); part2 += b << 7; if (!(b & 0x80)) goto done; + // "part2 -= 0x80 << 7" is irrelevant because (0x80 << 7) << 56 is 0. + + // We have overrun the maximum size of a varint (10 bytes). Assume + // the data is corrupt. + return std::make_pair(false, ptr); + + done: + *value = (static_cast(part0)) | + (static_cast(part1) << 28) | + (static_cast(part2) << 56); + return std::make_pair(true, ptr); +} + } // namespace bool CodedInputStream::ReadVarint32Slow(uint32* value) { @@ -408,6 +451,32 @@ int64 CodedInputStream::ReadVarint32Fallback(uint32 first_byte_or_zero) { } } +int CodedInputStream::ReadVarintSizeAsIntSlow() { + // Directly invoke ReadVarint64Fallback, since we already tried to optimize + // for one-byte varints. + std::pair p = ReadVarint64Fallback(); + if (!p.second || p.first > static_cast(INT_MAX)) return -1; + return p.first; +} + +int CodedInputStream::ReadVarintSizeAsIntFallback() { + if (BufferSize() >= kMaxVarintBytes || + // Optimization: We're also safe if the buffer is non-empty and it ends + // with a byte that would terminate a varint. + (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { + uint64 temp; + ::std::pair p = ReadVarint64FromArray(buffer_, &temp); + if (!p.first || temp > static_cast(INT_MAX)) return -1; + buffer_ = p.second; + return temp; + } else { + // Really slow case: we will incur the cost of an extra function call here, + // but moving this out of line reduces the size of this function, which + // improves the common case. In micro benchmarks, this is worth about 10-15% + return ReadVarintSizeAsIntSlow(); + } +} + uint32 CodedInputStream::ReadTagSlow() { if (buffer_ == buffer_end_) { // Call refresh. @@ -499,47 +568,13 @@ std::pair CodedInputStream::ReadVarint64Fallback() { // Optimization: We're also safe if the buffer is non-empty and it ends // with a byte that would terminate a varint. (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { - // Fast path: We have enough bytes left in the buffer to guarantee that - // this read won't cross the end, so we can skip the checks. - - const uint8* ptr = buffer_; - uint32 b; - - // Splitting into 32-bit pieces gives better performance on 32-bit - // processors. - uint32 part0 = 0, part1 = 0, part2 = 0; - - b = *(ptr++); part0 = b ; if (!(b & 0x80)) goto done; - part0 -= 0x80; - b = *(ptr++); part0 += b << 7; if (!(b & 0x80)) goto done; - part0 -= 0x80 << 7; - b = *(ptr++); part0 += b << 14; if (!(b & 0x80)) goto done; - part0 -= 0x80 << 14; - b = *(ptr++); part0 += b << 21; if (!(b & 0x80)) goto done; - part0 -= 0x80 << 21; - b = *(ptr++); part1 = b ; if (!(b & 0x80)) goto done; - part1 -= 0x80; - b = *(ptr++); part1 += b << 7; if (!(b & 0x80)) goto done; - part1 -= 0x80 << 7; - b = *(ptr++); part1 += b << 14; if (!(b & 0x80)) goto done; - part1 -= 0x80 << 14; - b = *(ptr++); part1 += b << 21; if (!(b & 0x80)) goto done; - part1 -= 0x80 << 21; - b = *(ptr++); part2 = b ; if (!(b & 0x80)) goto done; - part2 -= 0x80; - b = *(ptr++); part2 += b << 7; if (!(b & 0x80)) goto done; - // "part2 -= 0x80 << 7" is irrelevant because (0x80 << 7) << 56 is 0. - - // We have overrun the maximum size of a varint (10 bytes). The data - // must be corrupt. - return std::make_pair(0, false); - - done: - Advance(ptr - buffer_); - return std::make_pair((static_cast(part0)) | - (static_cast(part1) << 28) | - (static_cast(part2) << 56), - true); + uint64 temp; + ::std::pair p = ReadVarint64FromArray(buffer_, &temp); + if (!p.first) { + return std::make_pair(0, false); + } + buffer_ = p.second; + return std::make_pair(temp, true); } else { uint64 temp; bool success = ReadVarint64Slow(&temp); diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h index c81a33ac..eb320745 100644 --- a/src/google/protobuf/io/coded_stream.h +++ b/src/google/protobuf/io/coded_stream.h @@ -237,6 +237,17 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // Read an unsigned integer with Varint encoding. bool ReadVarint64(uint64* value); + // Reads a varint off the wire into an "int". This should be used for reading + // sizes off the wire (sizes of strings, submessages, bytes fields, etc). + // + // The value from the wire is interpreted as unsigned. If its value exceeds + // the representable value of an integer on this platform, instead of + // truncating we return false. Truncating (as performed by ReadVarint32() + // above) is an acceptable approach for fields representing an integer, but + // when we are parsing a size from the wire, truncating the value would result + // in us misparsing the payload. + bool ReadVarintSizeAsInt(int* value); + // Read a tag. This calls ReadVarint32() and returns the result, or returns // zero (which is not a valid tag) if ReadVarint32() fails. Also, it updates // the last tag value, which can be checked with LastTagWas(). @@ -594,9 +605,11 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // if it fails and the uint32 it read otherwise. The latter has a bool // indicating success or failure as part of its return type. int64 ReadVarint32Fallback(uint32 first_byte_or_zero); + int ReadVarintSizeAsIntFallback(); std::pair ReadVarint64Fallback(); bool ReadVarint32Slow(uint32* value); bool ReadVarint64Slow(uint64* value); + int ReadVarintSizeAsIntSlow(); bool ReadLittleEndian32Fallback(uint32* value); bool ReadLittleEndian64Fallback(uint64* value); // Fallback/slow methods for reading tags. These do not update last_tag_, @@ -868,6 +881,19 @@ inline bool CodedInputStream::ReadVarint64(uint64* value) { return p.second; } +inline bool CodedInputStream::ReadVarintSizeAsInt(int* value) { + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { + int v = *buffer_; + if (v < 0x80) { + *value = v; + Advance(1); + return true; + } + } + *value = ReadVarintSizeAsIntFallback(); + return *value >= 0; +} + // static inline const uint8* CodedInputStream::ReadLittleEndian32FromArray( const uint8* buffer, diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h index 2ba84559..e78e2efd 100644 --- a/src/google/protobuf/io/printer.h +++ b/src/google/protobuf/io/printer.h @@ -200,6 +200,26 @@ class LIBPROTOBUF_EXPORT Printer { Annotate(begin_varname, end_varname, descriptor->file()->name(), path); } + // Link a subsitution variable emitted by the last call to Print to the file + // with path file_name. + void Annotate(const char* varname, const string& file_name) { + Annotate(varname, varname, file_name); + } + + // Link the output range defined by the substitution variables as emitted by + // the last call to Print to the file with path file_name. The range begins + // at begin_varname's value and ends after the last character of the value + // substituted for end_varname. + void Annotate(const char* begin_varname, const char* end_varname, + const string& file_name) { + if (annotation_collector_ == NULL) { + // Annotations aren't turned on for this Printer. + return; + } + vector empty_path; + Annotate(begin_varname, end_varname, file_name, empty_path); + } + // Print some text after applying variable substitutions. If a particular // variable in the text is not defined, this will crash. Variables to be // substituted are identified by their names surrounded by delimiter diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h index 9d81ccfb..e4d6a024 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h @@ -53,7 +53,6 @@ #include #include #include -#include #include diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index 31593c1a..42bcfd94 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -520,7 +520,7 @@ class Map { typedef size_t size_type; typedef hash hasher; - Map(bool old_style = true) + explicit Map(bool old_style = true) : arena_(NULL), default_enum_value_(0), old_style_(old_style) { @@ -1621,6 +1621,24 @@ class Map { return *this; } + void swap(Map& other) { + if (arena_ == other.arena_ && old_style_ == other.old_style_) { + std::swap(default_enum_value_, other.default_enum_value_); + if (old_style_) { + std::swap(deprecated_elements_, other.deprecated_elements_); + } else { + std::swap(elements_, other.elements_); + } + } else { + // TODO(zuguang): optimize this. The temporary copy can be allocated + // in the same arena as the other message, and the "other = copy" can + // be replaced with the fast-path swap above. + Map copy = *this; + *this = other; + other = copy; + } + } + // Access to hasher. Currently this returns a copy, but it may // be modified to return a const reference in the future. hasher hash_function() const { diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index 987c4e29..801e7522 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -166,8 +166,10 @@ class MapEntry : public MapEntryBase { entry_lite_.SerializeWithCachedSizes(output); } - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { - return entry_lite_.SerializeWithCachedSizesToArray(output); + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(bool deterministic, + ::google::protobuf::uint8* output) const { + return entry_lite_.InternalSerializeWithCachedSizesToArray(deterministic, + output); } int GetCachedSize() const { diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h index 7cdf1b93..23ac7b8a 100644 --- a/src/google/protobuf/map_entry_lite.h +++ b/src/google/protobuf/map_entry_lite.h @@ -31,6 +31,7 @@ #ifndef GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__ #define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__ +#include #include #include @@ -54,6 +55,38 @@ class MapFieldLite; namespace protobuf { namespace internal { +// MoveHelper::Move is used to set *dest. It copies *src, or moves it (in +// the C++11 sense), or swaps it. *src is left in a sane state for +// subsequent destruction, but shouldn't be used for anything. +template +struct MoveHelper { // primitives + static void Move(T* src, T* dest) { *dest = *src; } +}; + +template +struct MoveHelper { // enums + static void Move(T* src, T* dest) { *dest = *src; } + // T is an enum here, so allow conversions to and from int. + static void Move(T* src, int* dest) { *dest = static_cast(*src); } + static void Move(int* src, T* dest) { *dest = static_cast(*src); } +}; + +template +struct MoveHelper { // messages + static void Move(T* src, T* dest) { dest->Swap(src); } +}; + +template +struct MoveHelper { // strings and similar + static void Move(T* src, T* dest) { +#if __cplusplus >= 201103L + *dest = std::move(*src); +#else + dest->swap(*src); +#endif + } +}; + // MapEntryLite is used to implement parsing and serialization of map for lite // runtime. template + class Parser { + public: + explicit Parser(MapField* mf) : mf_(mf), map_(mf->MutableMap()) {} + + // This does what the typical MergePartialFromCodedStream() is expected to + // do, with the additional side-effect that if successful (i.e., if true is + // going to be its return value) it inserts the key-value pair into map_. + bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) { + // Look for the expected thing: a key and then a value. If it fails, + // invoke the enclosing class's MergePartialFromCodedStream, or return + // false if that would be pointless. + if (input->ExpectTag(kKeyTag)) { + if (!KeyTypeHandler::Read(input, &key_)) { + return false; + } + // Peek at the next byte to see if it is kValueTag. If not, bail out. + const void* data; + int size; + input->GetDirectBufferPointerInline(&data, &size); + // We could use memcmp here, but we don't bother. The tag is one byte. + assert(kTagSize == 1); + if (size > 0 && *reinterpret_cast(data) == kValueTag) { + typename Map::size_type size = map_->size(); + value_ptr_ = &(*map_)[key_]; + if (GOOGLE_PREDICT_TRUE(size != map_->size())) { + // We created a new key-value pair. Fill in the value. + typedef + typename MapIf::type T; + input->Skip(kTagSize); // Skip kValueTag. + if (!ValueTypeHandler::Read(input, + reinterpret_cast(value_ptr_))) { + map_->erase(key_); // Failure! Undo insertion. + return false; + } + if (input->ExpectAtEnd()) return true; + return ReadBeyondKeyValuePair(input); + } + } + } else { + key_ = Key(); + } + + entry_.reset(mf_->NewEntry()); + *entry_->mutable_key() = key_; + if (!entry_->MergePartialFromCodedStream(input)) return false; + return UseKeyAndValueFromEntry(); + } + + const Key& key() const { return key_; } + const Value& value() const { return *value_ptr_; } + + private: + bool UseKeyAndValueFromEntry() GOOGLE_ATTRIBUTE_COLD { + // Update key_ in case we need it later (because key() is called). + // This is potentially inefficient, especially if the key is + // expensive to copy (e.g., a long string), but this is a cold + // path, so it's not a big deal. + key_ = entry_->key(); + value_ptr_ = &(*map_)[key_]; + MoveHelper::Move(entry_->mutable_value(), value_ptr_); + if (entry_->GetArena() != NULL) entry_.release(); + return true; + } + + // After reading a key and value successfully, and inserting that data + // into map_, we are not at the end of the input. This is unusual, but + // allowed by the spec. + bool ReadBeyondKeyValuePair(::google::protobuf::io::CodedInputStream* input) + GOOGLE_ATTRIBUTE_COLD { + typedef MoveHelper KeyMover; + typedef MoveHelper ValueMover; + entry_.reset(mf_->NewEntry()); + ValueMover::Move(value_ptr_, entry_->mutable_value()); + map_->erase(key_); + KeyMover::Move(&key_, entry_->mutable_key()); + if (!entry_->MergePartialFromCodedStream(input)) return false; + return UseKeyAndValueFromEntry(); + } + + MapField* const mf_; + Map* const map_; + Key key_; + Value* value_ptr_; + // On the fast path entry_ is not used. + google::protobuf::scoped_ptr entry_; + }; + protected: void set_has_key() { _has_bits_[0] |= 0x00000001u; } bool has_key() const { return (_has_bits_[0] & 0x00000001u) != 0; } diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc index 223d42f3..dd5061c4 100644 --- a/src/google/protobuf/map_field_test.cc +++ b/src/google/protobuf/map_field_test.cc @@ -47,8 +47,8 @@ #include #include #include - namespace google { + namespace protobuf { namespace internal { diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index 9d4d6c13..dccb31ca 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -77,6 +76,7 @@ #include #include #include +#include #include #include @@ -915,6 +915,55 @@ TEST_P(MapImplTest, ConvertToStdVectorOfPairs) { EXPECT_EQ(101, std_vec[0].second); } +TEST_P(MapImplTest, SwapSameStyle) { + Map another(GetParam()); // same old_style_ value + map_[9398] = 41999; + another[9398] = 41999; + another[8070] = 42056; + another.swap(map_); + EXPECT_THAT(another, testing::UnorderedElementsAre( + testing::Pair(9398, 41999))); + EXPECT_THAT(map_, testing::UnorderedElementsAre( + testing::Pair(8070, 42056), + testing::Pair(9398, 41999))); +} + +TEST_P(MapImplTest, SwapDifferentStyle) { + Map another(!GetParam()); // different old_style_ value + map_[9398] = 41999; + another[9398] = 41999; + another[8070] = 42056; + another.swap(map_); + EXPECT_THAT(another, testing::UnorderedElementsAre( + testing::Pair(9398, 41999))); + EXPECT_THAT(map_, testing::UnorderedElementsAre( + testing::Pair(8070, 42056), + testing::Pair(9398, 41999))); +} + +TEST_P(MapImplTest, SwapArena) { + Arena arena1, arena2; + Map m1(&arena1, false); + Map m2(&arena2, false); + map_[9398] = 41999; + m1[9398] = 41999; + m1[8070] = 42056; + m2[10244] = 10247; + m2[8070] = 42056; + m1.swap(map_); + EXPECT_THAT(m1, testing::UnorderedElementsAre( + testing::Pair(9398, 41999))); + EXPECT_THAT(map_, testing::UnorderedElementsAre( + testing::Pair(8070, 42056), + testing::Pair(9398, 41999))); + m2.swap(m1); + EXPECT_THAT(m1, testing::UnorderedElementsAre( + testing::Pair(8070, 42056), + testing::Pair(10244, 10247))); + EXPECT_THAT(m2, testing::UnorderedElementsAre( + testing::Pair(9398, 41999))); +} + INSTANTIATE_TEST_CASE_P(BoolSequence, MapImplTest, testing::Bool()); // Map Field Reflection Test ======================================== @@ -2106,6 +2155,76 @@ TEST(GeneratedMapFieldTest, DuplicatedKeyWireFormat) { EXPECT_TRUE(message.ParseFromString(data)); EXPECT_EQ(1, message.map_int32_int32().size()); EXPECT_EQ(1, message.map_int32_int32().at(2)); + + // A similar test, but with a map from int to a message type. + // Again, we want to be sure that the "second one wins" when + // there are two separate entries with the same key. + const int key = 99; + unittest::TestRequiredMessageMap map_message; + unittest::TestRequired with_dummy4; + with_dummy4.set_a(0); + with_dummy4.set_b(0); + with_dummy4.set_c(0); + with_dummy4.set_dummy4(11); + (*map_message.mutable_map_field())[key] = with_dummy4; + string s = map_message.SerializeAsString(); + unittest::TestRequired with_dummy5; + with_dummy5.set_a(0); + with_dummy5.set_b(0); + with_dummy5.set_c(0); + with_dummy5.set_dummy5(12); + (*map_message.mutable_map_field())[key] = with_dummy5; + string both = s + map_message.SerializeAsString(); + // We don't expect a merge now. The "second one wins." + ASSERT_TRUE(map_message.ParseFromString(both)); + ASSERT_EQ(1, map_message.map_field().size()); + ASSERT_EQ(1, map_message.map_field().count(key)); + EXPECT_EQ(0, map_message.map_field().find(key)->second.a()); + EXPECT_EQ(0, map_message.map_field().find(key)->second.b()); + EXPECT_EQ(0, map_message.map_field().find(key)->second.c()); + EXPECT_FALSE(map_message.map_field().find(key)->second.has_dummy4()); + ASSERT_TRUE(map_message.map_field().find(key)->second.has_dummy5()); + EXPECT_EQ(12, map_message.map_field().find(key)->second.dummy5()); +} + +// Exhaustive combinations of keys, values, and junk in any order. +// This re-tests some of the things tested above, but if it fails +// it's more work to determine what went wrong, so it isn't necessarily +// bad that we have the simpler tests too. +TEST(GeneratedMapFieldTest, KeysValuesUnknownsWireFormat) { + unittest::TestMap message; + const int kMaxNumKeysAndValuesAndJunk = 4; + const char kKeyTag = 0x08; + const char kValueTag = 0x10; + const char kJunkTag = 0x20; + for (int items = 0; items <= kMaxNumKeysAndValuesAndJunk; items++) { + string data = "\x0A"; + // Encode length of what will follow. + data.push_back(items * 2); + static const int kBitsOfIPerItem = 4; + static const int mask = (1 << kBitsOfIPerItem) - 1; + // Each iteration of the following is a test. It uses i as bit vector + // encoding the keys and values to put in the wire format. + for (int i = 0; i < (1 << (items * kBitsOfIPerItem)); i++) { + string wire_format = data; + int expected_key = 0; + int expected_value = 0; + for (int k = i, j = 0; j < items; j++, k >>= kBitsOfIPerItem) { + bool is_key = k & 0x1; + bool is_value = !is_key && (k & 0x2); + wire_format.push_back(is_key ? kKeyTag : + is_value ? kValueTag : kJunkTag); + char c = static_cast(k & mask) >> 2; // One char after the tag. + wire_format.push_back(c); + if (is_key) expected_key = static_cast(c); + if (is_value) expected_value = static_cast(c); + ASSERT_TRUE(message.ParseFromString(wire_format)); + ASSERT_EQ(1, message.map_int32_int32().size()); + ASSERT_EQ(expected_key, message.map_int32_int32().begin()->first); + ASSERT_EQ(expected_value, message.map_int32_int32().begin()->second); + } + } + } } TEST(GeneratedMapFieldTest, DuplicatedValueWireFormat) { @@ -2189,6 +2308,74 @@ TEST(GeneratedMapFieldTest, IsInitialized) { EXPECT_TRUE(map_message.IsInitialized()); } +TEST(GeneratedMapFieldTest, MessagesMustMerge) { + unittest::TestRequiredMessageMap map_message; + unittest::TestRequired with_dummy4; + with_dummy4.set_a(97); + with_dummy4.set_b(0); + with_dummy4.set_c(0); + with_dummy4.set_dummy4(98); + + EXPECT_TRUE(with_dummy4.IsInitialized()); + (*map_message.mutable_map_field())[0] = with_dummy4; + EXPECT_TRUE(map_message.IsInitialized()); + string s = map_message.SerializeAsString(); + + // Modify s so that there are two values in the entry for key 0. + // The first will have no value for c. The second will have no value for a. + // Those are required fields. Also, make some other little changes, to + // ensure we are merging the two values (because they're messages). + ASSERT_EQ(s.size() - 2, s[1]); // encoding of the length of what follows + string encoded_val(s.data() + 4, s.data() + s.size()); + // In s, change the encoding of c to an encoding of dummy32. + s[s.size() - 3] -= 8; + // Make encoded_val slightly different from what's in s. + encoded_val[encoded_val.size() - 1] += 33; // Encode c = 33. + for (int i = 0; i < encoded_val.size(); i++) { + if (encoded_val[i] == 97) { + // Encode b = 91 instead of a = 97. But this won't matter, because + // we also encode b = 0 right after this. The point is to leave out + // a required field, and make sure the parser doesn't complain, because + // every required field is set after the merge of the two values. + encoded_val[i - 1] += 16; + encoded_val[i] = 91; + } else if (encoded_val[i] == 98) { + // Encode dummy5 = 99 instead of dummy4 = 98. + encoded_val[i - 1] += 8; // The tag for dummy5 is 8 more. + encoded_val[i]++; + break; + } + } + + s += encoded_val; // Add the second message. + s[1] += encoded_val.size(); // Adjust encoded size. + + // Test key then value then value. + int key = 0; + ASSERT_TRUE(map_message.ParseFromString(s)); + ASSERT_EQ(1, map_message.map_field().size()); + ASSERT_EQ(1, map_message.map_field().count(key)); + EXPECT_EQ(97, map_message.map_field().find(key)->second.a()); + EXPECT_EQ(0, map_message.map_field().find(key)->second.b()); + EXPECT_EQ(33, map_message.map_field().find(key)->second.c()); + EXPECT_EQ(98, map_message.map_field().find(key)->second.dummy4()); + EXPECT_EQ(99, map_message.map_field().find(key)->second.dummy5()); + + // Test key then value then value then key. + s.push_back(s[2]); // Copy the key's tag. + key = 19; + s.push_back(key); // Second key is 19 instead of 0. + s[1] += 2; // Adjust encoded size. + ASSERT_TRUE(map_message.ParseFromString(s)); + ASSERT_EQ(1, map_message.map_field().size()); + ASSERT_EQ(1, map_message.map_field().count(key)); + EXPECT_EQ(97, map_message.map_field().find(key)->second.a()); + EXPECT_EQ(0, map_message.map_field().find(key)->second.b()); + EXPECT_EQ(33, map_message.map_field().find(key)->second.c()); + EXPECT_EQ(98, map_message.map_field().find(key)->second.dummy4()); + EXPECT_EQ(99, map_message.map_field().find(key)->second.dummy5()); +} + // Generated Message Reflection Test ================================ TEST(GeneratedMapFieldReflectionTest, SpaceUsed) { @@ -2783,6 +2970,21 @@ TEST(ArenaTest, StringMapNoLeak) { ASSERT_FALSE(message == NULL); } +TEST(ArenaTest, IsInitialized) { + // Allocate a large initial polluted block. + std::vector arena_block(128 * 1024); + std::fill(arena_block.begin(), arena_block.end(), '\xff'); + + ArenaOptions options; + options.initial_block = &arena_block[0]; + options.initial_block_size = arena_block.size(); + Arena arena(options); + + unittest::TestArenaMap* message = + Arena::CreateMessage(&arena); + EXPECT_EQ(0, (*message->mutable_map_int32_int32())[0]); +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h index f8ad7584..74e8bb50 100644 --- a/src/google/protobuf/map_type_handler.h +++ b/src/google/protobuf/map_type_handler.h @@ -164,6 +164,9 @@ class MapTypeHandler { MapEntryAccessorType* value); static inline void Write(int field, const MapEntryAccessorType& value, io::CodedOutputStream* output); + static inline uint8* InternalWriteToArray(int field, + const MapEntryAccessorType& value, + bool deterministic, uint8* output); static inline uint8* WriteToArray(int field, const MapEntryAccessorType& value, uint8* output); @@ -220,9 +223,16 @@ class MapTypeHandler { MapEntryAccessorType* value); \ static inline void Write(int field, const MapEntryAccessorType& value, \ io::CodedOutputStream* output); \ + static inline uint8* InternalWriteToArray( \ + int field, \ + const MapEntryAccessorType& value, \ + bool deterministic, \ + uint8* output); \ static inline uint8* WriteToArray(int field, \ const MapEntryAccessorType& value, \ - uint8* output); \ + uint8* output) { \ + return InternalWriteToArray(field, value, false, output); \ + } \ static inline const MapEntryAccessorType& GetExternalReference( \ const TypeOnMemory& value); \ static inline void DeleteNoArena(const TypeOnMemory& x); \ @@ -362,9 +372,11 @@ inline void MapTypeHandler::Write( template inline uint8* -MapTypeHandler::WriteToArray( - int field, const MapEntryAccessorType& value, uint8* output) { - return WireFormatLite::WriteMessageToArray(field, value, output); +MapTypeHandler::InternalWriteToArray( + int field, const MapEntryAccessorType& value, bool deterministic, + uint8* output) { + return WireFormatLite::InternalWriteMessageToArray(field, value, + deterministic, output); } #define WRITE_METHOD(FieldType, DeclaredType) \ @@ -376,8 +388,9 @@ MapTypeHandler::WriteToArray( } \ template \ inline uint8* \ - MapTypeHandler::WriteToArray( \ - int field, const MapEntryAccessorType& value, uint8* output) { \ + MapTypeHandler::InternalWriteToArray( \ + int field, const MapEntryAccessorType& value, bool, uint8* output) { \ return WireFormatLite::Write##DeclaredType##ToArray(field, value, output); \ } @@ -543,7 +556,7 @@ inline bool MapTypeHandler::MapEntryAccessorType& \ MapTypeHandler::GetExternalReference(const TypeOnMemory& value) { \ - return value.Get(&::google::protobuf::internal::GetEmptyString()); \ + return value.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); \ } \ template \ inline int \ @@ -564,7 +577,8 @@ inline bool MapTypeHandler \ inline void MapTypeHandler::Clear( \ TypeOnMemory* value, Arena* arena) { \ - value->ClearToEmpty(&::google::protobuf::internal::GetEmptyString(), arena); \ + value->ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), \ + arena); \ } \ template \ inline void \ @@ -577,12 +591,12 @@ inline bool MapTypeHandler \ inline void MapTypeHandler::Merge( \ const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) { \ - to->Set(&::google::protobuf::internal::GetEmptyString(), from, arena); \ + to->Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from, arena); \ } \ template \ void MapTypeHandler::DeleteNoArena( \ TypeOnMemory& value) { \ - value.DestroyNoArena(&::google::protobuf::internal::GetEmptyString()); \ + value.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); \ } \ template \ inline void MapTypeHandler::Initialize( \ TypeOnMemory* value, Arena* arena) { \ - value->UnsafeSetDefault(&::google::protobuf::internal::GetEmptyString()); \ + value->UnsafeSetDefault( \ + &::google::protobuf::internal::GetEmptyStringAlreadyInited()); \ } \ template \ inline void \ @@ -606,7 +621,8 @@ inline bool MapTypeHandler::MapEntryAccessorType* \ MapTypeHandler::EnsureMutable( \ TypeOnMemory* value, Arena* arena) { \ - return value->Mutable(&::google::protobuf::internal::GetEmptyString(), arena); \ + return value->Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), \ + arena); \ } \ template \ inline const typename MapTypeHandler::DefaultIfNotInitialized(const TypeOnMemory& value, \ const TypeOnMemory& \ default_value) { \ - return value.Get(&::google::protobuf::internal::GetEmptyString()); \ + return value.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); \ } \ template \ inline bool MapTypeHandlerGetPrototype(field->message_type() MUST return an instance of the - // compiled-in class for this type, NOT DynamicMessage. + // factory->GetPrototype(field->message_type()) MUST return an instance of + // the compiled-in class for this type, NOT DynamicMessage. virtual Message* MutableMessage(Message* message, const FieldDescriptor* field, MessageFactory* factory = NULL) const = 0; diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 9d7b64f7..3913be1b 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -221,7 +221,8 @@ bool MessageLite::ParsePartialFromArray(const void* data, int size) { // =================================================================== -uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const { +uint8* MessageLite::InternalSerializeWithCachedSizesToArray( + bool deterministic, uint8* target) const { // We only optimize this when using optimize_for = SPEED. In other cases // we just use the CodedOutputStream path. int size = GetCachedSize(); diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index 4c16f4c0..f606aeec 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -51,6 +51,9 @@ namespace io { class ZeroCopyInputStream; class ZeroCopyOutputStream; } +namespace internal { + class WireFormatLite; +} // Interface to light weight protocol messages. // @@ -249,10 +252,11 @@ class LIBPROTOBUF_EXPORT MessageLite { 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; + // A version of SerializeWithCachedSizesToArray, below, that does + // not guarantee deterministic serialization. + virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const { + return InternalSerializeWithCachedSizesToArray(false, target); + } // Returns the result of the last call to ByteSize(). An embedded message's // size is needed both to serialize it (because embedded messages are @@ -267,7 +271,22 @@ class LIBPROTOBUF_EXPORT MessageLite { // method.) virtual int GetCachedSize() const = 0; + // Functions below here are not part of the public interface. It isn't + // enforced, but they should be treated as private, and will be private + // at some future time. Unfortunately the implementation of the "friend" + // keyword in GCC is broken at the moment, but we expect it will be fixed. + + // 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. If deterministic + // is true then we use deterministic serialization, e.g., map keys are sorted. + // FOR INTERNAL USE ONLY! + virtual uint8* InternalSerializeWithCachedSizesToArray(bool deterministic, + uint8* target) const; + private: + friend class internal::WireFormatLite; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite); }; diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 1961bc48..38358dbb 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -564,12 +564,16 @@ class GenericTypeHandler { return ::google::protobuf::Arena::CreateMaybeMessage( arena, static_cast(0)); } - // We force NewFromPrototype() and Delete() to be non-inline to reduce code - // size: else, several other methods get inlined copies of message types' - // constructors and destructors. + // We force NewFromPrototype() to be non-inline to reduce code size: + // else, several other methods get inlined copies of message types' + // constructors. GOOGLE_ATTRIBUTE_NOINLINE static GenericType* NewFromPrototype( const GenericType* prototype, ::google::protobuf::Arena* arena = NULL); - GOOGLE_ATTRIBUTE_NOINLINE static void Delete(GenericType* value, Arena* arena); + static inline void Delete(GenericType* value, Arena* arena) { + if (arena == NULL) { + delete value; + } + } static inline ::google::protobuf::Arena* GetArena(GenericType* value) { return ::google::protobuf::Arena::GetArena(value); } @@ -594,12 +598,6 @@ GenericType* GenericTypeHandler::NewFromPrototype( return New(arena); } template -void GenericTypeHandler::Delete(GenericType* value, Arena* arena) { - if (arena == NULL) { - delete value; - } -} -template void GenericTypeHandler::Merge(const GenericType& from, GenericType* to) { to->MergeFrom(from); @@ -1359,13 +1357,13 @@ inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(::google::protobuf::Arena* are template void RepeatedPtrFieldBase::Destroy() { - if (rep_ != NULL) { - for (int i = 0; i < rep_->allocated_size; i++) { - TypeHandler::Delete(cast(rep_->elements[i]), arena_); - } - if (arena_ == NULL) { - delete [] reinterpret_cast(rep_); + if (rep_ != NULL && arena_ == NULL) { + int n = rep_->allocated_size; + void* const* elements = rep_->elements; + for (int i = 0; i < n; i++) { + TypeHandler::Delete(cast(elements[i]), NULL); } + delete[] reinterpret_cast(rep_); } rep_ = NULL; } diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index c67cd102..4d8e77ce 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -244,8 +244,8 @@ void SourceContext::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.SourceContext) } -::google::protobuf::uint8* SourceContext::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* SourceContext::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceContext) // optional string file_name = 1; if (this->file_name().size() > 0) { diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index ccfd365b..341a4534 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h @@ -41,7 +41,7 @@ class SourceContext; // =================================================================== -class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceContext) */ { public: SourceContext(); virtual ~SourceContext(); @@ -75,7 +75,11 @@ class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/src/google/protobuf/source_context.proto b/src/google/protobuf/source_context.proto index d76252ca..a2c08e2b 100644 --- a/src/google/protobuf/source_context.proto +++ b/src/google/protobuf/source_context.proto @@ -43,6 +43,6 @@ option objc_class_prefix = "GPB"; // protobuf element, like the file in which it is defined. message SourceContext { // The path-qualified name of the .proto file that contained the associated - // protobuf element. For example: `"google/protobuf/source.proto"`. + // protobuf element. For example: `"google/protobuf/source_context.proto"`. string file_name = 1; } diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index 11ccabbf..dd6b78d1 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -239,6 +239,7 @@ Struct::Struct(const Struct& from) void Struct::SharedCtor() { _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); _cached_size_ = 0; fields_.SetAssignDescriptorCallback( protobuf_AssignDescriptorsOnce); @@ -301,12 +302,16 @@ bool Struct::MergePartialFromCodedStream( if (tag == 10) { DO_(input->IncrementRecursionDepth()); parse_loop_fields: - ::google::protobuf::scoped_ptr entry(fields_.NewEntry()); + Struct_FieldsEntry::Parser< ::google::protobuf::internal::MapField< + ::std::string, ::google::protobuf::Value, + ::google::protobuf::internal::WireFormatLite::TYPE_STRING, + ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE, + 0 >, + ::google::protobuf::Map< ::std::string, ::google::protobuf::Value > > parser(&fields_); DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, entry.get())); - (*mutable_fields())[entry->key()].Swap(entry->mutable_value()); + input, &parser)); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - entry->key().data(), entry->key().length(), + parser.key().data(), parser.key().length(), ::google::protobuf::internal::WireFormatLite::PARSE, "google.protobuf.Struct.FieldsEntry.key")); } else { @@ -361,8 +366,8 @@ void Struct::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Struct) } -::google::protobuf::uint8* Struct::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Struct::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Struct) // map fields = 1; { @@ -372,8 +377,8 @@ void Struct::SerializeWithCachedSizes( it != this->fields().end(); ++it) { entry.reset(fields_.NewEntryWrapper(it->first, it->second)); target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, *entry, target); + InternalWriteMessageNoVirtualToArray( + 1, *entry, false, target); ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( it->first.data(), it->first.length(), ::google::protobuf::internal::WireFormatLite::SERIALIZE, @@ -774,8 +779,8 @@ void Value::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Value) } -::google::protobuf::uint8* Value::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Value::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Value) // optional .google.protobuf.NullValue null_value = 1; if (has_null_value()) { @@ -807,15 +812,15 @@ void Value::SerializeWithCachedSizes( // optional .google.protobuf.Struct struct_value = 5; if (has_struct_value()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, *kind_.struct_value_, target); + InternalWriteMessageNoVirtualToArray( + 5, *kind_.struct_value_, false, target); } // optional .google.protobuf.ListValue list_value = 6; if (has_list_value()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 6, *kind_.list_value_, target); + InternalWriteMessageNoVirtualToArray( + 6, *kind_.list_value_, false, target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Value) @@ -1367,14 +1372,14 @@ void ListValue::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.ListValue) } -::google::protobuf::uint8* ListValue::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ListValue::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ListValue) // repeated .google.protobuf.Value values = 1; for (unsigned int i = 0, n = this->values_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, this->values(i), target); + InternalWriteMessageNoVirtualToArray( + 1, this->values(i), false, target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ListValue) diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index 6a4764a7..b085b849 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h @@ -66,7 +66,7 @@ inline bool NullValue_Parse( } // =================================================================== -class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Struct) */ { public: Struct(); virtual ~Struct(); @@ -100,7 +100,11 @@ class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -158,7 +162,7 @@ class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Value) */ { public: Value(); virtual ~Value(); @@ -202,7 +206,11 @@ class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -320,7 +328,7 @@ class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ListValue) */ { public: ListValue(); virtual ~ListValue(); @@ -354,7 +362,11 @@ class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/src/google/protobuf/stubs/mathlimits.h b/src/google/protobuf/stubs/mathlimits.h index d9846940..70e47bff 100644 --- a/src/google/protobuf/stubs/mathlimits.h +++ b/src/google/protobuf/stubs/mathlimits.h @@ -230,11 +230,11 @@ DECL_UNSIGNED_INT_LIMITS(unsigned long long int) static bool IsNegInf(const Type x) { return _fpclass(x) == _FPCLASS_NINF; } #else #define DECL_FP_LIMIT_FUNCS \ - static bool IsFinite(const Type x) { return !isinf(x) && !isnan(x); } \ + static bool IsFinite(const Type x) { return !isinf(x) && !isnan(x); } \ static bool IsNaN(const Type x) { return isnan(x); } \ static bool IsInf(const Type x) { return isinf(x); } \ - static bool IsPosInf(const Type x) { return isinf(x) && x > 0; } \ - static bool IsNegInf(const Type x) { return isinf(x) && x < 0; } + static bool IsPosInf(const Type x) { return isinf(x) && x > 0; } \ + static bool IsNegInf(const Type x) { return isinf(x) && x < 0; } #endif // We can't put floating-point constant values in the header here because diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h index 0e65fc8f..328258b7 100644 --- a/src/google/protobuf/stubs/port.h +++ b/src/google/protobuf/stubs/port.h @@ -174,6 +174,15 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); #endif #endif +#ifndef GOOGLE_ATTRIBUTE_NORETURN +#ifdef __GNUC__ +// Tell the compiler that a given function never returns. +#define GOOGLE_ATTRIBUTE_NORETURN __attribute__((noreturn)) +#else +#define GOOGLE_ATTRIBUTE_NORETURN +#endif +#endif + #ifndef GOOGLE_ATTRIBUTE_DEPRECATED #ifdef __GNUC__ // If the method/variable/type is used anywhere, produce a warning. diff --git a/src/google/protobuf/test_util.cc b/src/google/protobuf/test_util.cc index 07aa1d77..658c8ee2 100644 --- a/src/google/protobuf/test_util.cc +++ b/src/google/protobuf/test_util.cc @@ -3332,7 +3332,11 @@ void TestUtil::ReflectionTester::ExpectMessagesReleasedViaReflection( break; case NOT_NULL: EXPECT_TRUE(released != NULL); - EXPECT_EQ(&sub_message, released); + if (message->GetArena() == NULL) { + // released message must be same as sub_message if source message is + // not on arena. + EXPECT_EQ(&sub_message, released); + } break; case CAN_BE_NULL: break; diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc index 2b9cddef..d45706b6 100644 --- a/src/google/protobuf/testing/googletest.cc +++ b/src/google/protobuf/testing/googletest.cc @@ -66,6 +66,9 @@ namespace protobuf { string TestSourceDir() { #ifndef GOOGLE_THIRD_PARTY_PROTOBUF +#ifdef GOOGLE_PROTOBUF_TEST_SOURCE_PATH + return GOOGLE_PROTOBUF_TEST_SOURCE_PATH; +#else #ifndef _MSC_VER // automake sets the "srcdir" environment variable. char* result = getenv("srcdir"); @@ -86,6 +89,7 @@ string TestSourceDir() { prefix += "/.."; } return prefix + "/src"; +#endif // GOOGLE_PROTOBUF_TEST_SOURCE_PATH #else return "third_party/protobuf/src"; #endif // GOOGLE_THIRD_PARTY_PROTOBUF diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index c0dfd53f..d49d8588 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -234,7 +234,8 @@ class TextFormat::Parser::ParserImpl { bool allow_unknown_field, bool allow_unknown_enum, bool allow_field_number, - bool allow_relaxed_whitespace) + bool allow_relaxed_whitespace, + bool allow_partial) : error_collector_(error_collector), finder_(finder), parse_info_tree_(parse_info_tree), @@ -246,6 +247,7 @@ class TextFormat::Parser::ParserImpl { allow_unknown_field_(allow_unknown_field), allow_unknown_enum_(allow_unknown_enum), allow_field_number_(allow_field_number), + allow_partial_(allow_partial), had_errors_(false) { // For backwards-compatibility with proto1, we need to allow the 'f' suffix // for floats. @@ -718,7 +720,8 @@ class TextFormat::Parser::ParserImpl { value = SimpleItoa(int_value); // for error reporting enum_value = enum_type->FindValueByNumber(int_value); } else { - ReportError("Expected integer or identifier."); + ReportError("Expected integer or identifier, got: " + + tokenizer_.current().text); return false; } @@ -831,7 +834,7 @@ class TextFormat::Parser::ParserImpl { return true; } - ReportError("Expected identifier."); + ReportError("Expected identifier, got: " + tokenizer_.current().text); return false; } @@ -851,7 +854,7 @@ class TextFormat::Parser::ParserImpl { // Returns false if the token is not of type STRING. bool ConsumeString(string* text) { if (!LookingAtType(io::Tokenizer::TYPE_STRING)) { - ReportError("Expected string."); + ReportError("Expected string, got: " + tokenizer_.current().text); return false; } @@ -869,13 +872,13 @@ class TextFormat::Parser::ParserImpl { // Returns false if the token is not of type INTEGER. bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) { if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { - ReportError("Expected integer."); + ReportError("Expected integer, got: " + tokenizer_.current().text); return false; } if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, max_value, value)) { - ReportError("Integer out of range."); + ReportError("Integer out of range (" + tokenizer_.current().text + ")"); return false; } @@ -902,10 +905,14 @@ class TextFormat::Parser::ParserImpl { DO(ConsumeUnsignedInteger(&unsigned_value, max_value)); - *value = static_cast(unsigned_value); - if (negative) { - *value = -*value; + if ((static_cast(kint64max) + 1) == unsigned_value) { + *value = kint64min; + } else { + *value = -static_cast(unsigned_value); + } + } else { + *value = static_cast(unsigned_value); } return true; @@ -915,18 +922,18 @@ class TextFormat::Parser::ParserImpl { // Accepts decimal numbers only, rejects hex or oct numbers. bool ConsumeUnsignedDecimalInteger(uint64* value, uint64 max_value) { if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { - ReportError("Expected integer."); + ReportError("Expected integer, got: " + tokenizer_.current().text); return false; } const string& text = tokenizer_.current().text; if (IsHexNumber(text) || IsOctNumber(text)) { - ReportError("Expect a decimal number."); + ReportError("Expect a decimal number, got: " + text); return false; } if (!io::Tokenizer::ParseInteger(text, max_value, value)) { - ReportError("Integer out of range."); + ReportError("Integer out of range (" + text + ")"); return false; } @@ -971,11 +978,11 @@ class TextFormat::Parser::ParserImpl { *value = std::numeric_limits::quiet_NaN(); tokenizer_.Next(); } else { - ReportError("Expected double."); + ReportError("Expected double, got: " + text); return false; } } else { - ReportError("Expected double."); + ReportError("Expected double, got: " + tokenizer_.current().text); return false; } @@ -1033,7 +1040,17 @@ class TextFormat::Parser::ParserImpl { DO(ConsumeMessageDelimiter(&sub_delimiter)); DO(ConsumeMessage(value.get(), sub_delimiter)); - value->AppendToString(serialized_value); + if (allow_partial_) { + value->AppendPartialToString(serialized_value); + } else { + if (!value->IsInitialized()) { + ReportError( + "Value of type \"" + full_type_name + + "\" stored in google.protobuf.Any has missing required fields"); + return false; + } + value->AppendToString(serialized_value); + } return true; } @@ -1098,6 +1115,7 @@ class TextFormat::Parser::ParserImpl { const bool allow_unknown_field_; const bool allow_unknown_enum_; const bool allow_field_number_; + const bool allow_partial_; bool had_errors_; }; @@ -1259,7 +1277,7 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, overwrites_policy, allow_case_insensitive_field_, allow_unknown_field_, allow_unknown_enum_, allow_field_number_, - allow_relaxed_whitespace_); + allow_relaxed_whitespace_, allow_partial_); return MergeUsingImpl(input, output, &parser); } @@ -1276,7 +1294,7 @@ bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, ParserImpl::ALLOW_SINGULAR_OVERWRITES, allow_case_insensitive_field_, allow_unknown_field_, allow_unknown_enum_, allow_field_number_, - allow_relaxed_whitespace_); + allow_relaxed_whitespace_, allow_partial_); return MergeUsingImpl(input, output, &parser); } @@ -1310,7 +1328,7 @@ bool TextFormat::Parser::ParseFieldValueFromString( ParserImpl::ALLOW_SINGULAR_OVERWRITES, allow_case_insensitive_field_, allow_unknown_field_, allow_unknown_enum_, allow_field_number_, - allow_relaxed_whitespace_); + allow_relaxed_whitespace_, allow_partial_); return parser.ParseField(field, output); } diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 410e5480..c9521cc3 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -1196,11 +1196,13 @@ TEST_F(TextFormatParserTest, ParseFieldValueFromString) { TEST_F(TextFormatParserTest, InvalidToken) { - ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.", + ExpectFailure("optional_bool: true\n-5\n", "Expected identifier, got: -", 2, 1); - ExpectFailure("optional_bool: true!\n", "Expected identifier.", 1, 20); - ExpectFailure("\"some string\"", "Expected identifier.", 1, 1); + ExpectFailure("optional_bool: true!\n", "Expected identifier, got: !", 1, + 20); + ExpectFailure("\"some string\"", + "Expected identifier, got: \"some string\"", 1, 1); } TEST_F(TextFormatParserTest, InvalidFieldName) { @@ -1248,46 +1250,52 @@ TEST_F(TextFormatParserTest, AllowIgnoreCapitalizationError) { TEST_F(TextFormatParserTest, InvalidFieldValues) { // Invalid values for a double/float field. - ExpectFailure("optional_double: \"hello\"\n", "Expected double.", 1, 18); - ExpectFailure("optional_double: true\n", "Expected double.", 1, 18); - ExpectFailure("optional_double: !\n", "Expected double.", 1, 18); + ExpectFailure("optional_double: \"hello\"\n", + "Expected double, got: \"hello\"", 1, 18); + ExpectFailure("optional_double: true\n", "Expected double, got: true", 1, + 18); + ExpectFailure("optional_double: !\n", "Expected double, got: !", 1, 18); ExpectFailure("optional_double {\n \n}\n", "Expected \":\", found \"{\".", 1, 17); // Invalid values for a signed integer field. - ExpectFailure("optional_int32: \"hello\"\n", "Expected integer.", 1, 17); - ExpectFailure("optional_int32: true\n", "Expected integer.", 1, 17); - ExpectFailure("optional_int32: 4.5\n", "Expected integer.", 1, 17); - ExpectFailure("optional_int32: !\n", "Expected integer.", 1, 17); + ExpectFailure("optional_int32: \"hello\"\n", + "Expected integer, got: \"hello\"", 1, 17); + ExpectFailure("optional_int32: true\n", "Expected integer, got: true", 1, 17); + ExpectFailure("optional_int32: 4.5\n", "Expected integer, got: 4.5", 1, 17); + ExpectFailure("optional_int32: !\n", "Expected integer, got: !", 1, 17); ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".", 1, 16); ExpectFailure("optional_int32: 0x80000000\n", - "Integer out of range.", 1, 17); + "Integer out of range (0x80000000)", 1, 17); ExpectFailure("optional_int64: 0x8000000000000000\n", - "Integer out of range.", 1, 17); + "Integer out of range (0x8000000000000000)", 1, 17); ExpectFailure("optional_int32: -0x80000001\n", - "Integer out of range.", 1, 18); + "Integer out of range (0x80000001)", 1, 18); ExpectFailure("optional_int64: -0x8000000000000001\n", - "Integer out of range.", 1, 18); + "Integer out of range (0x8000000000000001)", 1, 18); // Invalid values for an unsigned integer field. - ExpectFailure("optional_uint64: \"hello\"\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64: true\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64: 4.5\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64: -5\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64: !\n", "Expected integer.", 1, 18); + ExpectFailure("optional_uint64: \"hello\"\n", + "Expected integer, got: \"hello\"", 1, 18); + ExpectFailure("optional_uint64: true\n", + "Expected integer, got: true", 1, 18); + ExpectFailure("optional_uint64: 4.5\n", "Expected integer, got: 4.5", 1, 18); + ExpectFailure("optional_uint64: -5\n", "Expected integer, got: -", 1, 18); + ExpectFailure("optional_uint64: !\n", "Expected integer, got: !", 1, 18); ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".", 1, 17); ExpectFailure("optional_uint32: 0x100000000\n", - "Integer out of range.", 1, 18); + "Integer out of range (0x100000000)", 1, 18); ExpectFailure("optional_uint64: 0x10000000000000000\n", - "Integer out of range.", 1, 18); + "Integer out of range (0x10000000000000000)", 1, 18); // Invalid values for a boolean field. - ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16); - ExpectFailure("optional_bool: 5\n", "Integer out of range.", 1, 16); - ExpectFailure("optional_bool: -7.5\n", "Expected identifier.", 1, 16); - ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16); + ExpectFailure("optional_bool: \"hello\"\n", + "Expected identifier, got: \"hello\"", 1, 16); + ExpectFailure("optional_bool: 5\n", "Integer out of range (5)", 1, 16); + ExpectFailure("optional_bool: -7.5\n", "Expected identifier, got: -", 1, 16); + ExpectFailure("optional_bool: !\n", "Expected identifier, got: !", 1, 16); ExpectFailure( "optional_bool: meh\n", @@ -1298,16 +1306,16 @@ TEST_F(TextFormatParserTest, InvalidFieldValues) { 1, 15); // Invalid values for a string field. - ExpectFailure("optional_string: true\n", "Expected string.", 1, 18); - ExpectFailure("optional_string: 5\n", "Expected string.", 1, 18); - ExpectFailure("optional_string: -7.5\n", "Expected string.", 1, 18); - ExpectFailure("optional_string: !\n", "Expected string.", 1, 18); + ExpectFailure("optional_string: true\n", "Expected string, got: true", 1, 18); + ExpectFailure("optional_string: 5\n", "Expected string, got: 5", 1, 18); + ExpectFailure("optional_string: -7.5\n", "Expected string, got: -", 1, 18); + ExpectFailure("optional_string: !\n", "Expected string, got: !", 1, 18); ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".", 1, 17); // Invalid values for an enumeration field. ExpectFailure("optional_nested_enum: \"hello\"\n", - "Expected integer or identifier.", 1, 23); + "Expected integer or identifier, got: \"hello\"", 1, 23); // Valid token, but enum value is not defined. ExpectFailure("optional_nested_enum: 5\n", @@ -1315,9 +1323,10 @@ TEST_F(TextFormatParserTest, InvalidFieldValues) { "\"optional_nested_enum\".", 2, 1); // We consume the negative sign, so the error position starts one character // later. - ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer.", 1, 24); + ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer, got: 7.5", 1, + 24); ExpectFailure("optional_nested_enum: !\n", - "Expected integer or identifier.", 1, 23); + "Expected integer or identifier, got: !", 1, 23); ExpectFailure( "optional_nested_enum: grah\n", @@ -1340,7 +1349,7 @@ TEST_F(TextFormatParserTest, MessageDelimiters) { // Unending message. ExpectFailure("optional_nested_message {\n \nbb: 118\n", - "Expected identifier.", + "Expected identifier, got: ", 4, 1); } diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index 7cdf5093..2ec4bc56 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc @@ -293,8 +293,8 @@ void Timestamp::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Timestamp) } -::google::protobuf::uint8* Timestamp::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Timestamp::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Timestamp) // optional int64 seconds = 1; if (this->seconds() != 0) { diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index 7bf62597..19f4f86f 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h @@ -41,7 +41,7 @@ class Timestamp; // =================================================================== -class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Timestamp) */ { public: Timestamp(); virtual ~Timestamp(); @@ -80,7 +80,11 @@ class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index 759cab27..f9182a75 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -548,8 +548,8 @@ void Type::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Type) } -::google::protobuf::uint8* Type::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Type::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Type) // optional string name = 1; if (this->name().size() > 0) { @@ -565,8 +565,8 @@ void Type::SerializeWithCachedSizes( // repeated .google.protobuf.Field fields = 2; for (unsigned int i = 0, n = this->fields_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, this->fields(i), target); + InternalWriteMessageNoVirtualToArray( + 2, this->fields(i), false, target); } // repeated string oneofs = 3; @@ -582,15 +582,15 @@ void Type::SerializeWithCachedSizes( // repeated .google.protobuf.Option options = 4; for (unsigned int i = 0, n = this->options_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 4, this->options(i), target); + InternalWriteMessageNoVirtualToArray( + 4, this->options(i), false, target); } // optional .google.protobuf.SourceContext source_context = 5; if (this->has_source_context()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, *this->source_context_, target); + InternalWriteMessageNoVirtualToArray( + 5, *this->source_context_, false, target); } // optional .google.protobuf.Syntax syntax = 6; @@ -1417,8 +1417,8 @@ void Field::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Field) } -::google::protobuf::uint8* Field::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Field::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Field) // optional .google.protobuf.Field.Kind kind = 1; if (this->kind() != 0) { @@ -1472,8 +1472,8 @@ void Field::SerializeWithCachedSizes( // repeated .google.protobuf.Option options = 9; for (unsigned int i = 0, n = this->options_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 9, this->options(i), target); + InternalWriteMessageNoVirtualToArray( + 9, this->options(i), false, target); } // optional string json_name = 10; @@ -2192,8 +2192,8 @@ void Enum::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Enum) } -::google::protobuf::uint8* Enum::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Enum::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Enum) // optional string name = 1; if (this->name().size() > 0) { @@ -2209,22 +2209,22 @@ void Enum::SerializeWithCachedSizes( // repeated .google.protobuf.EnumValue enumvalue = 2; for (unsigned int i = 0, n = this->enumvalue_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, this->enumvalue(i), target); + InternalWriteMessageNoVirtualToArray( + 2, this->enumvalue(i), false, target); } // repeated .google.protobuf.Option options = 3; for (unsigned int i = 0, n = this->options_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 3, this->options(i), target); + InternalWriteMessageNoVirtualToArray( + 3, this->options(i), false, target); } // optional .google.protobuf.SourceContext source_context = 4; if (this->has_source_context()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 4, *this->source_context_, target); + InternalWriteMessageNoVirtualToArray( + 4, *this->source_context_, false, target); } // optional .google.protobuf.Syntax syntax = 5; @@ -2700,8 +2700,8 @@ void EnumValue::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValue) } -::google::protobuf::uint8* EnumValue::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* EnumValue::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValue) // optional string name = 1; if (this->name().size() > 0) { @@ -2722,8 +2722,8 @@ void EnumValue::SerializeWithCachedSizes( // repeated .google.protobuf.Option options = 3; for (unsigned int i = 0, n = this->options_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 3, this->options(i), target); + InternalWriteMessageNoVirtualToArray( + 3, this->options(i), false, target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValue) @@ -3082,8 +3082,8 @@ void Option::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Option) } -::google::protobuf::uint8* Option::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Option::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Option) // optional string name = 1; if (this->name().size() > 0) { @@ -3099,8 +3099,8 @@ void Option::SerializeWithCachedSizes( // optional .google.protobuf.Any value = 2; if (this->has_value()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, *this->value_, target); + InternalWriteMessageNoVirtualToArray( + 2, *this->value_, false, target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Option) diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index 4255fa8c..ce29c281 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h @@ -130,7 +130,7 @@ inline bool Syntax_Parse( } // =================================================================== -class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Type) */ { public: Type(); virtual ~Type(); @@ -164,7 +164,11 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -273,7 +277,7 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Field) */ { public: Field(); virtual ~Field(); @@ -307,7 +311,11 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -530,7 +538,7 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Enum) */ { public: Enum(); virtual ~Enum(); @@ -564,7 +572,11 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -656,7 +668,7 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValue) */ { public: EnumValue(); virtual ~EnumValue(); @@ -690,7 +702,11 @@ class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -759,7 +775,7 @@ class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Option) */ { public: Option(); virtual ~Option(); @@ -793,7 +809,11 @@ class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto index da56ae0a..d5206d24 100644 --- a/src/google/protobuf/unittest.proto +++ b/src/google/protobuf/unittest.proto @@ -195,6 +195,7 @@ message TestDeprecatedFields { // that. message ForeignMessage { optional int32 c = 1; + optional int32 d = 2; } enum ForeignEnum { diff --git a/src/google/protobuf/unittest_custom_options.proto b/src/google/protobuf/unittest_custom_options.proto index 4cc0e362..218447e9 100644 --- a/src/google/protobuf/unittest_custom_options.proto +++ b/src/google/protobuf/unittest_custom_options.proto @@ -69,6 +69,10 @@ extend google.protobuf.FieldOptions { optional int32 field_opt2 = 7753913 [default=42]; } +extend google.protobuf.OneofOptions { + optional int32 oneof_opt1 = 7740111; +} + extend google.protobuf.EnumOptions { optional sfixed32 enum_opt1 = 7753576; } @@ -100,6 +104,11 @@ message TestMessageWithCustomOptions { optional string field1 = 1 [ctype=CORD, (field_opt1)=8765432109]; + oneof AnOneof { + option (oneof_opt1) = -99; + int32 oneof_field = 2; + } + enum AnEnum { option (enum_opt1) = -789; diff --git a/src/google/protobuf/util/field_mask_util.cc b/src/google/protobuf/util/field_mask_util.cc index 547c9fb5..409010a0 100644 --- a/src/google/protobuf/util/field_mask_util.cc +++ b/src/google/protobuf/util/field_mask_util.cc @@ -200,6 +200,15 @@ class FieldMaskTree { MergeMessage(&root_, source, options, destination); } + // Trims all fields not specified by this tree from the given message. + void TrimMessage(Message* message) { + // Do nothing if the tree is empty. + if (root_.children.empty()) { + return; + } + TrimMessage(&root_, message); + } + private: struct Node { Node() {} @@ -233,6 +242,9 @@ class FieldMaskTree { const FieldMaskUtil::MergeOptions& options, Message* destination); + // Trims all fields not specified by this sub-tree from the given message. + void TrimMessage(const Node* node, Message* message); + Node root_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldMaskTree); @@ -367,11 +379,15 @@ void FieldMaskTree::MergeMessage(const Node* node, const Message& source, } if (!field->is_repeated()) { switch (field->cpp_type()) { -#define COPY_VALUE(TYPE, Name) \ - case FieldDescriptor::CPPTYPE_##TYPE: { \ - destination_reflection->Set##Name( \ - destination, field, source_reflection->Get##Name(source, field)); \ - break; \ +#define COPY_VALUE(TYPE, Name) \ + case FieldDescriptor::CPPTYPE_##TYPE: { \ + if (source_reflection->HasField(source, field)) { \ + destination_reflection->Set##Name( \ + destination, field, source_reflection->Get##Name(source, field)); \ + } else { \ + destination_reflection->ClearField(destination, field); \ + } \ + break; \ } COPY_VALUE(BOOL, Bool) COPY_VALUE(INT32, Int32) @@ -433,6 +449,26 @@ void FieldMaskTree::MergeMessage(const Node* node, const Message& source, } } +void FieldMaskTree::TrimMessage(const Node* node, Message* message) { + GOOGLE_DCHECK(!node->children.empty()); + const Reflection* reflection = message->GetReflection(); + const Descriptor* descriptor = message->GetDescriptor(); + const int32 field_count = descriptor->field_count(); + for (int index = 0; index < field_count; ++index) { + const FieldDescriptor* field = descriptor->field(index); + if (!ContainsKey(node->children, field->name())) { + reflection->ClearField(message, field); + } else { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + Node* child = node->children.at(field->name()); + if (!child->children.empty()) { + TrimMessage(child, reflection->MutableMessage(message, field)); + } + } + } + } +} + } // namespace void FieldMaskUtil::ToCanonicalForm(const FieldMask& mask, FieldMask* out) { @@ -489,6 +525,14 @@ void FieldMaskUtil::MergeMessageTo(const Message& source, const FieldMask& mask, tree.MergeMessage(source, options, destination); } +void FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* destination) { + // Build a FieldMaskTree and walk through the tree to merge all specified + // fields. + FieldMaskTree tree; + tree.MergeFromFieldMask(mask); + tree.TrimMessage(GOOGLE_CHECK_NOTNULL(destination)); +} + } // namespace util } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/util/field_mask_util.h b/src/google/protobuf/util/field_mask_util.h index 644161b9..e79b65e9 100644 --- a/src/google/protobuf/util/field_mask_util.h +++ b/src/google/protobuf/util/field_mask_util.h @@ -107,10 +107,16 @@ class LIBPROTOBUF_EXPORT FieldMaskUtil { static bool IsPathInFieldMask(StringPiece path, const FieldMask& mask); class MergeOptions; - // Merges fields specified in a FieldMask into another message. + // Merges fields specified in a FieldMask into another message. See the + // comments in MergeOptions regarding compatibility with + // google/protobuf/field_mask.proto static void MergeMessageTo(const Message& source, const FieldMask& mask, const MergeOptions& options, Message* destination); + // Removes from 'message' any field that is not represented in the given + // FieldMask. If the FieldMask is empty, does nothing. + static void TrimMessage(const FieldMask& mask, Message* message); + private: friend class SnakeCaseCamelCaseTest; // Converts a field name from snake_case to camelCase: @@ -148,6 +154,10 @@ class LIBPROTOBUF_EXPORT FieldMaskUtil { FieldMask* out); }; +// Note that for compatibility with the defined behaviour for FieldMask in +// google/protobuf/field_mask.proto, set replace_message_fields and +// replace_repeated_fields to 'true'. The default options are not compatible +// with google/protobuf/field_mask.proto. class LIBPROTOBUF_EXPORT FieldMaskUtil::MergeOptions { public: MergeOptions() diff --git a/src/google/protobuf/util/field_mask_util_test.cc b/src/google/protobuf/util/field_mask_util_test.cc index 9b7fb62a..43fb7905 100644 --- a/src/google/protobuf/util/field_mask_util_test.cc +++ b/src/google/protobuf/util/field_mask_util_test.cc @@ -349,6 +349,10 @@ TEST(FieldMaskUtilTest, MergeMessage) { dst.Clear(); \ FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \ EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \ + src.clear_##field_name(); \ + tmp.clear_##field_name(); \ + FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \ + EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \ } TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int32) TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int64) @@ -484,6 +488,117 @@ TEST(FieldMaskUtilTest, MergeMessage) { EXPECT_EQ(1234, nested_dst.payload().repeated_int32(0)); } +TEST(FieldMaskUtilTest, TrimMessage) { +#define TEST_TRIM_ONE_PRIMITIVE_FIELD(field_name) \ + { \ + TestAllTypes msg; \ + TestUtil::SetAllFields(&msg); \ + TestAllTypes tmp; \ + tmp.set_##field_name(msg.field_name()); \ + FieldMask mask; \ + mask.add_paths(#field_name); \ + FieldMaskUtil::TrimMessage(mask, &msg); \ + EXPECT_EQ(tmp.DebugString(), msg.DebugString()); \ + } + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_int32) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_int64) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_uint32) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_uint64) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sint32) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sint64) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_fixed32) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_fixed64) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sfixed32) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sfixed64) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_float) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_double) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_bool) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_string) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_bytes) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_nested_enum) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_foreign_enum) + TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_import_enum) +#undef TEST_TRIM_ONE_PRIMITIVE_FIELD + +#define TEST_TRIM_ONE_FIELD(field_name) \ + { \ + TestAllTypes msg; \ + TestUtil::SetAllFields(&msg); \ + TestAllTypes tmp; \ + *tmp.mutable_##field_name() = msg.field_name(); \ + FieldMask mask; \ + mask.add_paths(#field_name); \ + FieldMaskUtil::TrimMessage(mask, &msg); \ + EXPECT_EQ(tmp.DebugString(), msg.DebugString()); \ + } + TEST_TRIM_ONE_FIELD(optional_nested_message) + TEST_TRIM_ONE_FIELD(optional_foreign_message) + TEST_TRIM_ONE_FIELD(optional_import_message) + + TEST_TRIM_ONE_FIELD(repeated_int32) + TEST_TRIM_ONE_FIELD(repeated_int64) + TEST_TRIM_ONE_FIELD(repeated_uint32) + TEST_TRIM_ONE_FIELD(repeated_uint64) + TEST_TRIM_ONE_FIELD(repeated_sint32) + TEST_TRIM_ONE_FIELD(repeated_sint64) + TEST_TRIM_ONE_FIELD(repeated_fixed32) + TEST_TRIM_ONE_FIELD(repeated_fixed64) + TEST_TRIM_ONE_FIELD(repeated_sfixed32) + TEST_TRIM_ONE_FIELD(repeated_sfixed64) + TEST_TRIM_ONE_FIELD(repeated_float) + TEST_TRIM_ONE_FIELD(repeated_double) + TEST_TRIM_ONE_FIELD(repeated_bool) + TEST_TRIM_ONE_FIELD(repeated_string) + TEST_TRIM_ONE_FIELD(repeated_bytes) + TEST_TRIM_ONE_FIELD(repeated_nested_message) + TEST_TRIM_ONE_FIELD(repeated_foreign_message) + TEST_TRIM_ONE_FIELD(repeated_import_message) + TEST_TRIM_ONE_FIELD(repeated_nested_enum) + TEST_TRIM_ONE_FIELD(repeated_foreign_enum) + TEST_TRIM_ONE_FIELD(repeated_import_enum) +#undef TEST_TRIM_ONE_FIELD + + // Test trim nested fields. + NestedTestAllTypes nested_msg; + nested_msg.mutable_child()->mutable_payload()->set_optional_int32(1234); + nested_msg.mutable_child() + ->mutable_child() + ->mutable_payload() + ->set_optional_int32(5678); + NestedTestAllTypes trimmed_msg(nested_msg); + FieldMask mask; + FieldMaskUtil::FromString("child.payload", &mask); + FieldMaskUtil::TrimMessage(mask, &trimmed_msg); + EXPECT_EQ(1234, trimmed_msg.child().payload().optional_int32()); + EXPECT_EQ(0, trimmed_msg.child().child().payload().optional_int32()); + + trimmed_msg = nested_msg; + FieldMaskUtil::FromString("child.child.payload", &mask); + FieldMaskUtil::TrimMessage(mask, &trimmed_msg); + EXPECT_EQ(0, trimmed_msg.child().payload().optional_int32()); + EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32()); + + trimmed_msg = nested_msg; + FieldMaskUtil::FromString("child", &mask); + FieldMaskUtil::TrimMessage(mask, &trimmed_msg); + EXPECT_EQ(1234, trimmed_msg.child().payload().optional_int32()); + EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32()); + + trimmed_msg = nested_msg; + FieldMaskUtil::FromString("child.child", &mask); + FieldMaskUtil::TrimMessage(mask, &trimmed_msg); + EXPECT_EQ(0, trimmed_msg.child().payload().optional_int32()); + EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32()); + + // Verify than an empty FieldMask trims nothing + TestAllTypes all_types_msg; + TestUtil::SetAllFields(&all_types_msg); + TestAllTypes trimmed_all_types(all_types_msg); + FieldMask empty_mask; + FieldMaskUtil::TrimMessage(empty_mask, &trimmed_all_types); + EXPECT_EQ(trimmed_all_types.DebugString(), all_types_msg.DebugString()); +} + } // namespace } // namespace util diff --git a/src/google/protobuf/util/internal/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc index 72c0aca6..ef8da427 100644 --- a/src/google/protobuf/util/internal/datapiece.cc +++ b/src/google/protobuf/util/internal/datapiece.cc @@ -329,9 +329,8 @@ bool DataPiece::DecodeBase64(StringPiece src, string* dest) const { // WebSafeBase64Escape does no padding by default. WebSafeBase64Escape(*dest, &encoded); // Remove trailing padding '=' characters before comparison. - StringPiece src_no_padding(src, 0, src.ends_with("=") - ? src.find_last_not_of('=') + 1 - : src.length()); + StringPiece src_no_padding = StringPiece(src).substr( + 0, src.ends_with("=") ? src.find_last_not_of('=') + 1 : src.length()); return encoded == src_no_padding; } return true; @@ -343,9 +342,8 @@ bool DataPiece::DecodeBase64(StringPiece src, string* dest) const { Base64Escape( reinterpret_cast(dest->data()), dest->length(), &encoded, false); - StringPiece src_no_padding(src, 0, src.ends_with("=") - ? src.find_last_not_of('=') + 1 - : src.length()); + StringPiece src_no_padding = StringPiece(src).substr( + 0, src.ends_with("=") ? src.find_last_not_of('=') + 1 : src.length()); return encoded == src_no_padding; } return true; @@ -354,6 +352,26 @@ bool DataPiece::DecodeBase64(StringPiece src, string* dest) const { return false; } +void DataPiece::InternalCopy(const DataPiece& other) { + type_ = other.type_; + switch (type_) { + case TYPE_INT32: + case TYPE_INT64: + case TYPE_UINT32: + case TYPE_UINT64: + case TYPE_DOUBLE: + case TYPE_FLOAT: + case TYPE_BOOL: + case TYPE_ENUM: + case TYPE_NULL: + case TYPE_BYTES: + case TYPE_STRING: { + str_ = other.str_; + break; + } + } +} + } // namespace converter } // namespace util } // namespace protobuf diff --git a/src/google/protobuf/util/internal/datapiece.h b/src/google/protobuf/util/internal/datapiece.h index 8b2e35d3..e82cdbac 100644 --- a/src/google/protobuf/util/internal/datapiece.h +++ b/src/google/protobuf/util/internal/datapiece.h @@ -92,10 +92,11 @@ class LIBPROTOBUF_EXPORT DataPiece { : type_(TYPE_BYTES), str_(StringPiecePod::CreateFromStringPiece(value)), use_strict_base64_decoding_(use_strict_base64_decoding) {} - DataPiece(const DataPiece& r) : type_(r.type_), str_(r.str_) {} + + DataPiece(const DataPiece& r) : type_(r.type_) { InternalCopy(r); } + DataPiece& operator=(const DataPiece& x) { - type_ = x.type_; - str_ = x.str_; + InternalCopy(x); return *this; } @@ -171,6 +172,9 @@ class LIBPROTOBUF_EXPORT DataPiece { // Decodes a base64 string. Returns true on success. bool DecodeBase64(StringPiece src, string* dest) const; + // Helper function to initialize this DataPiece with 'other'. + void InternalCopy(const DataPiece& other); + // Data type for this piece of data. Type type_; diff --git a/src/google/protobuf/util/internal/json_escaping.cc b/src/google/protobuf/util/internal/json_escaping.cc index 24bd554e..06d2791b 100644 --- a/src/google/protobuf/util/internal/json_escaping.cc +++ b/src/google/protobuf/util/internal/json_escaping.cc @@ -255,7 +255,7 @@ StringPiece ToHex(uint16 cp, char* buffer) { buffer[3] = kHex[cp & 0x0f]; cp >>= 4; buffer[2] = kHex[cp & 0x0f]; - return StringPiece(buffer, 0, 6); + return StringPiece(buffer).substr(0, 6); } // Stores the 32-bit unicode code point as its hexadecimal digits in buffer diff --git a/src/google/protobuf/util/internal/object_writer.h b/src/google/protobuf/util/internal/object_writer.h index 9f07363d..5781aa1e 100644 --- a/src/google/protobuf/util/internal/object_writer.h +++ b/src/google/protobuf/util/internal/object_writer.h @@ -101,6 +101,7 @@ class LIBPROTOBUF_EXPORT ObjectWriter { // Renders a Null value. virtual ObjectWriter* RenderNull(StringPiece name) = 0; + // Renders a DataPiece object to a ObjectWriter. static void RenderDataPieceTo(const DataPiece& data, StringPiece name, ObjectWriter* ow); diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc index 36b79410..18cc1233 100644 --- a/src/google/protobuf/util/internal/proto_writer.cc +++ b/src/google/protobuf/util/internal/proto_writer.cc @@ -293,10 +293,14 @@ ProtoWriter::ProtoElement::ProtoElement(const TypeInfo* typeinfo, ow_(enclosing), parent_field_(NULL), typeinfo_(typeinfo), + proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3), type_(type), - required_fields_(GetRequiredFields(type)), size_index_(-1), - array_index_(-1) {} + array_index_(-1) { + if (!proto3_) { + required_fields_ = GetRequiredFields(type_); + } +} ProtoWriter::ProtoElement::ProtoElement(ProtoWriter::ProtoElement* parent, const google::protobuf::Field* field, @@ -306,6 +310,7 @@ ProtoWriter::ProtoElement::ProtoElement(ProtoWriter::ProtoElement* parent, ow_(this->parent()->ow_), parent_field_(field), typeinfo_(this->parent()->typeinfo_), + proto3_(this->parent()->proto3_), type_(type), size_index_( !is_list && field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE @@ -316,12 +321,15 @@ ProtoWriter::ProtoElement::ProtoElement(ProtoWriter::ProtoElement* parent, if (ow_->IsRepeated(*field)) { // Update array_index_ if it is an explicit list. if (this->parent()->array_index_ >= 0) this->parent()->array_index_++; - } else { + } else if (!proto3_) { + // For required fields tracking. this->parent()->RegisterField(field); } if (field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE) { - required_fields_ = GetRequiredFields(type_); + if (!proto3_) { + required_fields_ = GetRequiredFields(type_); + } int start_pos = ow_->stream_->ByteCount(); // length of serialized message is the final buffer position minus // starting buffer position, plus length adjustments for size fields @@ -334,12 +342,14 @@ ProtoWriter::ProtoElement::ProtoElement(ProtoWriter::ProtoElement* parent, } ProtoWriter::ProtoElement* ProtoWriter::ProtoElement::pop() { - // Calls the registered error listener for any required field(s) not yet - // seen. - for (set::iterator it = - required_fields_.begin(); - it != required_fields_.end(); ++it) { - ow_->MissingField((*it)->name()); + if (!proto3_) { + // Calls the registered error listener for any required field(s) not yet + // seen. + for (set::iterator it = + required_fields_.begin(); + it != required_fields_.end(); ++it) { + ow_->MissingField((*it)->name()); + } } // Computes the total number of proto bytes used by a message, also adjusts // the size of all parent messages by the length of this size field. diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h index 957565e7..ffb8f60e 100644 --- a/src/google/protobuf/util/internal/proto_writer.h +++ b/src/google/protobuf/util/internal/proto_writer.h @@ -117,6 +117,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { return RenderDataPiece(name, DataPiece::NullData()); } + // Renders a DataPiece 'value' into a field whose wire type is determined // from the given field 'name'. virtual ProtoWriter* RenderDataPiece(StringPiece name, @@ -198,6 +199,9 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { // TypeInfo to lookup types. const TypeInfo* typeinfo_; + // Whether the root type is a proto3 or not. + bool proto3_; + // Additional variables if this element is a message: // (Root element is always a message). // type_ : the type of this element. diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc index 1f3781a4..0048d75b 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -121,7 +121,8 @@ ProtoStreamObjectSource::ProtoStreamObjectSource( type_(type), use_lower_camel_for_enums_(false), recursion_depth_(0), - max_recursion_depth_(kDefaultMaxRecursionDepth) { + max_recursion_depth_(kDefaultMaxRecursionDepth), + render_unknown_fields_(false) { GOOGLE_LOG_IF(DFATAL, stream == NULL) << "Input stream is NULL."; } @@ -134,7 +135,8 @@ ProtoStreamObjectSource::ProtoStreamObjectSource( type_(type), use_lower_camel_for_enums_(false), recursion_depth_(0), - max_recursion_depth_(kDefaultMaxRecursionDepth) { + max_recursion_depth_(kDefaultMaxRecursionDepth), + render_unknown_fields_(false) { GOOGLE_LOG_IF(DFATAL, stream == NULL) << "Input stream is NULL."; } @@ -184,6 +186,7 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, string field_name; // last_tag set to dummy value that is different from tag. uint32 tag = stream_->ReadTag(), last_tag = tag + 1; + google::protobuf::UnknownFieldSet unknown_fields; if (include_start_and_end) { ow->StartObject(name); @@ -199,7 +202,8 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, if (field == NULL) { // If we didn't find a field, skip this unknown tag. // TODO(wpoon): Check return boolean value. - WireFormat::SkipField(stream_, tag, NULL); + WireFormat::SkipField(stream_, tag, + render_unknown_fields_ ? &unknown_fields : NULL); tag = stream_->ReadTag(); continue; } @@ -221,6 +225,8 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, tag = stream_->ReadTag(); } } + + if (include_start_and_end) { ow->EndObject(); } diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h index d7d4347b..243f85b2 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.h +++ b/src/google/protobuf/util/internal/protostream_objectsource.h @@ -117,6 +117,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { max_recursion_depth_ = max_depth; } + protected: // Writes a proto2 Message to the ObjectWriter. When the given end_tag is // found this method will complete, allowing it to be used for parsing both @@ -287,6 +288,9 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { // Maximum allowed recursion depth. int max_recursion_depth_; + // Whether to render unknown fields. + bool render_unknown_fields_; + GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoStreamObjectSource); }; diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc index 97a7909a..8fa58a6f 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc @@ -384,6 +384,9 @@ ProtoStreamObjectWriter::Item::Item(ProtoStreamObjectWriter* enclosing, if (item_type_ == ANY) { any_.reset(new AnyWriter(ow_)); } + if (item_type == MAP) { + map_keys_.reset(new hash_set); + } } ProtoStreamObjectWriter::Item::Item(ProtoStreamObjectWriter::Item* parent, @@ -398,11 +401,14 @@ ProtoStreamObjectWriter::Item::Item(ProtoStreamObjectWriter::Item* parent, if (item_type == ANY) { any_.reset(new AnyWriter(ow_)); } + if (item_type == MAP) { + map_keys_.reset(new hash_set); + } } bool ProtoStreamObjectWriter::Item::InsertMapKeyIfNotPresent( StringPiece map_key) { - return InsertIfNotPresent(&map_keys_, map_key.ToString()); + return InsertIfNotPresent(map_keys_.get(), map_key.ToString()); } ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( @@ -1000,6 +1006,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece( DataPiece(name, use_strict_base64_decoding())); field = Lookup("value"); if (field == NULL) { + Pop(); GOOGLE_LOG(DFATAL) << "Map does not have a value field."; return this; } diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h index e1162d43..75e3d67d 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.h +++ b/src/google/protobuf/util/internal/protostream_objectwriter.h @@ -231,7 +231,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { // Set of map keys already seen for the type_. Used to validate incoming // messages so no map key appears more than once. - hash_set map_keys_; + google::protobuf::scoped_ptr > map_keys_; // Conveys whether this Item is a placeholder or not. Placeholder items are // pushed to stack to account for special types. @@ -249,19 +249,19 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { strings::ByteSink* output, ErrorListener* listener); // Returns true if the field is a map. - bool IsMap(const google::protobuf::Field& field); + inline bool IsMap(const google::protobuf::Field& field); // Returns true if the field is an any. - bool IsAny(const google::protobuf::Field& field); + inline bool IsAny(const google::protobuf::Field& field); // Returns true if the field is google.protobuf.Struct. - bool IsStruct(const google::protobuf::Field& field); + inline bool IsStruct(const google::protobuf::Field& field); // Returns true if the field is google.protobuf.Value. - bool IsStructValue(const google::protobuf::Field& field); + inline bool IsStructValue(const google::protobuf::Field& field); // Returns true if the field is google.protobuf.ListValue. - bool IsStructListValue(const google::protobuf::Field& field); + inline bool IsStructListValue(const google::protobuf::Field& field); // Renders google.protobuf.Value in struct.proto. It picks the right oneof // type based on value's type. diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc index ee7a51fc..5f613e77 100644 --- a/src/google/protobuf/util/internal/utility.cc +++ b/src/google/protobuf/util/internal/utility.cc @@ -52,7 +52,7 @@ const StringPiece SkipWhiteSpace(StringPiece str) { for (i = 0; i < str.size() && isspace(str[i]); ++i) { } GOOGLE_DCHECK(i == str.size() || !isspace(str[i])); - return StringPiece(str, i); + return str.substr(i); } } // namespace @@ -128,8 +128,12 @@ string GetStringFromAny(const google::protobuf::Any& any) { } const StringPiece GetTypeWithoutUrl(StringPiece type_url) { - size_t idx = type_url.rfind('/'); - return type_url.substr(idx + 1); + if (type_url.size() > kTypeUrlSize && type_url[kTypeUrlSize] == '/') { + return type_url.substr(kTypeUrlSize + 1); + } else { + size_t idx = type_url.rfind('/'); + return type_url.substr(idx + 1); + } } const string GetFullTypeWithUrl(StringPiece simple_type) { diff --git a/src/google/protobuf/util/internal/utility.h b/src/google/protobuf/util/internal/utility.h index 33df8eda..26fed444 100644 --- a/src/google/protobuf/util/internal/utility.h +++ b/src/google/protobuf/util/internal/utility.h @@ -64,6 +64,10 @@ class EnumValue; namespace protobuf { namespace util { namespace converter { + +// Size of "type.googleapis.com" +static const int64 kTypeUrlSize = 19; + // Finds the tech option identified by option_name. Parses the boolean value and // returns it. // When the option with the given name is not found, default_value is returned. diff --git a/src/google/protobuf/util/json_format_proto3.proto b/src/google/protobuf/util/json_format_proto3.proto index a1e24c18..3835b30e 100644 --- a/src/google/protobuf/util/json_format_proto3.proto +++ b/src/google/protobuf/util/json_format_proto3.proto @@ -39,6 +39,7 @@ import "google/protobuf/wrappers.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/any.proto"; import "google/protobuf/field_mask.proto"; +import "google/protobuf/unittest.proto"; enum EnumType { FOO = 0; @@ -174,3 +175,7 @@ message TestBoolValue { message TestCustomJsonName { int32 value = 1 [json_name = "@value"]; } + +message TestExtensions { + .protobuf_unittest.TestAllExtensions extensions = 1; +} diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index fe8119bf..fc55c2b9 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -474,7 +474,10 @@ bool MessageDifferencer::Compare( // Retrieve all the set fields, including extensions. vector message1_fields; + message1_fields.reserve(1 + message1.GetDescriptor()->field_count()); + vector message2_fields; + message2_fields.reserve(1 + message2.GetDescriptor()->field_count()); reflection1->ListFields(message1, &message1_fields); reflection2->ListFields(message2, &message2_fields); diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h index 3ea74e67..1abbfcba 100644 --- a/src/google/protobuf/util/message_differencer.h +++ b/src/google/protobuf/util/message_differencer.h @@ -570,6 +570,12 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { // any differences found in human-readable form to the supplied // ZeroCopyOutputStream or Printer. If a printer is used, the delimiter // *must* be '$'. + // + // WARNING: this reporter does not necessarily flush its output until it is + // destroyed. As a result, it is not safe to assume the output is valid or + // complete until after you destroy the reporter. For example, if you use a + // StreamReporter to write to a StringOutputStream, the target string may + // contain uninitialized data until the reporter is destroyed. class LIBPROTOBUF_EXPORT StreamReporter : public Reporter { public: explicit StreamReporter(io::ZeroCopyOutputStream* output); diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h index 55fc7ecd..580d4db0 100644 --- a/src/google/protobuf/wire_format_lite.h +++ b/src/google/protobuf/wire_format_lite.h @@ -457,20 +457,48 @@ class LIBPROTOBUF_EXPORT WireFormatLite { INL static uint8* WriteBytesToArray( field_number, const string& value, output); - INL static uint8* WriteGroupToArray( - field_number, const MessageLite& value, output); - INL static uint8* WriteMessageToArray( - field_number, const MessageLite& value, output); + // Whether to serialize deterministically (e.g., map keys are + // sorted) is a property of a CodedOutputStream, and in the process + // of serialization, the "ToArray" variants may be invoked. But they don't + // have a CodedOutputStream available, so they get an additional parameter + // telling them whether to serialize deterministically. + INL static uint8* InternalWriteGroupToArray( + field_number, const MessageLite& value, bool deterministic, output); + INL static uint8* InternalWriteMessageToArray( + field_number, const MessageLite& value, bool deterministic, output); // 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 + INL static uint8* InternalWriteGroupNoVirtualToArray( + field_number, const MessageType& value, bool deterministic, output); + template + INL static uint8* InternalWriteMessageNoVirtualToArray( + field_number, const MessageType& value, bool deterministic, output); + + // For backward-compatibility, the last four methods also have versions + // that are non-deterministic always. + INL static uint8* WriteGroupToArray( + field_number, const MessageLite& value, output) { + return InternalWriteGroupToArray(field_number_arg, value, false, target); + } + INL static uint8* WriteMessageToArray( + field_number, const MessageLite& value, output) { + return InternalWriteMessageToArray(field_number_arg, value, false, target); + } + template INL static uint8* WriteGroupNoVirtualToArray( - field_number, const MessageType& value, output); + field_number, const MessageType& value, output) { + return InternalWriteGroupNoVirtualToArray(field_number_arg, value, false, + target); + } template INL static uint8* WriteMessageNoVirtualToArray( - field_number, const MessageType& value, output); + field_number, const MessageType& value, output) { + return InternalWriteMessageNoVirtualToArray(field_number_arg, value, false, + target); + } #undef output #undef input diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h index 7bce21cf..ebd858ff 100644 --- a/src/google/protobuf/wire_format_lite_inl.h +++ b/src/google/protobuf/wire_format_lite_inl.h @@ -329,8 +329,8 @@ bool WireFormatLite::ReadRepeatedPrimitiveNoInline( template inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input, RepeatedField* values) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; + int length; + if (!input->ReadVarintSizeAsInt(&length)) return false; io::CodedInputStream::Limit limit = input->PushLimit(length); while (input->BytesUntilLimit() > 0) { CType value; @@ -344,8 +344,8 @@ inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input, template inline bool WireFormatLite::ReadPackedFixedSizePrimitive( io::CodedInputStream* input, RepeatedField* values) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; + int length; + if (!input->ReadVarintSizeAsInt(&length)) return false; const uint32 old_entries = values->size(); const uint32 new_entries = length / sizeof(CType); const uint32 new_bytes = new_entries * sizeof(CType); @@ -443,8 +443,8 @@ inline bool WireFormatLite::ReadGroup(int field_number, } inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, MessageLite* value) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; + int length; + if (!input->ReadVarintSizeAsInt(&length)) return false; std::pair p = input->IncrementRecursionDepthAndPushLimit(length); if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false; @@ -489,8 +489,8 @@ inline bool WireFormatLite::ReadGroupNoVirtualNoRecursionDepth( template inline bool WireFormatLite::ReadMessageNoVirtual( io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; + int length; + if (!input->ReadVarintSizeAsInt(&length)) return false; std::pair p = input->IncrementRecursionDepthAndPushLimit(length); if (p.second < 0 || !value-> @@ -772,42 +772,40 @@ inline uint8* WireFormatLite::WriteBytesToArray(int field_number, } -inline uint8* WireFormatLite::WriteGroupToArray(int field_number, - const MessageLite& value, - uint8* target) { +inline uint8* WireFormatLite::InternalWriteGroupToArray( + int field_number, const MessageLite& value, bool deterministic, + uint8* target) { target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); - target = value.SerializeWithCachedSizesToArray(target); + target = value.InternalSerializeWithCachedSizesToArray(deterministic, target); return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); } -inline uint8* WireFormatLite::WriteMessageToArray(int field_number, - const MessageLite& value, - uint8* target) { +inline uint8* WireFormatLite::InternalWriteMessageToArray( + int field_number, const MessageLite& value, bool deterministic, + uint8* target) { target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); target = io::CodedOutputStream::WriteVarint32ToArray( value.GetCachedSize(), target); - return value.SerializeWithCachedSizesToArray(target); + return value.InternalSerializeWithCachedSizesToArray(deterministic, target); } // See comment on ReadGroupNoVirtual to understand the need for this template // parameter name. template -inline uint8* WireFormatLite::WriteGroupNoVirtualToArray( +inline uint8* WireFormatLite::InternalWriteGroupNoVirtualToArray( int field_number, const MessageType_WorkAroundCppLookupDefect& value, - uint8* target) { + bool deterministic, uint8* target) { target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); - target = value.MessageType_WorkAroundCppLookupDefect - ::SerializeWithCachedSizesToArray(target); + target = value.InternalSerializeWithCachedSizesToArray(deterministic, target); return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); } template -inline uint8* WireFormatLite::WriteMessageNoVirtualToArray( +inline uint8* WireFormatLite::InternalWriteMessageNoVirtualToArray( int field_number, const MessageType_WorkAroundCppLookupDefect& value, - uint8* target) { + bool deterministic, uint8* target) { target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); target = io::CodedOutputStream::WriteVarint32ToArray( value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target); - return value.MessageType_WorkAroundCppLookupDefect - ::SerializeWithCachedSizesToArray(target); + return value.InternalSerializeWithCachedSizesToArray(deterministic, target); } // =================================================================== diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc index 60801423..08490f3f 100644 --- a/src/google/protobuf/wrappers.pb.cc +++ b/src/google/protobuf/wrappers.pb.cc @@ -448,8 +448,8 @@ void DoubleValue::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.DoubleValue) } -::google::protobuf::uint8* DoubleValue::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* DoubleValue::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DoubleValue) // optional double value = 1; if (this->value() != 0) { @@ -706,8 +706,8 @@ void FloatValue::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.FloatValue) } -::google::protobuf::uint8* FloatValue::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* FloatValue::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FloatValue) // optional float value = 1; if (this->value() != 0) { @@ -964,8 +964,8 @@ void Int64Value::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Int64Value) } -::google::protobuf::uint8* Int64Value::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Int64Value::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int64Value) // optional int64 value = 1; if (this->value() != 0) { @@ -1224,8 +1224,8 @@ void UInt64Value::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.UInt64Value) } -::google::protobuf::uint8* UInt64Value::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* UInt64Value::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt64Value) // optional uint64 value = 1; if (this->value() != 0) { @@ -1484,8 +1484,8 @@ void Int32Value::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.Int32Value) } -::google::protobuf::uint8* Int32Value::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* Int32Value::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int32Value) // optional int32 value = 1; if (this->value() != 0) { @@ -1744,8 +1744,8 @@ void UInt32Value::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.UInt32Value) } -::google::protobuf::uint8* UInt32Value::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* UInt32Value::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt32Value) // optional uint32 value = 1; if (this->value() != 0) { @@ -2004,8 +2004,8 @@ void BoolValue::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.BoolValue) } -::google::protobuf::uint8* BoolValue::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* BoolValue::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BoolValue) // optional bool value = 1; if (this->value() != 0) { @@ -2271,8 +2271,8 @@ void StringValue::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.StringValue) } -::google::protobuf::uint8* StringValue::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* StringValue::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.StringValue) // optional string value = 1; if (this->value().size() > 0) { @@ -2590,8 +2590,8 @@ void BytesValue::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:google.protobuf.BytesValue) } -::google::protobuf::uint8* BytesValue::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* BytesValue::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BytesValue) // optional bytes value = 1; if (this->value().size() > 0) { diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h index 10784778..73f8ff62 100644 --- a/src/google/protobuf/wrappers.pb.h +++ b/src/google/protobuf/wrappers.pb.h @@ -49,7 +49,7 @@ class UInt64Value; // =================================================================== -class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DoubleValue) */ { public: DoubleValue(); virtual ~DoubleValue(); @@ -88,7 +88,11 @@ class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -140,7 +144,7 @@ class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FloatValue) */ { public: FloatValue(); virtual ~FloatValue(); @@ -179,7 +183,11 @@ class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -231,7 +239,7 @@ class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int64Value) */ { public: Int64Value(); virtual ~Int64Value(); @@ -270,7 +278,11 @@ class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -322,7 +334,7 @@ class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt64Value) */ { public: UInt64Value(); virtual ~UInt64Value(); @@ -361,7 +373,11 @@ class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -413,7 +429,7 @@ class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int32Value) */ { public: Int32Value(); virtual ~Int32Value(); @@ -452,7 +468,11 @@ class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -504,7 +524,7 @@ class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt32Value) */ { public: UInt32Value(); virtual ~UInt32Value(); @@ -543,7 +563,11 @@ class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -595,7 +619,7 @@ class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BoolValue) */ { public: BoolValue(); virtual ~BoolValue(); @@ -634,7 +658,11 @@ class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -686,7 +714,7 @@ class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.StringValue) */ { public: StringValue(); virtual ~StringValue(); @@ -725,7 +753,11 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -785,7 +817,7 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message { +class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BytesValue) */ { public: BytesValue(); virtual ~BytesValue(); @@ -824,7 +856,11 @@ class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); -- cgit v1.2.3