// Copyright 2018 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.
// Package protowire parses and formats the raw wire encoding.// See https://developers.google.com/protocol-buffers/docs/encoding.//// For marshaling and unmarshaling entire protobuf messages,// use the "google.golang.org/protobuf/proto" package instead.
package protowireimport ()// Number represents the field number.typeNumberint32const (MinValidNumberNumber = 1FirstReservedNumberNumber = 19000LastReservedNumberNumber = 19999MaxValidNumberNumber = 1<<29 - 1DefaultRecursionLimit = 10000)// IsValid reports whether the field number is semantically valid.//// Note that while numbers within the reserved range are semantically invalid,// they are syntactically valid in the wire format.// Implementations may treat records with reserved field numbers as unknown.func ( Number) () bool {returnMinValidNumber <= && < FirstReservedNumber || LastReservedNumber < && <= MaxValidNumber}// Type represents the wire type.typeTypeint8const (VarintTypeType = 0Fixed32TypeType = 5Fixed64TypeType = 1BytesTypeType = 2StartGroupTypeType = 3EndGroupTypeType = 4)const ( _ = -iotaerrCodeTruncatederrCodeFieldNumbererrCodeOverflowerrCodeReservederrCodeEndGrouperrCodeRecursionDepth)var (errFieldNumber = errors.New("invalid field number")errOverflow = errors.New("variable length integer overflow")errReserved = errors.New("cannot parse reserved wire type")errEndGroup = errors.New("mismatching end group marker")errParse = errors.New("parse error"))// ParseError converts an error code into an error value.// This returns nil if n is a non-negative number.func ( int) error {if >= 0 {returnnil }switch {caseerrCodeTruncated:returnio.ErrUnexpectedEOFcaseerrCodeFieldNumber:returnerrFieldNumbercaseerrCodeOverflow:returnerrOverflowcaseerrCodeReserved:returnerrReservedcaseerrCodeEndGroup:returnerrEndGroupdefault:returnerrParse }}// ConsumeField parses an entire field record (both tag and value) and returns// the field number, the wire type, and the total length.// This returns a negative length upon an error (see ParseError).//// The total length includes the tag header and the end group marker (if the// field is a group).func ( []byte) (Number, Type, int) { , , := ConsumeTag()if < 0 {return0, 0, // forward error code } := ConsumeFieldValue(, , [:])if < 0 {return0, 0, // forward error code }return , , + }// ConsumeFieldValue parses a field value and returns its length.// This assumes that the field Number and wire Type have already been parsed.// This returns a negative length upon an error (see ParseError).//// When parsing a group, the length includes the end group marker and// the end group is verified to match the starting field number.func ( Number, Type, []byte) ( int) {returnconsumeFieldValueD(, , , DefaultRecursionLimit)}func ( Number, Type, []byte, int) ( int) {switch {caseVarintType: _, = ConsumeVarint()returncaseFixed32Type: _, = ConsumeFixed32()returncaseFixed64Type: _, = ConsumeFixed64()returncaseBytesType: _, = ConsumeBytes()returncaseStartGroupType:if < 0 {returnerrCodeRecursionDepth } := len()for { , , := ConsumeTag()if < 0 {return// forward error code } = [:]if == EndGroupType {if != {returnerrCodeEndGroup }return - len() } = (, , , -1)if < 0 {return// forward error code } = [:] }caseEndGroupType:returnerrCodeEndGroupdefault:returnerrCodeReserved }}// AppendTag encodes num and typ as a varint-encoded tag and appends it to b.func ( []byte, Number, Type) []byte {returnAppendVarint(, EncodeTag(, ))}// ConsumeTag parses b as a varint-encoded tag, reporting its length.// This returns a negative length upon an error (see ParseError).func ( []byte) (Number, Type, int) { , := ConsumeVarint()if < 0 {return0, 0, // forward error code } , := DecodeTag()if < MinValidNumber {return0, 0, errCodeFieldNumber }return , , }func ( Number) int {returnSizeVarint(EncodeTag(, 0)) // wire type has no effect on size}// AppendVarint appends v to b as a varint-encoded uint64.func ( []byte, uint64) []byte {switch {case < 1<<7: = append(, byte())case < 1<<14: = append(,byte((>>0)&0x7f|0x80),byte(>>7))case < 1<<21: = append(,byte((>>0)&0x7f|0x80),byte((>>7)&0x7f|0x80),byte(>>14))case < 1<<28: = append(,byte((>>0)&0x7f|0x80),byte((>>7)&0x7f|0x80),byte((>>14)&0x7f|0x80),byte(>>21))case < 1<<35: = append(,byte((>>0)&0x7f|0x80),byte((>>7)&0x7f|0x80),byte((>>14)&0x7f|0x80),byte((>>21)&0x7f|0x80),byte(>>28))case < 1<<42: = append(,byte((>>0)&0x7f|0x80),byte((>>7)&0x7f|0x80),byte((>>14)&0x7f|0x80),byte((>>21)&0x7f|0x80),byte((>>28)&0x7f|0x80),byte(>>35))case < 1<<49: = append(,byte((>>0)&0x7f|0x80),byte((>>7)&0x7f|0x80),byte((>>14)&0x7f|0x80),byte((>>21)&0x7f|0x80),byte((>>28)&0x7f|0x80),byte((>>35)&0x7f|0x80),byte(>>42))case < 1<<56: = append(,byte((>>0)&0x7f|0x80),byte((>>7)&0x7f|0x80),byte((>>14)&0x7f|0x80),byte((>>21)&0x7f|0x80),byte((>>28)&0x7f|0x80),byte((>>35)&0x7f|0x80),byte((>>42)&0x7f|0x80),byte(>>49))case < 1<<63: = append(,byte((>>0)&0x7f|0x80),byte((>>7)&0x7f|0x80),byte((>>14)&0x7f|0x80),byte((>>21)&0x7f|0x80),byte((>>28)&0x7f|0x80),byte((>>35)&0x7f|0x80),byte((>>42)&0x7f|0x80),byte((>>49)&0x7f|0x80),byte(>>56))default: = append(,byte((>>0)&0x7f|0x80),byte((>>7)&0x7f|0x80),byte((>>14)&0x7f|0x80),byte((>>21)&0x7f|0x80),byte((>>28)&0x7f|0x80),byte((>>35)&0x7f|0x80),byte((>>42)&0x7f|0x80),byte((>>49)&0x7f|0x80),byte((>>56)&0x7f|0x80),1) }return}// ConsumeVarint parses b as a varint-encoded uint64, reporting its length.// This returns a negative length upon an error (see ParseError).func ( []byte) ( uint64, int) {varuint64iflen() <= 0 {return0, errCodeTruncated } = uint64([0])if < 0x80 {return , 1 } -= 0x80iflen() <= 1 {return0, errCodeTruncated } = uint64([1]) += << 7if < 0x80 {return , 2 } -= 0x80 << 7iflen() <= 2 {return0, errCodeTruncated } = uint64([2]) += << 14if < 0x80 {return , 3 } -= 0x80 << 14iflen() <= 3 {return0, errCodeTruncated } = uint64([3]) += << 21if < 0x80 {return , 4 } -= 0x80 << 21iflen() <= 4 {return0, errCodeTruncated } = uint64([4]) += << 28if < 0x80 {return , 5 } -= 0x80 << 28iflen() <= 5 {return0, errCodeTruncated } = uint64([5]) += << 35if < 0x80 {return , 6 } -= 0x80 << 35iflen() <= 6 {return0, errCodeTruncated } = uint64([6]) += << 42if < 0x80 {return , 7 } -= 0x80 << 42iflen() <= 7 {return0, errCodeTruncated } = uint64([7]) += << 49if < 0x80 {return , 8 } -= 0x80 << 49iflen() <= 8 {return0, errCodeTruncated } = uint64([8]) += << 56if < 0x80 {return , 9 } -= 0x80 << 56iflen() <= 9 {return0, errCodeTruncated } = uint64([9]) += << 63if < 2 {return , 10 }return0, errCodeOverflow}// SizeVarint returns the encoded size of a varint.// The size is guaranteed to be within 1 and 10, inclusive.func ( uint64) int {// This computes 1 + (bits.Len64(v)-1)/7. // 9/64 is a good enough approximation of 1/7returnint(9*uint32(bits.Len64())+64) / 64}// AppendFixed32 appends v to b as a little-endian uint32.func ( []byte, uint32) []byte {returnappend(,byte(>>0),byte(>>8),byte(>>16),byte(>>24))}// ConsumeFixed32 parses b as a little-endian uint32, reporting its length.// This returns a negative length upon an error (see ParseError).func ( []byte) ( uint32, int) {iflen() < 4 {return0, errCodeTruncated } = uint32([0])<<0 | uint32([1])<<8 | uint32([2])<<16 | uint32([3])<<24return , 4}// SizeFixed32 returns the encoded size of a fixed32; which is always 4.func () int {return4}// AppendFixed64 appends v to b as a little-endian uint64.func ( []byte, uint64) []byte {returnappend(,byte(>>0),byte(>>8),byte(>>16),byte(>>24),byte(>>32),byte(>>40),byte(>>48),byte(>>56))}// ConsumeFixed64 parses b as a little-endian uint64, reporting its length.// This returns a negative length upon an error (see ParseError).func ( []byte) ( uint64, int) {iflen() < 8 {return0, errCodeTruncated } = uint64([0])<<0 | uint64([1])<<8 | uint64([2])<<16 | uint64([3])<<24 | uint64([4])<<32 | uint64([5])<<40 | uint64([6])<<48 | uint64([7])<<56return , 8}// SizeFixed64 returns the encoded size of a fixed64; which is always 8.func () int {return8}// AppendBytes appends v to b as a length-prefixed bytes value.func ( []byte, []byte) []byte {returnappend(AppendVarint(, uint64(len())), ...)}// ConsumeBytes parses b as a length-prefixed bytes value, reporting its length.// This returns a negative length upon an error (see ParseError).func ( []byte) ( []byte, int) { , := ConsumeVarint()if < 0 {returnnil, // forward error code }if > uint64(len([:])) {returnnil, errCodeTruncated }return [:][:], + int()}// SizeBytes returns the encoded size of a length-prefixed bytes value,// given only the length.func ( int) int {returnSizeVarint(uint64()) + }// AppendString appends v to b as a length-prefixed bytes value.func ( []byte, string) []byte {returnappend(AppendVarint(, uint64(len())), ...)}// ConsumeString parses b as a length-prefixed bytes value, reporting its length.// This returns a negative length upon an error (see ParseError).func ( []byte) ( string, int) { , := ConsumeBytes()returnstring(), }// AppendGroup appends v to b as group value, with a trailing end group marker.// The value v must not contain the end marker.func ( []byte, Number, []byte) []byte {returnAppendVarint(append(, ...), EncodeTag(, EndGroupType))}// ConsumeGroup parses b as a group value until the trailing end group marker,// and verifies that the end marker matches the provided num. The value v// does not contain the end marker, while the length does contain the end marker.// This returns a negative length upon an error (see ParseError).func ( Number, []byte) ( []byte, int) { = ConsumeFieldValue(, StartGroupType, )if < 0 {returnnil, // forward error code } = [:]// Truncate off end group marker, but need to handle denormalized varints. // Assuming end marker is never 0 (which is always the case since // EndGroupType is non-zero), we can truncate all trailing bytes where the // lower 7 bits are all zero (implying that the varint is denormalized).forlen() > 0 && [len()-1]&0x7f == 0 { = [:len()-1] } = [:len()-SizeTag()]return , }// SizeGroup returns the encoded size of a group, given only the length.func ( Number, int) int {return + SizeTag()}// DecodeTag decodes the field Number and wire Type from its unified form.// The Number is -1 if the decoded field number overflows int32.// Other than overflow, this does not check for field number validity.func ( uint64) (Number, Type) {// NOTE: MessageSet allows for larger field numbers than normal.if >>3 > uint64(math.MaxInt32) {return -1, 0 }returnNumber( >> 3), Type( & 7)}// EncodeTag encodes the field Number and wire Type into its unified form.func ( Number, Type) uint64 {returnuint64()<<3 | uint64(&7)}// DecodeZigZag decodes a zig-zag-encoded uint64 as an int64.//// Input: {…, 5, 3, 1, 0, 2, 4, 6, …}// Output: {…, -3, -2, -1, 0, +1, +2, +3, …}func ( uint64) int64 {returnint64(>>1) ^ int64()<<63>>63}// EncodeZigZag encodes an int64 as a zig-zag-encoded uint64.//// Input: {…, -3, -2, -1, 0, +1, +2, +3, …}// Output: {…, 5, 3, 1, 0, 2, 4, 6, …}func ( int64) uint64 {returnuint64(<<1) ^ uint64(>>63)}// DecodeBool decodes a uint64 as a bool.//// Input: { 0, 1, 2, …}// Output: {false, true, true, …}func ( uint64) bool {return != 0}// EncodeBool encodes a bool as a uint64.//// Input: {false, true}// Output: { 0, 1}func ( bool) uint64 {if {return1 }return0}
The pages are generated with Goldsv0.4.9. (GOOS=linux GOARCH=amd64)