Skip to content

mergeFromJsonMap message-field merge behavior is incorrect or inconsistent with other merge methods #726

@osa1

Description

@osa1

When merging a message-field all merge methods (binary, proto3 JSON, merging from another message) recursively merge fields of the message being merged to the message-field.

But mergeFromJsonMap overwrites the message-field. Repro, as a test case added to protoc_plugin/test/merge_test.dart:

  test('nested message merges recursively merges message-fields', () {
    pb.Outer newMessage() => pb.Outer()
      ..inner = (pb.Inner()
        ..value = 'test'
        ..id = Int64(123));

    void checkUpdatedMessage(pb.Outer msg) {
      expect(msg.inner.value, 'test');
      expect(msg.inner.id, Int64(100));
    }

    {
      final msg = newMessage();
      msg.mergeFromBuffer(<int>[
        (4 << 3) | 2, // tag = 4, type = length delimited
        2, // length
        (2 << 3) | 0, // tag = 2, type = varint
        100, // int64 id = 100
      ]);
      checkUpdatedMessage(msg);
    }

    {
      final msg = newMessage();
      msg.mergeFromJsonMap({'4': {'2': 100}});
      checkUpdatedMessage(msg);
    }

    {
      final msg = newMessage();
      msg.mergeFromMessage(pb.Outer()..inner = (pb.Inner()..id = Int64(100)));
      checkUpdatedMessage(msg);
    }

    {
      final msg = newMessage();
      msg.mergeFromProto3Json({'inner': {'id': 100}});
      checkUpdatedMessage(msg);
    }
  });

checkUpdatedMessage after mergeFromJsonMap fails, because mergeFromJsonMap overwrites the inner field and effectively clears inner.value.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions