Exemplo n.º 1
0
    def SpecificDecoder(field_number, is_repeated, is_packed, key,
                        new_default):
        if is_packed:
            local_DecodeVarint = _DecodeVarint

            def DecodePackedField(buffer, pos, end, message, field_dict):
                value = field_dict.get(key)
                if value is None:
                    value = field_dict.setdefault(key, new_default(message))
                (endpoint, pos) = local_DecodeVarint(buffer, pos)
                endpoint += pos
                if endpoint > end:
                    raise _DecodeError('Truncated message.')
                while pos < endpoint:
                    (element, pos) = decode_value(buffer, pos)
                    value.append(element)
                if pos > endpoint:
                    del value[-1]
                    raise _DecodeError('Packed element was truncated.')
                return pos

            return DecodePackedField
        elif is_repeated:
            tag_bytes = encoder.TagBytes(field_number, wire_type)
            tag_len = len(tag_bytes)

            def DecodeRepeatedField(buffer, pos, end, message, field_dict):
                value = field_dict.get(key)
                if value is None:
                    value = field_dict.setdefault(key, new_default(message))
                while 1:
                    (element, new_pos) = decode_value(buffer, pos)
                    value.append(element)

                    pos = new_pos + tag_len
                    if buffer[new_pos:pos] != tag_bytes or new_pos >= end:

                        if new_pos > end:
                            raise _DecodeError('Truncated message.')
                        return new_pos

            return DecodeRepeatedField
        else:

            def DecodeField(buffer, pos, end, message, field_dict):
                (field_dict[key], pos) = decode_value(buffer, pos)
                if pos > end:
                    del field_dict[key]
                    raise _DecodeError('Truncated message.')
                return pos

            return DecodeField
Exemplo n.º 2
0
def MessageDecoder(field_number, is_repeated, is_packed, key, new_default):
  """Returns a decoder for a message field."""

  local_DecodeVarint = _DecodeVarint

  assert not is_packed
  if is_repeated:
    tag_bytes = encoder.TagBytes(field_number,
                                 wire_format.WIRETYPE_LENGTH_DELIMITED)
    tag_len = len(tag_bytes)
    def DecodeRepeatedField(buffer, pos, end, message, field_dict):
      value = field_dict.get(key)
      if value is None:
        value = field_dict.setdefault(key, new_default(message))
      while 1:
        value = field_dict.get(key)
        if value is None:
          value = field_dict.setdefault(key, new_default(message))

        (size, pos) = local_DecodeVarint(buffer, pos)
        new_pos = pos + size
        if new_pos > end:
          raise _DecodeError('Truncated message.')

        if value.add()._InternalParse(buffer, pos, new_pos) != new_pos:


          raise _DecodeError('Unexpected end-group tag.')

        pos = new_pos + tag_len
        if buffer[new_pos:pos] != tag_bytes or new_pos == end:

          return new_pos
    return DecodeRepeatedField
  else:
    def DecodeField(buffer, pos, end, message, field_dict):
      value = field_dict.get(key)
      if value is None:
        value = field_dict.setdefault(key, new_default(message))

      (size, pos) = local_DecodeVarint(buffer, pos)
      new_pos = pos + size
      if new_pos > end:
        raise _DecodeError('Truncated message.')

      if value._InternalParse(buffer, pos, new_pos) != new_pos:


        raise _DecodeError('Unexpected end-group tag.')
      return new_pos
    return DecodeField
Exemplo n.º 3
0
        def DecodePackedField(buffer, pos, end, message, field_dict):
            """Decode serialized packed enum to its value and a new position.

      Args:
        buffer: memoryview of the serialized bytes.
        pos: int, position in the memory view to start at.
        end: int, end position of serialized data
        message: Message object to store unknown fields in
        field_dict: Map[Descriptor, Any] to store decoded values in.

      Returns:
        int, new position in serialized data.
      """
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            (endpoint, pos) = local_DecodeVarint(buffer, pos)
            endpoint += pos
            if endpoint > end:
                raise _DecodeError('Truncated message.')
            while pos < endpoint:
                value_start_pos = pos
                (element, pos) = _DecodeSignedVarint32(buffer, pos)

                if element in enum_type.values_by_number:
                    value.append(element)
                else:
                    if not message._unknown_fields:
                        message._unknown_fields = []
                    tag_bytes = encoder.TagBytes(field_number,
                                                 wire_format.WIRETYPE_VARINT)

                    message._unknown_fields.append(
                        (tag_bytes, buffer[value_start_pos:pos].tobytes()))
                    if message._unknown_field_set is None:
                        message._unknown_field_set = containers.UnknownFieldSet(
                        )
                    message._unknown_field_set._add(
                        field_number, wire_format.WIRETYPE_VARINT, element)

            if pos > endpoint:
                if element in enum_type.values_by_number:
                    del value[-1]
                else:
                    del message._unknown_fields[-1]

                    del message._unknown_field_set._values[-1]

                raise _DecodeError('Packed element was truncated.')
            return pos
