To write a field you first write its tag, so today you build the inverse of the decoder: pack a field number and wire type back into a single varint. This is the first thing every encoded field emits.
Encode a field number and wire type into a tag varint.
Encoding a tag is the mirror of decoding one: combine the field number and wire
type with field << 3 | wire, then write the result as a varint using the encoder
you already have. For small field numbers the tag is a single byte, which is why
protobuf rewards putting your most common fields in numbers 1 through 15 - they
cost one tag byte instead of two.
Field 16 is the boundary worth pinning: 16 << 3 | 2 is 130, which is larger than
127, so the tag spills to two varint bytes, 0x82 0x01. That is not a special case
in your code - it falls straight out of reusing AppendVarint - but it confirms
the tag really is just a varint like any other, and that field numbers above 15
carry a real encoding cost.
// shift the field number up by 3 and drop the wire type in the low bitsfunc AppendTag(buf []byte, field int, wire int) []byte {tag := uint64(field)<<3 | uint64(wire)return AppendVarint(buf, tag)}