1
// Copyright 2018 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
5
// Package protowire parses and formats the raw wire encoding.
6
// See https://protobuf.dev/programming-guides/encoding.
8
// For marshaling and unmarshaling entire protobuf messages,
9
// use the "google.golang.org/protobuf/proto" package instead.
17
"google.golang.org/protobuf/internal/errors"
20
// Number represents the field number.
24
MinValidNumber Number = 1
25
FirstReservedNumber Number = 19000
26
LastReservedNumber Number = 19999
27
MaxValidNumber Number = 1<<29 - 1
28
DefaultRecursionLimit = 10000
31
// IsValid reports whether the field number is semantically valid.
32
func (n Number) IsValid() bool {
33
return MinValidNumber <= n && n <= MaxValidNumber
36
// Type represents the wire type.
44
StartGroupType Type = 3
59
errFieldNumber = errors.New("invalid field number")
60
errOverflow = errors.New("variable length integer overflow")
61
errReserved = errors.New("cannot parse reserved wire type")
62
errEndGroup = errors.New("mismatching end group marker")
63
errParse = errors.New("parse error")
66
// ParseError converts an error code into an error value.
67
// This returns nil if n is a non-negative number.
68
func ParseError(n int) error {
73
case errCodeTruncated:
74
return io.ErrUnexpectedEOF
75
case errCodeFieldNumber:
88
// ConsumeField parses an entire field record (both tag and value) and returns
89
// the field number, the wire type, and the total length.
90
// This returns a negative length upon an error (see ParseError).
92
// The total length includes the tag header and the end group marker (if the
94
func ConsumeField(b []byte) (Number, Type, int) {
95
num, typ, n := ConsumeTag(b)
97
return 0, 0, n // forward error code
99
m := ConsumeFieldValue(num, typ, b[n:])
101
return 0, 0, m // forward error code
103
return num, typ, n + m
106
// ConsumeFieldValue parses a field value and returns its length.
107
// This assumes that the field Number and wire Type have already been parsed.
108
// This returns a negative length upon an error (see ParseError).
110
// When parsing a group, the length includes the end group marker and
111
// the end group is verified to match the starting field number.
112
func ConsumeFieldValue(num Number, typ Type, b []byte) (n int) {
113
return consumeFieldValueD(num, typ, b, DefaultRecursionLimit)
116
func consumeFieldValueD(num Number, typ Type, b []byte, depth int) (n int) {
119
_, n = ConsumeVarint(b)
122
_, n = ConsumeFixed32(b)
125
_, n = ConsumeFixed64(b)
128
_, n = ConsumeBytes(b)
132
return errCodeRecursionDepth
136
num2, typ2, n := ConsumeTag(b)
138
return n // forward error code
141
if typ2 == EndGroupType {
143
return errCodeEndGroup
148
n = consumeFieldValueD(num2, typ2, b, depth-1)
150
return n // forward error code
155
return errCodeEndGroup
157
return errCodeReserved
161
// AppendTag encodes num and typ as a varint-encoded tag and appends it to b.
162
func AppendTag(b []byte, num Number, typ Type) []byte {
163
return AppendVarint(b, EncodeTag(num, typ))
166
// ConsumeTag parses b as a varint-encoded tag, reporting its length.
167
// This returns a negative length upon an error (see ParseError).
168
func ConsumeTag(b []byte) (Number, Type, int) {
169
v, n := ConsumeVarint(b)
171
return 0, 0, n // forward error code
173
num, typ := DecodeTag(v)
174
if num < MinValidNumber {
175
return 0, 0, errCodeFieldNumber
180
func SizeTag(num Number) int {
181
return SizeVarint(EncodeTag(num, 0)) // wire type has no effect on size
184
// AppendVarint appends v to b as a varint-encoded uint64.
185
func AppendVarint(b []byte, v uint64) []byte {
188
b = append(b, byte(v))
191
byte((v>>0)&0x7f|0x80),
195
byte((v>>0)&0x7f|0x80),
196
byte((v>>7)&0x7f|0x80),
200
byte((v>>0)&0x7f|0x80),
201
byte((v>>7)&0x7f|0x80),
202
byte((v>>14)&0x7f|0x80),
206
byte((v>>0)&0x7f|0x80),
207
byte((v>>7)&0x7f|0x80),
208
byte((v>>14)&0x7f|0x80),
209
byte((v>>21)&0x7f|0x80),
213
byte((v>>0)&0x7f|0x80),
214
byte((v>>7)&0x7f|0x80),
215
byte((v>>14)&0x7f|0x80),
216
byte((v>>21)&0x7f|0x80),
217
byte((v>>28)&0x7f|0x80),
221
byte((v>>0)&0x7f|0x80),
222
byte((v>>7)&0x7f|0x80),
223
byte((v>>14)&0x7f|0x80),
224
byte((v>>21)&0x7f|0x80),
225
byte((v>>28)&0x7f|0x80),
226
byte((v>>35)&0x7f|0x80),
230
byte((v>>0)&0x7f|0x80),
231
byte((v>>7)&0x7f|0x80),
232
byte((v>>14)&0x7f|0x80),
233
byte((v>>21)&0x7f|0x80),
234
byte((v>>28)&0x7f|0x80),
235
byte((v>>35)&0x7f|0x80),
236
byte((v>>42)&0x7f|0x80),
240
byte((v>>0)&0x7f|0x80),
241
byte((v>>7)&0x7f|0x80),
242
byte((v>>14)&0x7f|0x80),
243
byte((v>>21)&0x7f|0x80),
244
byte((v>>28)&0x7f|0x80),
245
byte((v>>35)&0x7f|0x80),
246
byte((v>>42)&0x7f|0x80),
247
byte((v>>49)&0x7f|0x80),
251
byte((v>>0)&0x7f|0x80),
252
byte((v>>7)&0x7f|0x80),
253
byte((v>>14)&0x7f|0x80),
254
byte((v>>21)&0x7f|0x80),
255
byte((v>>28)&0x7f|0x80),
256
byte((v>>35)&0x7f|0x80),
257
byte((v>>42)&0x7f|0x80),
258
byte((v>>49)&0x7f|0x80),
259
byte((v>>56)&0x7f|0x80),
265
// ConsumeVarint parses b as a varint-encoded uint64, reporting its length.
266
// This returns a negative length upon an error (see ParseError).
267
func ConsumeVarint(b []byte) (v uint64, n int) {
270
return 0, errCodeTruncated
279
return 0, errCodeTruncated
289
return 0, errCodeTruncated
299
return 0, errCodeTruncated
309
return 0, errCodeTruncated
319
return 0, errCodeTruncated
329
return 0, errCodeTruncated
339
return 0, errCodeTruncated
349
return 0, errCodeTruncated
359
return 0, errCodeTruncated
366
return 0, errCodeOverflow
369
// SizeVarint returns the encoded size of a varint.
370
// The size is guaranteed to be within 1 and 10, inclusive.
371
func SizeVarint(v uint64) int {
372
// This computes 1 + (bits.Len64(v)-1)/7.
373
// 9/64 is a good enough approximation of 1/7
374
return int(9*uint32(bits.Len64(v))+64) / 64
377
// AppendFixed32 appends v to b as a little-endian uint32.
378
func AppendFixed32(b []byte, v uint32) []byte {
386
// ConsumeFixed32 parses b as a little-endian uint32, reporting its length.
387
// This returns a negative length upon an error (see ParseError).
388
func ConsumeFixed32(b []byte) (v uint32, n int) {
390
return 0, errCodeTruncated
392
v = uint32(b[0])<<0 | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
396
// SizeFixed32 returns the encoded size of a fixed32; which is always 4.
397
func SizeFixed32() int {
401
// AppendFixed64 appends v to b as a little-endian uint64.
402
func AppendFixed64(b []byte, v uint64) []byte {
414
// ConsumeFixed64 parses b as a little-endian uint64, reporting its length.
415
// This returns a negative length upon an error (see ParseError).
416
func ConsumeFixed64(b []byte) (v uint64, n int) {
418
return 0, errCodeTruncated
420
v = uint64(b[0])<<0 | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
424
// SizeFixed64 returns the encoded size of a fixed64; which is always 8.
425
func SizeFixed64() int {
429
// AppendBytes appends v to b as a length-prefixed bytes value.
430
func AppendBytes(b []byte, v []byte) []byte {
431
return append(AppendVarint(b, uint64(len(v))), v...)
434
// ConsumeBytes parses b as a length-prefixed bytes value, reporting its length.
435
// This returns a negative length upon an error (see ParseError).
436
func ConsumeBytes(b []byte) (v []byte, n int) {
437
m, n := ConsumeVarint(b)
439
return nil, n // forward error code
441
if m > uint64(len(b[n:])) {
442
return nil, errCodeTruncated
444
return b[n:][:m], n + int(m)
447
// SizeBytes returns the encoded size of a length-prefixed bytes value,
448
// given only the length.
449
func SizeBytes(n int) int {
450
return SizeVarint(uint64(n)) + n
453
// AppendString appends v to b as a length-prefixed bytes value.
454
func AppendString(b []byte, v string) []byte {
455
return append(AppendVarint(b, uint64(len(v))), v...)
458
// ConsumeString parses b as a length-prefixed bytes value, reporting its length.
459
// This returns a negative length upon an error (see ParseError).
460
func ConsumeString(b []byte) (v string, n int) {
461
bb, n := ConsumeBytes(b)
465
// AppendGroup appends v to b as group value, with a trailing end group marker.
466
// The value v must not contain the end marker.
467
func AppendGroup(b []byte, num Number, v []byte) []byte {
468
return AppendVarint(append(b, v...), EncodeTag(num, EndGroupType))
471
// ConsumeGroup parses b as a group value until the trailing end group marker,
472
// and verifies that the end marker matches the provided num. The value v
473
// does not contain the end marker, while the length does contain the end marker.
474
// This returns a negative length upon an error (see ParseError).
475
func ConsumeGroup(num Number, b []byte) (v []byte, n int) {
476
n = ConsumeFieldValue(num, StartGroupType, b)
478
return nil, n // forward error code
482
// Truncate off end group marker, but need to handle denormalized varints.
483
// Assuming end marker is never 0 (which is always the case since
484
// EndGroupType is non-zero), we can truncate all trailing bytes where the
485
// lower 7 bits are all zero (implying that the varint is denormalized).
486
for len(b) > 0 && b[len(b)-1]&0x7f == 0 {
489
b = b[:len(b)-SizeTag(num)]
493
// SizeGroup returns the encoded size of a group, given only the length.
494
func SizeGroup(num Number, n int) int {
495
return n + SizeTag(num)
498
// DecodeTag decodes the field Number and wire Type from its unified form.
499
// The Number is -1 if the decoded field number overflows int32.
500
// Other than overflow, this does not check for field number validity.
501
func DecodeTag(x uint64) (Number, Type) {
502
// NOTE: MessageSet allows for larger field numbers than normal.
503
if x>>3 > uint64(math.MaxInt32) {
506
return Number(x >> 3), Type(x & 7)
509
// EncodeTag encodes the field Number and wire Type into its unified form.
510
func EncodeTag(num Number, typ Type) uint64 {
511
return uint64(num)<<3 | uint64(typ&7)
514
// DecodeZigZag decodes a zig-zag-encoded uint64 as an int64.
516
// Input: {…, 5, 3, 1, 0, 2, 4, 6, …}
517
// Output: {…, -3, -2, -1, 0, +1, +2, +3, …}
518
func DecodeZigZag(x uint64) int64 {
519
return int64(x>>1) ^ int64(x)<<63>>63
522
// EncodeZigZag encodes an int64 as a zig-zag-encoded uint64.
524
// Input: {…, -3, -2, -1, 0, +1, +2, +3, …}
525
// Output: {…, 5, 3, 1, 0, 2, 4, 6, …}
526
func EncodeZigZag(x int64) uint64 {
527
return uint64(x<<1) ^ uint64(x>>63)
530
// DecodeBool decodes a uint64 as a bool.
532
// Input: { 0, 1, 2, …}
533
// Output: {false, true, true, …}
534
func DecodeBool(x uint64) bool {
538
// EncodeBool encodes a bool as a uint64.
540
// Input: {false, true}
542
func EncodeBool(x bool) uint64 {