Exemplo n.º 4
0
 def DecodeField(buffer, pos, end, message, field_dict):
   value_start_pos = pos
   (enum_value, pos) = _DecodeSignedVarint32(buffer, pos)
   if pos > end:
     raise _DecodeError('Truncated message.')
   if enum_value in enum_type.values_by_number:
     field_dict[key] = enum_value
   else:
     if not message._unknown_fields:
       message._unknown_fields = []
     tag_bytes = encoder.TagBytes(field_number,
                                  wire_format.WIRETYPE_VARINT)
     message._unknown_fields.append(
       (tag_bytes, buffer[value_start_pos:pos]))
   return pos
Exemplo n.º 5
0
def StringDecoder(field_number, is_repeated, is_packed, key, new_default):
    """Returns a decoder for a string field."""

    local_DecodeVarint = _DecodeVarint
    local_unicode = six.text_type

    def _ConvertToUnicode(byte_str):
        try:
            return local_unicode(byte_str, 'utf-8')
        except UnicodeDecodeError as e:

            e.reason = '%s in field: %s' % (e, key.full_name)
            raise

    assert not is_packed
    if is_repeated:
        tag_bytes = encoder.TagBytes(field_number,
                                     wire_format.WIRETYPE_LENGTH_DELIMITED)
        tag_len = len(tag_bytes)

        def DecodeRepeatedField(buffer, pos, end, message, field_dict):
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            while 1:
                (size, pos) = local_DecodeVarint(buffer, pos)
                new_pos = pos + size
                if new_pos > end:
                    raise _DecodeError('Truncated string.')
                value.append(_ConvertToUnicode(buffer[pos:new_pos]))

                pos = new_pos + tag_len
                if buffer[new_pos:pos] != tag_bytes or new_pos == end:

                    return new_pos

        return DecodeRepeatedField
    else:

        def DecodeField(buffer, pos, end, message, field_dict):
            (size, pos) = local_DecodeVarint(buffer, pos)
            new_pos = pos + size
            if new_pos > end:
                raise _DecodeError('Truncated string.')
            field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos])
            return new_pos

        return DecodeField
Exemplo n.º 6
0
    def AddDecoder(wiretype, is_packed):
        tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype)
        decode_type = field_descriptor.type
        if (decode_type == _FieldDescriptor.TYPE_ENUM
                and type_checkers.SupportsOpenEnums(field_descriptor)):
            decode_type = _FieldDescriptor.TYPE_INT32

        oneof_descriptor = None
        if field_descriptor.containing_oneof is not None:
            oneof_descriptor = field_descriptor

        field_decoder = type_checkers.TYPE_TO_DECODER[decode_type](
            field_descriptor.number, is_repeated, is_packed, field_descriptor,
            field_descriptor._default_constructor)

        cls._decoders_by_tag[tag_bytes] = (field_decoder, oneof_descriptor)
Exemplo n.º 7
0
def MapDecoder(field_descriptor, new_default, is_message_map):
  """Returns a decoder for a map field."""

  key = field_descriptor
  tag_bytes = encoder.TagBytes(field_descriptor.number,
                               wire_format.WIRETYPE_LENGTH_DELIMITED)
  tag_len = len(tag_bytes)
  local_DecodeVarint = _DecodeVarint

  message_type = field_descriptor.message_type

  def DecodeMap(buffer, pos, end, message, field_dict):
    submsg = message_type._concrete_class()
    value = field_dict.get(key)
    if value is None:
      value = field_dict.setdefault(key, new_default(message))
    while 1:

      (size, pos) = local_DecodeVarint(buffer, pos)
      new_pos = pos + size
      if new_pos > end:
        raise _DecodeError('Truncated message.')

      submsg.Clear()
      if submsg._InternalParse(buffer, pos, new_pos) != new_pos:


        raise _DecodeError('Unexpected end-group tag.')

      if is_message_map:
        value[submsg.key].CopyFrom(submsg.value)
      else:
        value[submsg.key] = submsg.value


      pos = new_pos + tag_len
      if buffer[new_pos:pos] != tag_bytes or new_pos == end:

        return new_pos

  return DecodeMap
