|
|
|
@ -77,6 +77,10 @@ void ReflectionOps::Merge(const Message& from, Message* to) { |
|
|
|
|
|
|
|
|
|
const Reflection* from_reflection = GetReflectionOrDie(from); |
|
|
|
|
const Reflection* to_reflection = GetReflectionOrDie(*to); |
|
|
|
|
bool is_from_generated = (from_reflection->GetMessageFactory() == |
|
|
|
|
google::protobuf::MessageFactory::generated_factory()); |
|
|
|
|
bool is_to_generated = (to_reflection->GetMessageFactory() == |
|
|
|
|
google::protobuf::MessageFactory::generated_factory()); |
|
|
|
|
|
|
|
|
|
std::vector<const FieldDescriptor*> fields; |
|
|
|
|
from_reflection->ListFields(from, &fields); |
|
|
|
@ -84,15 +88,17 @@ void ReflectionOps::Merge(const Message& from, Message* to) { |
|
|
|
|
const FieldDescriptor* field = fields[i]; |
|
|
|
|
|
|
|
|
|
if (field->is_repeated()) { |
|
|
|
|
if (field->is_map()) { |
|
|
|
|
MapFieldBase* from_field = |
|
|
|
|
from_reflection->MapData(const_cast<Message*>(&from), field); |
|
|
|
|
// Use map reflection if both are in map status and have the
|
|
|
|
|
// same map type to avoid sync with repeated field.
|
|
|
|
|
// Note: As from and to messages have the same descriptor, the
|
|
|
|
|
// map field types are the same if they are both generated
|
|
|
|
|
// messages or both dynamic messages.
|
|
|
|
|
if (is_from_generated == is_to_generated && field->is_map()) { |
|
|
|
|
const MapFieldBase* from_field = |
|
|
|
|
from_reflection->GetMapData(from, field); |
|
|
|
|
MapFieldBase* to_field = |
|
|
|
|
to_reflection->MapData(const_cast<Message*>(to), field); |
|
|
|
|
// Use map reflection if both are in map status and have the
|
|
|
|
|
// same map type to avoid sync with repeated field.
|
|
|
|
|
if (to_field->IsMapValid() && from_field->IsMapValid() |
|
|
|
|
&& typeid(*from_field) == typeid(*to_field)) { |
|
|
|
|
to_reflection->MutableMapData(to, field); |
|
|
|
|
if (to_field->IsMapValid() && from_field->IsMapValid()) { |
|
|
|
|
to_field->MergeFrom(*from_field); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
@ -189,8 +195,8 @@ bool ReflectionOps::IsInitialized(const Message& message) { |
|
|
|
|
if (field->is_map()) { |
|
|
|
|
const FieldDescriptor* value_field = field->message_type()->field(1); |
|
|
|
|
if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
|
|
|
|
MapFieldBase* map_field = |
|
|
|
|
reflection->MapData(const_cast<Message*>(&message), field); |
|
|
|
|
const MapFieldBase* map_field = |
|
|
|
|
reflection->GetMapData(message, field); |
|
|
|
|
if (map_field->IsMapValid()) { |
|
|
|
|
MapIterator iter(const_cast<Message*>(&message), field); |
|
|
|
|
MapIterator end(const_cast<Message*>(&message), field); |
|
|
|
|