Make python text_format able to skip unknown fields for repeated messages

PiperOrigin-RevId: 742306668
This commit is contained in:
Jie Luo 2025-03-31 10:13:10 -07:00 committed by Copybara-Service
parent ea77a1a88e
commit dcafca2085
2 changed files with 21 additions and 7 deletions

View file

@ -841,6 +841,16 @@ class TextFormatParserTests(TextFormatBase):
self.assertEqual(message.optional_nested_message.bb, 45)
self.assertEqual(message.optional_int32, 123)
def testParseUnknownRepeatedMessage(self, message_module):
message = message_module.TestAllTypes()
text = (
'unknown_repeated: [{}]\n'
'unknown_repeated2: [<>, {}]\n'
'optional_nested_message { bb: 45 }'
)
text_format.Parse(text, message, allow_unknown_field=True)
self.assertEqual(message.optional_nested_message.bb, 45)
def testParseBadEnumValue(self, message_module):
message = message_module.TestAllTypes()
text = 'optional_nested_enum: BARR'

View file

@ -1196,7 +1196,7 @@ class _Parser(object):
':') and not tokenizer.LookingAt('{') and not tokenizer.LookingAt('<'):
self._DetectSilentMarker(tokenizer, immediate_message_type, field_name)
if tokenizer.LookingAt('['):
self._SkipRepeatedFieldValue(tokenizer)
self._SkipRepeatedFieldValue(tokenizer, immediate_message_type)
else:
self._SkipFieldValue(tokenizer)
else:
@ -1271,18 +1271,22 @@ class _Parser(object):
not tokenizer.TryConsumeFloat()):
raise ParseError('Invalid field value: ' + tokenizer.token)
def _SkipRepeatedFieldValue(self, tokenizer):
def _SkipRepeatedFieldValue(self, tokenizer, immediate_message_type):
"""Skips over a repeated field value.
Args:
tokenizer: A tokenizer to parse the field value.
"""
tokenizer.Consume('[')
if not tokenizer.LookingAt(']'):
self._SkipFieldValue(tokenizer)
while tokenizer.TryConsume(','):
self._SkipFieldValue(tokenizer)
tokenizer.Consume(']')
if not tokenizer.TryConsume(']'):
while True:
if tokenizer.LookingAt('<') or tokenizer.LookingAt('{'):
self._SkipFieldMessage(tokenizer, immediate_message_type)
else:
self._SkipFieldValue(tokenizer)
if tokenizer.TryConsume(']'):
break
tokenizer.Consume(',')
class Tokenizer(object):