Exemplo n.º 8
0
def StringDecoder(field_number, is_repeated, is_packed, key, new_default):
    """Returns a decoder for a string field."""

    local_DecodeVarint = _DecodeVarint
    local_unicode = unicode

    assert not is_packed
    if is_repeated:
        tag_bytes = encoder.TagBytes(field_number,
                                     wire_format.WIRETYPE_LENGTH_DELIMITED)
        tag_len = len(tag_bytes)

        def DecodeRepeatedField(buffer, pos, end, message, field_dict):
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            while 1:
                (size, pos) = local_DecodeVarint(buffer, pos)
                new_pos = pos + size
                if new_pos > end:
                    raise _DecodeError('Truncated string.')
                value.append(local_unicode(buffer[pos:new_pos], 'utf-8'))

                pos = new_pos + tag_len
                if buffer[new_pos:pos] != tag_bytes or new_pos == end:

                    return new_pos

        return DecodeRepeatedField
    else:

        def DecodeField(buffer, pos, end, message, field_dict):
            (size, pos) = local_DecodeVarint(buffer, pos)
            new_pos = pos + size
            if new_pos > end:
                raise _DecodeError('Truncated string.')
            field_dict[key] = local_unicode(buffer[pos:new_pos], 'utf-8')
            return new_pos

        return DecodeField
Exemplo n.º 9
0
def MessageSetItemDecoder(extensions_by_number):
  """Returns a decoder for a MessageSet item.

  The parameter is the _extensions_by_number map for the message class.

  The message set message looks like this:
    message MessageSet {
      repeated group Item = 1 {
        required int32 type_id = 2;
        required string message = 3;
      }
    }
  """

  type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT)
  message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED)
  item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP)

  local_ReadTag = ReadTag
  local_DecodeVarint = _DecodeVarint
  local_SkipField = SkipField

  def DecodeItem(buffer, pos, end, message, field_dict):
    message_set_item_start = pos
    type_id = -1
    message_start = -1
    message_end = -1



    while 1:
      (tag_bytes, pos) = local_ReadTag(buffer, pos)
      if tag_bytes == type_id_tag_bytes:
        (type_id, pos) = local_DecodeVarint(buffer, pos)
      elif tag_bytes == message_tag_bytes:
        (size, message_start) = local_DecodeVarint(buffer, pos)
        pos = message_end = message_start + size
      elif tag_bytes == item_end_tag_bytes:
        break
      else:
        pos = SkipField(buffer, pos, end, tag_bytes)
        if pos == -1:
          raise _DecodeError('Missing group end tag.')

    if pos > end:
      raise _DecodeError('Truncated message.')

    if type_id == -1:
      raise _DecodeError('MessageSet item missing type_id.')
    if message_start == -1:
      raise _DecodeError('MessageSet item missing message.')

    extension = extensions_by_number.get(type_id)
    if extension is not None:
      value = field_dict.get(extension)
      if value is None:
        value = field_dict.setdefault(
            extension, extension.message_type._concrete_class())
      if value._InternalParse(buffer, message_start,message_end) != message_end:


        raise _DecodeError('Unexpected end-group tag.')
    else:
      if not message._unknown_fields:
        message._unknown_fields = []
      message._unknown_fields.append((MESSAGE_SET_ITEM_TAG,
                                      buffer[message_set_item_start:pos]))

    return pos

  return DecodeItem
