protopack

package
v0.0.0-...-bb96f36 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 11, 2023 License: BSD-3-Clause Imports: 11 Imported by: 0

Documentation

Overview

Package protopack enables manual encoding and decoding of protobuf wire data.

This package is intended for use in debugging and/or creation of test data. Proper usage of this package requires knowledge of the wire format.

See https://protobuf.dev/programming-guides/encoding.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Bool

type Bool bool

Bool is a boolean.

type Bytes

type Bytes []byte

Bytes is a length-prefixed bytes.

type Denormalized

type Denormalized struct {
	Count uint // number of extra bytes
	Value Token
}

Denormalized is a denormalized varint value, where a varint is encoded using more bytes than is strictly necessary. The number of extra bytes alone is sufficient to losslessly represent the denormalized varint.

The value may be one of Tag, Bool, Varint, Svarint, or Uvarint, where the varint representation of each token is denormalized.

Alternatively, the value may be one of String, Bytes, or LengthPrefix, where the varint representation of the length-prefix is denormalized.

type Float32

type Float32 float32

Float32 is a 32-bit fixed-width floating point number.

type Float64

type Float64 float64

Float64 is a 64-bit fixed-width floating point number.

type Int32

type Int32 int32

Int32 is a signed 32-bit fixed-width integer.

type Int64

type Int64 int64

Int64 is a signed 64-bit fixed-width integer.

type LengthPrefix

type LengthPrefix Message

LengthPrefix is a length-prefixed message.

type Message

type Message []Token

Message is an ordered sequence of Tokens, where certain tokens may contain other tokens. It is functionally a concrete syntax tree that losslessly represents any arbitrary wire data (including invalid input).

func (Message) Format

func (m Message) Format(s fmt.State, r rune)

Format implements a custom formatter to visualize the syntax tree. Using "%#v" formats the Message in Go source code.

func (Message) Marshal

func (m Message) Marshal() []byte

Marshal encodes a syntax tree into the protobuf wire format.

Example message definition:

message MyMessage {
	string field1 = 1;
	int64 field2 = 2;
	repeated float32 field3 = 3;
}

Example encoded message:

b := Message{
	Tag{1, BytesType}, String("Hello, world!"),
	Tag{2, VarintType}, Varint(-10),
	Tag{3, BytesType}, LengthPrefix{
		Float32(1.1), Float32(2.2), Float32(3.3),
	},
}.Marshal()

Resulting wire data:

0x0000  0a 0d 48 65 6c 6c 6f 2c  20 77 6f 72 6c 64 21 10  |..Hello, world!.|
0x0010  f6 ff ff ff ff ff ff ff  ff 01 1a 0c cd cc 8c 3f  |...............?|
0x0020  cd cc 0c 40 33 33 53 40                           |...@33S@|

func (Message) Size

func (m Message) Size() int

Size reports the size in bytes of the marshaled message.

func (*Message) Unmarshal

func (m *Message) Unmarshal(in []byte)

Unmarshal parses the input protobuf wire data as a syntax tree. Any parsing error results in the remainder of the input being concatenated to the message as a Raw type.

Each tag (a tuple of the field number and wire type) encountered is inserted into the syntax tree as a Tag.

The contents of each wire type is mapped to the following Go types:

VarintType   => Uvarint
Fixed32Type  => Uint32
Fixed64Type  => Uint64
BytesType    => Bytes
GroupType    => Message

Since the wire format is not self-describing, this function cannot parse sub-messages and will leave them as the Bytes type. Further manual parsing can be performed as such:

var m, m1, m2 Message
m.Unmarshal(b)
m1.Unmarshal(m[3].(Bytes))
m[3] = LengthPrefix(m1)
m2.Unmarshal(m[3].(LengthPrefix)[1].(Bytes))
m[3].(LengthPrefix)[1] = LengthPrefix(m2)

Unmarshal is useful for debugging the protobuf wire format.

func (*Message) UnmarshalAbductive

func (m *Message) UnmarshalAbductive(in []byte, desc protoreflect.MessageDescriptor)

UnmarshalAbductive is like UnmarshalDescriptor, but infers abductively whether any unknown bytes values is a message based on whether it is a syntactically well-formed message.

Note that the protobuf wire format is not fully self-describing, so abductive inference may attempt to expand a bytes value as a message that is not actually a message. It is a best-effort guess.

func (*Message) UnmarshalDescriptor

func (m *Message) UnmarshalDescriptor(in []byte, desc protoreflect.MessageDescriptor)

UnmarshalDescriptor parses the input protobuf wire data as a syntax tree using the provided message descriptor for more accurate parsing of fields. It operates like Unmarshal, but may use a wider range of Go types to represent the wire data.

The contents of each wire type is mapped to one of the following Go types:

VarintType   => Bool, Varint, Svarint, Uvarint
Fixed32Type  => Int32, Uint32, Float32
Fixed64Type  => Uint32, Uint64, Float64
BytesType    => String, Bytes, LengthPrefix
GroupType    => Message

If the field is unknown, it uses the same mapping as Unmarshal. Known sub-messages are parsed as a Message and packed repeated fields are parsed as a LengthPrefix.

type Number

type Number = protowire.Number

Number is the field number; aliased from the protowire package for convenience.

const (
	MinValidNumber      Number = protowire.MinValidNumber
	FirstReservedNumber Number = protowire.FirstReservedNumber
	LastReservedNumber  Number = protowire.LastReservedNumber
	MaxValidNumber      Number = protowire.MaxValidNumber
)

Number type constants; copied from the protowire package for convenience.

type Raw

type Raw []byte

Raw are bytes directly appended to output.

type String

type String string

String is a length-prefixed string.

type Svarint

type Svarint int64

Svarint is a signed varint using zig-zag encoding.

type Tag

type Tag struct {
	Number Number
	Type   Type
}

Tag is a tuple of the field number and the wire type.

type Token

type Token token

Token is any other type (e.g., Message, Tag, Varint, Float32, etc).

type Type

type Type = protowire.Type

Type is the wire type; aliased from the protowire package for convenience.

const (
	VarintType     Type = protowire.VarintType
	Fixed32Type    Type = protowire.Fixed32Type
	Fixed64Type    Type = protowire.Fixed64Type
	BytesType      Type = protowire.BytesType
	StartGroupType Type = protowire.StartGroupType
	EndGroupType   Type = protowire.EndGroupType
)

Wire type constants; copied from the protowire package for convenience.

type Uint32

type Uint32 uint32

Uint32 is an unsigned 32-bit fixed-width integer.

type Uint64

type Uint64 uint64

Uint64 is an unsigned 64-bit fixed-width integer.

type Uvarint

type Uvarint uint64

Uvarint is a unsigned varint.

type Varint

type Varint int64

Varint is a signed varint using 64-bit two's complement encoding.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL