Add test cases for empty map entries for text format in Python.

This is just part of an effort at locking down (and understand well) how map
entries are serialized into textproto when they have empty fields.

Right now the C++ behaviour for DynamicMessages is that for implicit-presence
(i.e. "proto3") fields, the empty MapEntry fields are not serialized even if
explicitly set. For example, `value: ""` would not show up in textproto
serialization for proto3 MapEntry messages. This contrasts with C++ map
reflection behaviour, because C++ MapEntry messages are always generated with
hasbits (even if they are declared in a proto3 file and have implicit presence
according to their descriptors).

For this Python test, the DynamicMessage fallback path was triggered because
the implementation of the C++ proto was not found. When python is lacking in
implementation, it calls DynamicMessage which respects field presence, even for
map entries. If the corresponding `map_unittest_cc_proto` is linked, this test
actually fails, because the C++ MapEntry implementation, which is always
generated with hasbits even for implicit presence, is used.

PiperOrigin-RevId: 681944020
pull/18606/head
Tony Liao 2 months ago committed by Copybara-Service
parent fa858b82d2
commit d4a32bbc87
  1. 67
      python/google/protobuf/internal/text_format_test.py

@ -1179,6 +1179,73 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
test_util.SetAllFields(message)
self.assertEqual(message, parsed_message)
def testPrintMapEmptyKeys(self):
message = map_unittest_pb2.TestMap()
message.map_int32_int32[0] = 123
message.map_int64_int64[0] = 2**33
message.map_uint32_uint32[0] = 123
message.map_uint64_uint64[0] = 2**33
message.map_string_string[''] = 'world'
message.map_int32_foreign_message[0].c = 111
self.CompareToGoldenText(
text_format.MessageToString(message),
'map_int32_int32 {\n'
' value: 123\n'
'}\n'
'map_int64_int64 {\n'
' value: 8589934592\n'
'}\n'
'map_uint32_uint32 {\n'
' value: 123\n'
'}\n'
'map_uint64_uint64 {\n'
' value: 8589934592\n'
'}\n'
'map_string_string {\n'
' value: "world"\n'
'}\n'
'map_int32_foreign_message {\n'
' value {\n'
' c: 111\n'
' }\n'
'}\n',
)
def testPrintMapEmptyValues(self):
message = map_unittest_pb2.TestMap()
message.map_int32_int32[-123] = 0
message.map_int64_int64[-(2**33)] = 0
message.map_uint32_uint32[123] = 0
message.map_uint64_uint64[2**33] = 0
message.map_string_string['hello'] = ''
message.map_int32_foreign_message[111].c = 0
self.CompareToGoldenText(
text_format.MessageToString(message),
'map_int32_int32 {\n'
' key: -123\n'
'}\n'
'map_int64_int64 {\n'
' key: -8589934592\n'
'}\n'
'map_uint32_uint32 {\n'
' key: 123\n'
'}\n'
'map_uint64_uint64 {\n'
' key: 8589934592\n'
'}\n'
'map_string_string {\n'
' key: "hello"\n'
'}\n'
'map_int32_foreign_message {\n'
' key: 111\n'
' value {\n'
' c: 0\n'
' }\n'
'}\n',
)
def testPrintMap(self):
message = map_unittest_pb2.TestMap()

Loading…
Cancel
Save