Exemplo n.º 10
0
def EnumDecoder(field_number, is_repeated, is_packed, key, new_default):
  enum_type = key.enum_type
  if is_packed:
    local_DecodeVarint = _DecodeVarint
    def DecodePackedField(buffer, pos, end, message, field_dict):
      value = field_dict.get(key)
      if value is None:
        value = field_dict.setdefault(key, new_default(message))
      (endpoint, pos) = local_DecodeVarint(buffer, pos)
      endpoint += pos
      if endpoint > end:
        raise _DecodeError('Truncated message.')
      while pos < endpoint:
        value_start_pos = pos
        (element, pos) = _DecodeSignedVarint32(buffer, pos)
        if element in enum_type.values_by_number:
          value.append(element)
        else:
          if not message._unknown_fields:
            message._unknown_fields = []
          tag_bytes = encoder.TagBytes(field_number,
                                       wire_format.WIRETYPE_VARINT)
          message._unknown_fields.append(
              (tag_bytes, buffer[value_start_pos:pos]))
      if pos > endpoint:
        if element in enum_type.values_by_number:
          del value[-1]
        else:
          del message._unknown_fields[-1]
        raise _DecodeError('Packed element was truncated.')
      return pos
    return DecodePackedField
  elif is_repeated:
    tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT)
    tag_len = len(tag_bytes)
    def DecodeRepeatedField(buffer, pos, end, message, field_dict):
      value = field_dict.get(key)
      if value is None:
        value = field_dict.setdefault(key, new_default(message))
      while 1:
        (element, new_pos) = _DecodeSignedVarint32(buffer, pos)
        if element in enum_type.values_by_number:
          value.append(element)
        else:
          if not message._unknown_fields:
            message._unknown_fields = []
          message._unknown_fields.append(
              (tag_bytes, buffer[pos:new_pos]))


        pos = new_pos + tag_len
        if buffer[new_pos:pos] != tag_bytes or new_pos >= end:

          if new_pos > end:
            raise _DecodeError('Truncated message.')
          return new_pos
    return DecodeRepeatedField
  else:
    def DecodeField(buffer, pos, end, message, field_dict):
      value_start_pos = pos
      (enum_value, pos) = _DecodeSignedVarint32(buffer, pos)
      if pos > end:
        raise _DecodeError('Truncated message.')
      if enum_value in enum_type.values_by_number:
        field_dict[key] = enum_value
      else:
        if not message._unknown_fields:
          message._unknown_fields = []
        tag_bytes = encoder.TagBytes(field_number,
                                     wire_format.WIRETYPE_VARINT)
        message._unknown_fields.append(
          (tag_bytes, buffer[value_start_pos:pos]))
      return pos
    return DecodeField
Exemplo n.º 11
0
      (size, pos) = local_DecodeVarint(buffer, pos)
      new_pos = pos + size
      if new_pos > end:
        raise _DecodeError('Truncated message.')

      if value._InternalParse(buffer, pos, new_pos) != new_pos:


        raise _DecodeError('Unexpected end-group tag.')
      return new_pos
    return DecodeField




MESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP)

def MessageSetItemDecoder(extensions_by_number):
  """Returns a decoder for a MessageSet item.

  The parameter is the _extensions_by_number map for the message class.

  The message set message looks like this:
    message MessageSet {
      repeated group Item = 1 {
        required int32 type_id = 2;
        required string message = 3;
      }
    }
  """
Exemplo n.º 12
0
  """Returns a decoder for a string field."""

  local_DecodeVarint = _DecodeVarint
  local_unicode = unicode

  def _ConvertToUnicode(byte_str):
    try:
      return local_unicode(byte_str, 'utf-8')
    except UnicodeDecodeError, e:

      e.reason = '%s in field: %s' % (e, key.full_name)
      raise

  assert not is_packed
  if is_repeated:
    tag_bytes = encoder.TagBytes(field_number,
                                 wire_format.WIRETYPE_LENGTH_DELIMITED)
    tag_len = len(tag_bytes)
    def DecodeRepeatedField(buffer, pos, end, message, field_dict):
      value = field_dict.get(key)
      if value is None:
        value = field_dict.setdefault(key, new_default(message))
      while 1:
        (size, pos) = local_DecodeVarint(buffer, pos)
        new_pos = pos + size
        if new_pos > end:
          raise _DecodeError('Truncated string.')
        value.append(_ConvertToUnicode(buffer[pos:new_pos]))

        pos = new_pos + tag_len
        if buffer[new_pos:pos] != tag_bytes or new_pos == end:
