decodeTag function

Map<String, int> decodeTag(
  1. List<int> buffer,
  2. int offset
)

Decodes a protobuf field tag from buffer starting at offset.

Returns a map with three entries:

  • 'fieldNumber': the field number extracted from the tag.
  • 'wireType': the wire type (lowest 3 bits of the tag value).
  • 'bytesRead': the number of bytes consumed (the varint length).

The varint decoding is inlined here to avoid cross-file imports.

Throws a FormatException if the varint exceeds 10 bytes or the buffer ends before the varint is complete.

Implementation

Map<String, int> decodeTag(List<int> buffer, int offset) {
  // Inline varint decoding.
  int result = 0;
  int shift = 0;
  int bytesRead = 0;

  while (true) {
    if (offset + bytesRead >= buffer.length) {
      throw FormatException(
        'Unexpected end of buffer while decoding tag varint at offset $offset',
      );
    }

    int byte = buffer[offset + bytesRead];
    bytesRead++;

    result = result | ((byte & 0x7F) << shift);
    shift += 7;

    if ((byte & 0x80) == 0) {
      break;
    }

    if (bytesRead >= 10) {
      throw FormatException(
        'Tag varint exceeds maximum length of 10 bytes at offset $offset',
      );
    }
  }

  int wireType = result & 0x07;
  int fieldNumber = result >>> 3;
  return {
    'fieldNumber': fieldNumber,
    'wireType': wireType,
    'bytesRead': bytesRead,
  };
}