|
@@ -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);
|