(tokenizer, message)
Merges a single protocol message field into a message.

  Args:
    tokenizer: A tokenizer to parse the field name and values.
    message: A protocol message to record the data.

  Raises:
    ParseError: In case of ASCII parsing problems.
Merges a single protocol message field into a message.
Merges a single protocol message field into a message .
def _MergeField(tokenizer, message):
  """Merges a single protocol message field into a message.

  Args:
    tokenizer: A tokenizer to parse the field name and values.
    message: A protocol message to record the data.

  Raises:
    ParseError: In case of ASCII parsing problems.
  """
  message_descriptor = message.DESCRIPTOR
  if tokenizer.TryConsume('['):
    name = [tokenizer.ConsumeIdentifier()]
    while tokenizer.TryConsume('.'):
      name.append(tokenizer.ConsumeIdentifier())
    name = '.'.join(name)

    if not message_descriptor.is_extendable:
      raise tokenizer.ParseErrorPreviousToken(
          'Message type "%s" does not have extensions.' %
          message_descriptor.full_name)
    field = message.Extensions._FindExtensionByName(name)
    if not field:
      raise tokenizer.ParseErrorPreviousToken(
          'Extension "%s" not registered.' % name)
    elif message_descriptor != field.containing_type:
      raise tokenizer.ParseErrorPreviousToken(
          'Extension "%s" does not extend message type "%s".' % (
              name, message_descriptor.full_name))
    tokenizer.Consume(']')
  else:
    name = tokenizer.ConsumeIdentifier()
    field = message_descriptor.fields_by_name.get(name, None)

    # Group names are expected to be capitalized as they appear in the
    # .proto file, which actually matches their type names, not their field
    # names.
    if not field:
      field = message_descriptor.fields_by_name.get(name.lower(), None)
      if field and field.type != descriptor.FieldDescriptor.TYPE_GROUP:
        field = None

    if (field and field.type == descriptor.FieldDescriptor.TYPE_GROUP and
        field.message_type.name != name):
      field = None

    if not field:
      raise tokenizer.ParseErrorPreviousToken(
          'Message type "%s" has no field named "%s".' % (
              message_descriptor.full_name, name))

  if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
    tokenizer.TryConsume(':')

    if tokenizer.TryConsume('<'):
      end_token = '>'
    else:
      tokenizer.Consume('{')
      end_token = '}'

    if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
      if field.is_extension:
        sub_message = message.Extensions[field].add()
      else:
        sub_message = getattr(message, field.name).add()
    else:
      if field.is_extension:
        sub_message = message.Extensions[field]
      else:
        sub_message = getattr(message, field.name)
      sub_message.SetInParent()

    while not tokenizer.TryConsume(end_token):
      if tokenizer.AtEnd():
        raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token))
      _MergeField(tokenizer, sub_message)
  else:
    _MergeScalarField(tokenizer, message, field)
def _MergeField ( tokenizer , message ) : message_descriptor = message . DESCRIPTOR if tokenizer . TryConsume ( '[' ) : name = [ tokenizer . ConsumeIdentifier ( ) ] while tokenizer . TryConsume ( '.' ) : name . append ( tokenizer . ConsumeIdentifier ( ) ) name = '.' . join ( name ) if not message_descriptor . is_extendable : raise tokenizer . ParseErrorPreviousToken ( 'Message type "%s" does not have extensions.' % message_descriptor . full_name ) field = message . Extensions . _FindExtensionByName ( name ) if not field : raise tokenizer . ParseErrorPreviousToken ( 'Extension "%s" not registered.' % name ) elif message_descriptor != field . containing_type : raise tokenizer . ParseErrorPreviousToken ( 'Extension "%s" does not extend message type "%s".' % ( name , message_descriptor . full_name ) ) tokenizer . Consume ( ']' ) else : name = tokenizer . ConsumeIdentifier ( ) field = message_descriptor . fields_by_name . get ( name , None ) # Group names are expected to be capitalized as they appear in the # .proto file, which actually matches their type names, not their field # names. if not field : field = message_descriptor . fields_by_name . get ( name . lower ( ) , None ) if field and field . type != descriptor . FieldDescriptor . TYPE_GROUP : field = None if ( field and field . type == descriptor . FieldDescriptor . TYPE_GROUP and field . message_type . name != name ) : field = None if not field : raise tokenizer . ParseErrorPreviousToken ( 'Message type "%s" has no field named "%s".' % ( message_descriptor . full_name , name ) ) if field . cpp_type == descriptor . FieldDescriptor . CPPTYPE_MESSAGE : tokenizer . TryConsume ( ':' ) if tokenizer . TryConsume ( '<' ) : end_token = '>' else : tokenizer . Consume ( '{' ) end_token = '}' if field . label == descriptor . FieldDescriptor . LABEL_REPEATED : if field . is_extension : sub_message = message . Extensions [ field ] . add ( ) else : sub_message = getattr ( message , field . name ) . add ( ) else : if field . is_extension : sub_message = message . Extensions [ field ] else : sub_message = getattr ( message , field . name ) sub_message . SetInParent ( ) while not tokenizer . TryConsume ( end_token ) : if tokenizer . AtEnd ( ) : raise tokenizer . ParseErrorPreviousToken ( 'Expected "%s".' % ( end_token ) ) _MergeField ( tokenizer , sub_message ) else : _MergeScalarField ( tokenizer , message , field )