docs: def ReadIntoObject(buff, index, value_obj, length=0):
    """Reads all tags until the next end group and store in the value_obj."""
    raw_data = value_obj.GetRawData()
    count = 0
  
    # Split the buffer into tags and wire_format representations, then collect
    # these into the raw data cache.
    for (encoded_tag, encoded_length, encoded_field) in SplitBuffer(
        buff, index=index, length=length):
  
      type_info_obj = value_obj.type_infos_by_encoded_tag.get(encoded_tag)
  
      # Internal format to store parsed fields.
      wire_format = (encoded_tag, encoded_length, encoded_field)
  
      # If the tag is not found we need to skip it. Skipped fields are
      # inaccessible to this actual object, because they have no type info
      # describing them, however they are still stored in the raw data
      # representation because they will be re-serialized back. This way
      # programs which simply read protobufs and write them back do not need to
      # know all the fields, some of which were defined in a later version of
      # the application. In order to avoid having to worry about repeated fields
      # here, we just insert them into the raw data dict with a key which should
      # be unique.
      if type_info_obj is None:
        # Record an unknown field. The key is unique and ensures we do not collide
        # the dict on repeated fields of the encoded tag. Note that this field is
        # not really accessible using Get() and does not have a python format
        # representation. It will be written back using the same wire format it
        # was read with, therefore does not require a type descriptor at all.
        raw_data[count] = (None, wire_format, None)
  
        count += 1
  
      # Repeated fields are handled especially.
      elif type_info_obj.__class__ is ProtoList:
        value_obj.Get(type_info_obj.name).wrapped_list.append((None, wire_format))
  
      else:
        # Set the python_format as None so it gets converted lazily on access.
        raw_data[type_info_obj.name] = (None, wire_format, type_info_obj)
  
    value_obj.SetRawData(raw_data)