Exemplo n.º 13
0
 def AddDecoder(wiretype, is_packed):
     tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype)
     cls._decoders_by_tag[tag_bytes] = (
         type_checkers.TYPE_TO_DECODER[field_descriptor.type](
             field_descriptor.number, is_repeated, is_packed,
             field_descriptor, field_descriptor._default_constructor))
Exemplo n.º 14
0
def MessageSetItemDecoder(descriptor):
    """Returns a decoder for a MessageSet item.

  The parameter is the message Descriptor.

  The message set message looks like this:
    message MessageSet {
      repeated group Item = 1 {
        required int32 type_id = 2;
        required string message = 3;
      }
    }
  """

    type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT)
    message_tag_bytes = encoder.TagBytes(3,
                                         wire_format.WIRETYPE_LENGTH_DELIMITED)
    item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP)

    local_ReadTag = ReadTag
    local_DecodeVarint = _DecodeVarint
    local_SkipField = SkipField

    def DecodeItem(buffer, pos, end, message, field_dict):
        """Decode serialized message set to its value and new position.

    Args:
      buffer: memoryview of the serialized bytes.
      pos: int, position in the memory view to start at.
      end: int, end position of serialized data
      message: Message object to store unknown fields in
      field_dict: Map[Descriptor, Any] to store decoded values in.

    Returns:
      int, new position in serialized data.
    """
        message_set_item_start = pos
        type_id = -1
        message_start = -1
        message_end = -1

        while 1:
            (tag_bytes, pos) = local_ReadTag(buffer, pos)
            if tag_bytes == type_id_tag_bytes:
                (type_id, pos) = local_DecodeVarint(buffer, pos)
            elif tag_bytes == message_tag_bytes:
                (size, message_start) = local_DecodeVarint(buffer, pos)
                pos = message_end = message_start + size
            elif tag_bytes == item_end_tag_bytes:
                break
            else:
                pos = SkipField(buffer, pos, end, tag_bytes)
                if pos == -1:
                    raise _DecodeError('Missing group end tag.')

        if pos > end:
            raise _DecodeError('Truncated message.')

        if type_id == -1:
            raise _DecodeError('MessageSet item missing type_id.')
        if message_start == -1:
            raise _DecodeError('MessageSet item missing message.')

        extension = message.Extensions._FindExtensionByNumber(type_id)

        if extension is not None:
            value = field_dict.get(extension)
            if value is None:
                value = field_dict.setdefault(
                    extension, extension.message_type._concrete_class())
            if value._InternalParse(buffer, message_start,
                                    message_end) != message_end:

                raise _DecodeError('Unexpected end-group tag.')
        else:
            if not message._unknown_fields:
                message._unknown_fields = []
            message._unknown_fields.append(
                (MESSAGE_SET_ITEM_TAG,
                 buffer[message_set_item_start:pos].tobytes()))

        return pos

    return DecodeItem
Exemplo n.º 15
0
def StringDecoder(field_number,
                  is_repeated,
                  is_packed,
                  key,
                  new_default,
                  is_strict_utf8=False):
    """Returns a decoder for a string field."""

    local_DecodeVarint = _DecodeVarint
    local_unicode = six.text_type

    def _ConvertToUnicode(memview):
        """Convert byte to unicode."""
        byte_str = memview.tobytes()
        try:
            value = local_unicode(byte_str, 'utf-8')
        except UnicodeDecodeError as e:

            e.reason = '%s in field: %s' % (e, key.full_name)
            raise

        if is_strict_utf8 and six.PY2 and sys.maxunicode > _UCS2_MAXUNICODE:

            if _SURROGATE_PATTERN.search(value):
                reason = (
                    'String field %s contains invalid UTF-8 data when parsing'
                    'a protocol buffer: surrogates not allowed. Use'
                    'the bytes type if you intend to send raw bytes.') % (
                        key.full_name)
                raise message.DecodeError(reason)

        return value

    assert not is_packed
    if is_repeated:
        tag_bytes = encoder.TagBytes(field_number,
                                     wire_format.WIRETYPE_LENGTH_DELIMITED)
        tag_len = len(tag_bytes)

        def DecodeRepeatedField(buffer, pos, end, message, field_dict):
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            while 1:
                (size, pos) = local_DecodeVarint(buffer, pos)
                new_pos = pos + size
                if new_pos > end:
                    raise _DecodeError('Truncated string.')
                value.append(_ConvertToUnicode(buffer[pos:new_pos]))

                pos = new_pos + tag_len
                if buffer[new_pos:pos] != tag_bytes or new_pos == end:

                    return new_pos

        return DecodeRepeatedField
    else:

        def DecodeField(buffer, pos, end, message, field_dict):
            (size, pos) = local_DecodeVarint(buffer, pos)
            new_pos = pos + size
            if new_pos > end:
                raise _DecodeError('Truncated string.')
            field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos])
            return new_pos

        return DecodeField
