diff options
author | Feng Xiao <xfxyjwf@gmail.com> | 2015-08-22 18:25:48 -0700 |
---|---|---|
committer | Feng Xiao <xfxyjwf@gmail.com> | 2015-08-22 18:25:48 -0700 |
commit | eee38b0c018b3279f77d03dff796f440f40d3516 (patch) | |
tree | 7ff0978e30238d493fc7899b75abeb6d66939f07 /src/google/protobuf/dynamic_message.cc | |
parent | c3bc155aceda36ecb01cde2367a3b427f2d7ce40 (diff) |
Down-integrate from google3.
Diffstat (limited to 'src/google/protobuf/dynamic_message.cc')
-rw-r--r-- | src/google/protobuf/dynamic_message.cc | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index 318ce6f9..2324d952 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -65,6 +65,7 @@ #include <algorithm> #include <google/protobuf/stubs/hash.h> +#include <google/protobuf/stubs/scoped_ptr.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/dynamic_message.h> @@ -79,6 +80,7 @@ #include <google/protobuf/map_type_handler.h> #include <google/protobuf/extension_set.h> #include <google/protobuf/wire_format.h> +#include <google/protobuf/map_field.h> namespace google { namespace protobuf { @@ -87,7 +89,7 @@ using internal::WireFormat; using internal::ExtensionSet; using internal::GeneratedMessageReflection; using internal::MapField; -using internal::MapFieldBase; +using internal::DynamicMapField; using internal::ArenaStringPtr; @@ -116,7 +118,7 @@ int FieldSpaceUsed(const FieldDescriptor* field) { case FD::CPPTYPE_ENUM : return sizeof(RepeatedField<int >); case FD::CPPTYPE_MESSAGE: if (IsMapFieldInApi(field)) { - return sizeof(MapFieldBase); + return sizeof(DynamicMapField); } else { return sizeof(RepeatedPtrField<Message>); } @@ -389,7 +391,8 @@ void DynamicMessage::SharedCtor() { new(field_ptr) Message*(NULL); } else { if (IsMapFieldInApi(field)) { - new (field_ptr) MapFieldBase(); + new (field_ptr) DynamicMapField( + type_info_->factory->GetPrototypeNoLock(field->message_type())); } else { new (field_ptr) RepeatedPtrField<Message>(); } @@ -437,8 +440,8 @@ DynamicMessage::~DynamicMessage() { &(reinterpret_cast<const ArenaStringPtr*>( type_info_->prototype->OffsetToPointer( type_info_->offsets[i]))->Get(NULL)); - reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(default_value, - NULL); + reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( + default_value, NULL); break; } } @@ -480,7 +483,7 @@ DynamicMessage::~DynamicMessage() { case FieldDescriptor::CPPTYPE_MESSAGE: if (IsMapFieldInApi(field)) { - reinterpret_cast<MapFieldBase*>(field_ptr)->~MapFieldBase(); + reinterpret_cast<DynamicMapField*>(field_ptr)->~DynamicMapField(); } else { reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr) ->~RepeatedPtrField<Message>(); @@ -496,8 +499,8 @@ DynamicMessage::~DynamicMessage() { &(reinterpret_cast<const ArenaStringPtr*>( type_info_->prototype->OffsetToPointer( type_info_->offsets[i]))->Get(NULL)); - reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(default_value, - NULL); + reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( + default_value, NULL); break; } } @@ -723,8 +726,14 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( // Allocate the prototype. void* base = operator new(size); memset(base, 0, size); + // The prototype in type_info has to be set before creating the prototype + // instance on memory. e.g., message Foo { map<int32, Foo> a = 1; }. When + // creating prototype for Foo, prototype of the map entry will also be + // created, which needs the address of the prototype of Foo (the value in + // map). To break the cyclic dependency, we have to assgin the address of + // prototype into type_info first. + type_info->prototype = static_cast<DynamicMessage*>(base); DynamicMessage* prototype = new(base) DynamicMessage(type_info); - type_info->prototype = prototype; // Construct the reflection object. if (type->oneof_decl_count() > 0) { |