Groups are proto2’s older way of nesting one message in another. The documentation says “Groups are a deprecated feature that should not be used”, but they remain in the wire format, and parsers must still handle them.
How a group is written
A group is a nested message without a length. It opens with a tag of wire type 3 (SGROUP) carrying the field’s number, then come the group’s fields, read exactly like a message’s, and it closes with a tag of wire type 4 (EGROUP) carrying the same number. Groups can nest.
| Part | Type | Meaning |
|---|---|---|
| start-group tag | varint | Field number × 8 + 3. |
| fields | fields | The group’s contents, as many fields as it has. |
| end-group tag | varint | Field number × 8 + 4: the same number as the start tag. |
Field 9 as a group holding field 1 = 5 and, inside it, field 10 as a group holding
field 2 = in (built for this page):
| Bytes | Meaning |
|---|---|
4B | Start group, field 9. |
08 05 | Field 1, VARINT 5. |
53 | Start group, field 10. |
12 02 69 6E | Field 2, LEN 2, in. |
54 | End group, field 10. |
4C | End group, field 9. |
A reader that does not know the field skips a group by reading fields until the matching end-group tag, following any groups inside it. An end-group tag whose number does not match the open group, or one with no group open, is an error, and the explorer reports where it is. The explorer shows a group as its start tag, its fields and its end tag.
Delimited encoding in Editions
Editions, which replace proto2 and proto3 from release 27.0, have no group keyword.
They keep the encoding instead as a feature, features.message_encoding =
DELIMITED: a message field written as a group, between start and end tags,
instead of with a length. The bytes are the same as a proto2 group.