Exemplo n.º 16
0
def EnumDecoder(field_number, is_repeated, is_packed, key, new_default):
    enum_type = key.enum_type
    if is_packed:
        local_DecodeVarint = _DecodeVarint

        def DecodePackedField(buffer, pos, end, message, field_dict):
            """Decode serialized packed enum to its value and a new position.

      Args:
        buffer: memoryview of the serialized bytes.
        pos: int, position in the memory view to start at.
        end: int, end position of serialized data
        message: Message object to store unknown fields in
        field_dict: Map[Descriptor, Any] to store decoded values in.

      Returns:
        int, new position in serialized data.
      """
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            (endpoint, pos) = local_DecodeVarint(buffer, pos)
            endpoint += pos
            if endpoint > end:
                raise _DecodeError('Truncated message.')
            while pos < endpoint:
                value_start_pos = pos
                (element, pos) = _DecodeSignedVarint32(buffer, pos)

                if element in enum_type.values_by_number:
                    value.append(element)
                else:
                    if not message._unknown_fields:
                        message._unknown_fields = []
                    tag_bytes = encoder.TagBytes(field_number,
                                                 wire_format.WIRETYPE_VARINT)

                    message._unknown_fields.append(
                        (tag_bytes, buffer[value_start_pos:pos].tobytes()))

            if pos > endpoint:
                if element in enum_type.values_by_number:
                    del value[-1]
                else:
                    del message._unknown_fields[-1]
                raise _DecodeError('Packed element was truncated.')
            return pos

        return DecodePackedField
    elif is_repeated:
        tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT)
        tag_len = len(tag_bytes)

        def DecodeRepeatedField(buffer, pos, end, message, field_dict):
            """Decode serialized repeated enum to its value and a new position.

      Args:
        buffer: memoryview of the serialized bytes.
        pos: int, position in the memory view to start at.
        end: int, end position of serialized data
        message: Message object to store unknown fields in
        field_dict: Map[Descriptor, Any] to store decoded values in.

      Returns:
        int, new position in serialized data.
      """
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            while 1:
                (element, new_pos) = _DecodeSignedVarint32(buffer, pos)

                if element in enum_type.values_by_number:
                    value.append(element)
                else:
                    if not message._unknown_fields:
                        message._unknown_fields = []
                    message._unknown_fields.append(
                        (tag_bytes, buffer[pos:new_pos].tobytes()))

                pos = new_pos + tag_len
                if buffer[new_pos:pos] != tag_bytes or new_pos >= end:

                    if new_pos > end:
                        raise _DecodeError('Truncated message.')
                    return new_pos

        return DecodeRepeatedField
    else:

        def DecodeField(buffer, pos, end, message, field_dict):
            """Decode serialized repeated enum to its value and a new position.

      Args:
        buffer: memoryview of the serialized bytes.
        pos: int, position in the memory view to start at.
        end: int, end position of serialized data
        message: Message object to store unknown fields in
        field_dict: Map[Descriptor, Any] to store decoded values in.

      Returns:
        int, new position in serialized data.
      """
            value_start_pos = pos
            (enum_value, pos) = _DecodeSignedVarint32(buffer, pos)
            if pos > end:
                raise _DecodeError('Truncated message.')

            if enum_value in enum_type.values_by_number:
                field_dict[key] = enum_value
            else:
                if not message._unknown_fields:
                    message._unknown_fields = []
                tag_bytes = encoder.TagBytes(field_number,
                                             wire_format.WIRETYPE_VARINT)
                message._unknown_fields.append(
                    (tag_bytes, buffer[value_start_pos:pos].tobytes()))

            return pos

        return DecodeField