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 protowire

import (
	
	
	

	
)
Number represents the field number.
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 {
	return MinValidNumber <=  &&  < FirstReservedNumber || LastReservedNumber <  &&  <= MaxValidNumber
}
Type represents the wire type.
type Type int8

const (
	VarintType     Type = 0
	Fixed32Type    Type = 5
	Fixed64Type    Type = 1
	BytesType      Type = 2
	StartGroupType Type = 3
	EndGroupType   Type = 4
)

const (
	_ = -iota
	errCodeTruncated
	errCodeFieldNumber
	errCodeOverflow
	errCodeReserved
	errCodeEndGroup
)

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 {
		return nil
	}
	switch  {
	case errCodeTruncated:
		return io.ErrUnexpectedEOF
	case errCodeFieldNumber:
		return errFieldNumber
	case errCodeOverflow:
		return errOverflow
	case errCodeReserved:
		return errReserved
	case errCodeEndGroup:
		return errEndGroup
	default:
		return errParse
	}
}
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 {
		return 0, 0,  // forward error code
	}
	 := ConsumeFieldValue(, , [:])
	if  < 0 {
		return 0, 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) {
	switch  {
	case VarintType:
		_,  = ConsumeVarint()
		return 
	case Fixed32Type:
		_,  = ConsumeFixed32()
		return 
	case Fixed64Type:
		_,  = ConsumeFixed64()
		return 
	case BytesType:
		_,  = ConsumeBytes()
		return 
	case StartGroupType:
		 := len()
		for {
			, ,  := ConsumeTag()
			if  < 0 {
				return  // forward error code
			}
			 = [:]
			if  == EndGroupType {
				if  !=  {
					return errCodeEndGroup
				}
				return  - len()
			}

			 = (, , )
			if  < 0 {
				return  // forward error code
			}
			 = [:]
		}
	case EndGroupType:
		return errCodeEndGroup
	default:
		return errCodeReserved
	}
}
AppendTag encodes num and typ as a varint-encoded tag and appends it to b.
func ( []byte,  Number,  Type) []byte {
	return AppendVarint(, 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 {
		return 0, 0,  // forward error code
	}
	,  := DecodeTag()
	if  < MinValidNumber {
		return 0, 0, errCodeFieldNumber
	}
	return , , 
}

func ( Number) int {
	return SizeVarint(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) {
	var  uint64
	if len() <= 0 {
		return 0, errCodeTruncated
	}
	 = uint64([0])
	if  < 0x80 {
		return , 1
	}
	 -= 0x80

	if len() <= 1 {
		return 0, errCodeTruncated
	}
	 = uint64([1])
	 +=  << 7
	if  < 0x80 {
		return , 2
	}
	 -= 0x80 << 7

	if len() <= 2 {
		return 0, errCodeTruncated
	}
	 = uint64([2])
	 +=  << 14
	if  < 0x80 {
		return , 3
	}
	 -= 0x80 << 14

	if len() <= 3 {
		return 0, errCodeTruncated
	}
	 = uint64([3])
	 +=  << 21
	if  < 0x80 {
		return , 4
	}
	 -= 0x80 << 21

	if len() <= 4 {
		return 0, errCodeTruncated
	}
	 = uint64([4])
	 +=  << 28
	if  < 0x80 {
		return , 5
	}
	 -= 0x80 << 28

	if len() <= 5 {
		return 0, errCodeTruncated
	}
	 = uint64([5])
	 +=  << 35
	if  < 0x80 {
		return , 6
	}
	 -= 0x80 << 35

	if len() <= 6 {
		return 0, errCodeTruncated
	}
	 = uint64([6])
	 +=  << 42
	if  < 0x80 {
		return , 7
	}
	 -= 0x80 << 42

	if len() <= 7 {
		return 0, errCodeTruncated
	}
	 = uint64([7])
	 +=  << 49
	if  < 0x80 {
		return , 8
	}
	 -= 0x80 << 49

	if len() <= 8 {
		return 0, errCodeTruncated
	}
	 = uint64([8])
	 +=  << 56
	if  < 0x80 {
		return , 9
	}
	 -= 0x80 << 56

	if len() <= 9 {
		return 0, errCodeTruncated
	}
	 = uint64([9])
	 +=  << 63
	if  < 2 {
		return , 10
	}
	return 0, errCodeOverflow
}
SizeVarint returns the encoded size of a varint. The size is guaranteed to be within 1 and 10, inclusive.
This computes 1 + (bits.Len64(v)-1)/7. 9/64 is a good enough approximation of 1/7
	return int(9*uint32(bits.Len64())+64) / 64
}
AppendFixed32 appends v to b as a little-endian uint32.
func ( []byte,  uint32) []byte {
	return append(,
		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) {
	if len() < 4 {
		return 0, errCodeTruncated
	}
	 = uint32([0])<<0 | uint32([1])<<8 | uint32([2])<<16 | uint32([3])<<24
	return , 4
}
SizeFixed32 returns the encoded size of a fixed32; which is always 4.
func () int {
	return 4
}
AppendFixed64 appends v to b as a little-endian uint64.
func ( []byte,  uint64) []byte {
	return append(,
		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) {
	if len() < 8 {
		return 0, errCodeTruncated
	}
	 = uint64([0])<<0 | uint64([1])<<8 | uint64([2])<<16 | uint64([3])<<24 | uint64([4])<<32 | uint64([5])<<40 | uint64([6])<<48 | uint64([7])<<56
	return , 8
}
SizeFixed64 returns the encoded size of a fixed64; which is always 8.
func () int {
	return 8
}
AppendBytes appends v to b as a length-prefixed bytes value.
func ( []byte,  []byte) []byte {
	return append(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 {
		return nil,  // forward error code
	}
	if  > uint64(len([:])) {
		return nil, errCodeTruncated
	}
	return [:][:],  + int()
}
SizeBytes returns the encoded size of a length-prefixed bytes value, given only the length.
func ( int) int {
	return SizeVarint(uint64()) + 
}
AppendString appends v to b as a length-prefixed bytes value.
func ( []byte,  string) []byte {
	return append(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()
	return string(), 
}
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 {
	return AppendVarint(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 {
		return nil,  // 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).
	for len() > 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.
NOTE: MessageSet allows for larger field numbers than normal.
	if >>3 > uint64(math.MaxInt32) {
		return -1, 0
	}
	return Number( >> 3), Type( & 7)
}
EncodeTag encodes the field Number and wire Type into its unified form.
func ( Number,  Type) uint64 {
	return uint64()<<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 {
	return int64(>>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 {
	return uint64(<<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  {
		return 1
	}
	return 0