def bytesdecoder(field_number, is_repeated, is_packed, key, new_default):
  """returns a decoder for a bytes 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:
        (size, pos) = local_decodevarint(buffer, pos)
        new_pos = pos + size
        if new_pos > end:
          raise _decodeerror('truncated string.')
        value.append(buffer[pos:new_pos])
        # predict that the next tag is another copy of the same repeated field.
        pos = new_pos + tag_len
        if buffer[new_pos:pos] != tag_bytes or new_pos == end:
          # prediction failed.  return.
          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] = buffer[pos:new_pos]
      return new_pos
    return decodefield
def groupdecoder(field_number, is_repeated, is_packed, key, new_default):
  """returns a decoder for a group field."""

  end_tag_bytes = encoder.tagbytes(field_number,
                                   wire_format.wiretype_end_group)
  end_tag_len = len(end_tag_bytes)

  assert not is_packed
  if is_repeated:
    tag_bytes = encoder.tagbytes(field_number,
                                 wire_format.wiretype_start_group)
    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))
        # read sub-message.
        pos = value.add()._internalparse(buffer, pos, end)
        # read end tag.
        new_pos = pos+end_tag_len
        if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
          raise _decodeerror('missing group end tag.')
        # predict that the next tag is another copy of the same repeated field.
        pos = new_pos + tag_len
        if buffer[new_pos:pos] != tag_bytes or new_pos == end:
          # prediction failed.  return.
          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))
      # read sub-message.
      pos = value._internalparse(buffer, pos, end)
      # read end tag.
      new_pos = pos+end_tag_len
      if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
        raise _decodeerror('missing group end tag.')
      return new_pos
    return decodefield
 def getfield(self, name):
   field_descriptor = self.descriptor.fields_by_name[name]
   wire_type = type_checkers.field_type_to_wire_type[field_descriptor.type]
   field_tag = encoder.tagbytes(field_descriptor.number, wire_type)
   for tag_bytes, value in self.unknown_fields:
     if tag_bytes == field_tag:
       decoder = unittest_pb2.testalltypes._decoders_by_tag[tag_bytes]
       result_dict = {}
       decoder(value, 0, len(value), self.all_fields, result_dict)
       return result_dict[field_descriptor]
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))
        # read length.
        (size, pos) = local_decodevarint(buffer, pos)
        new_pos = pos + size
        if new_pos > end:
          raise _decodeerror('truncated message.')
        # read sub-message.
        if value.add()._internalparse(buffer, pos, new_pos) != new_pos:
          # the only reason _internalparse would return early is if it
          # encountered an end-group tag.
          raise _decodeerror('unexpected end-group tag.')
        # predict that the next tag is another copy of the same repeated field.
        pos = new_pos + tag_len
        if buffer[new_pos:pos] != tag_bytes or new_pos == end:
          # prediction failed.  return.
          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))
      # read length.
      (size, pos) = local_decodevarint(buffer, pos)
      new_pos = pos + size
      if new_pos > end:
        raise _decodeerror('truncated message.')
      # read sub-message.
      if value._internalparse(buffer, pos, new_pos) != new_pos:
        # the only reason _internalparse would return early is if it encountered
        # an end-group tag.
        raise _decodeerror('unexpected end-group tag.')
      return new_pos
    return decodefield
 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]   # discard corrupt value.
         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)
         # predict that the next tag is another copy of the same repeated
         # field.
         pos = new_pos + tag_len
         if buffer[new_pos:pos] != tag_bytes or new_pos >= end:
           # prediction failed.  return.
           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]  # discard corrupt value.
         raise _decodeerror('truncated message.')
       return pos
     return decodefield
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

    # technically, type_id and message can appear in any order, so we need
    # a little loop here.
    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:
        # the only reason _internalparse would return early is if it encountered
        # an end-group tag.
        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
      (size, pos) = local_decodevarint(buffer, pos)
      new_pos = pos + size
      if new_pos > end:
        raise _decodeerror('truncated message.')
      # read sub-message.
      if value._internalparse(buffer, pos, new_pos) != new_pos:
        # the only reason _internalparse would return early is if it encountered
        # an end-group tag.
        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;
      }
    }
  """
 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))