proto

package
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Jun 30, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package proto defines the foundational interface hierarchy for protobuf messages, following the Interface Segregation Principle (ISP). It provides nine focused, single-method interfaces that each describe one capability of a protobuf message:

  • MarshalAppender: append-style serialization
  • Marshaler: convenience allocation-based serialization
  • Unmarshaler: wire-format deserialization
  • Sizer: deterministic serialized-size pre-computation
  • Merger: protobuf merge semantics
  • Cloner: deep copy with no shared backing memory
  • Resetter: zero-state reset for object reuse
  • Validator: schema constraint validation
  • ProtoReflector: access to runtime reflection metadata

The composite Message interface embeds all nine individual interfaces and represents the full contract that generated message types are expected to satisfy. Consumers should accept the narrowest interface required by their function rather than demanding the full Message contract, following the ISP design principle.

MarshalAppender and Sizer have method signatures structurally identical to their counterparts in the pool package (pool.MarshalAppender and pool.Sizer). Because Go uses structural (duck) typing for interface satisfaction, any concrete type that satisfies one automatically satisfies the other without any import relationship between the two packages.

MessageReflection is a type alias for protoreflect.Message, bridging the proto package's ProtoReflector interface with the full reflection contract defined in the protoreflect package.

Package proto -- equal_field.go contains field-level equality comparison functions for singular, list, and map fields, dispatching on the field kind to handle messages, bytes, floats, enums, and other scalars.

Package proto -- equal_list_map.go contains diff collection functions for list and map fields, producing human-readable difference descriptions with indexed or keyed paths.

Package proto -- equal_message.go contains the top-level Equal and Diff functions, the core reflected message equality comparison, and the diff collection logic with path tracking.

Package proto -- unsafe_options.go defines the UnsafeUnmarshalOptions type for controlling zero-copy string and bytes unmarshal behavior.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Bool

func Bool(v bool) *bool

Bool returns a pointer to a copy of v.

func ClearExtension

func ClearExtension(msg Message, xt *ExtensionType)

ClearExtension clears the extension field on msg, returning it to its default state. It panics if the message's full name does not match the extension's extendee or if the extension's field number is outside the extendee's declared extension ranges.

func Diff

func Diff(a, b Message) string

Diff returns a human-readable string describing all structural differences between two protobuf messages. An empty string means the messages are equal.

func Equal

func Equal(a, b Message) bool

Equal reports whether two messages are structurally equal per protobuf semantics. Both nil arguments means equal. One nil and one non-nil means not equal. Messages with different descriptor full names are not equal (no panic).

Scalar fields are compared by value, enum fields by their integer EnumNumber, bytes fields by content (nil and empty are equivalent), and float fields treat NaN == NaN (protobuf convention). Unknown fields are compared via byte-level equality.

Repeated fields are compared element-by-element in order. Map fields are compared independent of insertion order. Nested message fields are compared recursively. Oneof fields are compared by the active variant and its value.

An unset repeated field and an empty repeated field are considered equal (both have length 0). An unset map field and an empty map field are considered equal (both have length 0).

func Float32

func Float32(v float32) *float32

Float32 returns a pointer to a copy of v.

func Float64

func Float64(v float64) *float64

Float64 returns a pointer to a copy of v.

func GetExtension

func GetExtension(msg Message, xt *ExtensionType) protoreflect.Value

GetExtension returns the value of the extension field on msg. It panics if the message's full name does not match the extension's extendee or if the extension's field number is outside the extendee's declared extension ranges.

func GetOption

func GetOption(optionsMsg Message, xt *ExtensionType) (v protoreflect.Value, err error)

GetOption reads a custom option value from an already-unmarshaled options message. It wraps GetExtension in a deferred panic recovery so that validation failures (wrong message type, out-of-range field number) are returned as errors instead of panics.

If optionsMsg is nil, GetOption returns the zero/default value for the extension's kind and a nil error. This handles the common case where no options were set on a descriptor.

The caller is responsible for constructing and unmarshaling optionsMsg with the appropriate extension resolver before passing it to GetOption. This design avoids import cycles between the proto and dynamicpb packages.

func HasExtension

func HasExtension(msg Message, xt *ExtensionType) bool

HasExtension reports whether the extension field is populated on msg. It panics if the message's full name does not match the extension's extendee or if the extension's field number is outside the extendee's declared extension ranges.

func Int32

func Int32(v int32) *int32

Int32 returns a pointer to a copy of v.

func Int64

func Int64(v int64) *int64

Int64 returns a pointer to a copy of v.

func Merge

func Merge(dst, src Message)

Merge merges all populated fields from src into dst. Scalar fields from src overwrite dst only when populated; bytes fields are defensively copied; repeated fields are appended; map fields merge by key; message fields are recursively merged; unknown fields from src are appended to dst. Merge panics if dst is nil, or if src and dst have different message descriptor full names.

Merge delegates to the fast-path dst.Merge(src) method via the Merger interface, which is embedded in proto.Message and therefore always available. The FullName check here is redundant with the one inside dst.Merge, but provides a consistent panic message at the proto package level.

If src is nil, Merge is a no-op and returns immediately.

func RegisterNewMessageFactory

func RegisterNewMessageFactory(fn func(descriptor.MessageDescriptorAccessor) protoreflect.Message)

RegisterNewMessageFactory sets the factory function used by ExtensionType.New to create message-typed extension zero values. This is called by the dynamicpb package at init time.

func SetExtension

func SetExtension(msg Message, xt *ExtensionType, v protoreflect.Value)

SetExtension sets the value of the extension field on msg. It panics if the message's full name does not match the extension's extendee or if the extension's field number is outside the extendee's declared extension ranges.

func String

func String(v string) *string

String returns a pointer to a copy of v.

func Uint32

func Uint32(v uint32) *uint32

Uint32 returns a pointer to a copy of v.

func Uint64

func Uint64(v uint64) *uint64

Uint64 returns a pointer to a copy of v.

Types

type Cloner

type Cloner interface {
	Clone() Message
}

Cloner is the interface for deep copy. An implementation returns a new Message value that is a complete, independent copy of the receiver. The returned value shares no backing memory with the original; mutations to either do not affect the other. The return type is the composite Message interface so callers can continue to use the full contract on the clone.

type ExtensionType

type ExtensionType struct {
	// contains filtered or unexported fields
}

ExtensionType represents a registered extension field type. It is a value type that wraps a field descriptor and the extendee message descriptor, providing type-safe access to extension metadata and zero-value construction.

func NewExtensionType

NewExtensionType creates an ExtensionType from an extension field descriptor and the message descriptor being extended.

func (ExtensionType) ExtendedType

ExtendedType returns the message descriptor of the message being extended.

func (ExtensionType) IsValidExtension

func (xt ExtensionType) IsValidExtension(msg Message) bool

IsValidExtension reports whether the extension is valid for the given message. It checks that the message's descriptor full name matches the extendee and that the extension's field number falls within the extendee's declared extension ranges.

func (ExtensionType) New

func (xt ExtensionType) New() protoreflect.Value

New returns the zero/default value for the extension field's kind. For scalar kinds it returns the appropriate zero value (0, false, "", nil). For message kinds it returns a new empty dynamic message created via the registered message factory. If no factory is available, it returns an invalid Value.

func (ExtensionType) TypeDescriptor

func (xt ExtensionType) TypeDescriptor() descriptor.FieldDescriptorAccessor

TypeDescriptor returns the extension's field descriptor.

type GetOptionError

type GetOptionError struct {
	PanicValue interface{}
}

GetOptionError represents a recovered panic from GetOption. It wraps the original panic value as context.

func (*GetOptionError) Error

func (e *GetOptionError) Error() string

Error returns a human-readable message for the recovered panic.

type MarshalAppender

type MarshalAppender interface {
	MarshalAppend(b []byte) ([]byte, error)
}

MarshalAppender is the interface for append-style serialization. An implementation appends the serialized form of the receiver to b and returns the extended slice. The error return covers message-level failures such as required fields missing or values out of range.

MarshalAppender has a method signature structurally identical to pool.MarshalAppender. Because Go uses structural typing for interface satisfaction, any concrete type that satisfies proto.MarshalAppender also satisfies pool.MarshalAppender, and vice versa, without any import relationship between the two packages.

type Marshaler

type Marshaler interface {
	Marshal() ([]byte, error)
}

Marshaler is the interface for convenience allocation-based serialization. An implementation allocates and returns a new byte slice containing the serialized form of the receiver.

Marshaler is distinct from pool.Marshaler, which is a composite interface embedding MarshalAppender and Sizer. This interface defines a single method with a different signature and semantics.

type Merger

type Merger interface {
	Merge(src Message) error
}

Merger is the interface for protobuf merge semantics. An implementation merges the fields of src into the receiver: singular fields are overwritten, repeated fields are concatenated, and nested messages are recursively merged. The src parameter is typed as the composite Message interface; implementations may type-assert to their concrete type for performance. The error return covers type mismatch when merging incompatible message types.

type Message

Message is the composite interface that represents the full contract for generated protobuf message types. It embeds all nine individual interfaces: MarshalAppender, Marshaler, Unmarshaler, Sizer, Merger, Cloner, Resetter, Validator, and ProtoReflector. Generated types verify satisfaction via compile-time checks of the form: var _ Message = (*GeneratedType)(nil).

Consumers should accept the narrowest interface needed by their function rather than requiring the full Message contract. For example, a function that only computes serialized size should accept Sizer, not Message. This follows the Interface Segregation Principle (ISP).

func Clone

func Clone(src Message) Message

Clone returns a deep copy of src as a proto.Message. The returned message shares no backing memory with the original: scalars are copied by value, bytes are defensively copied, nested messages are recursively cloned, and lists and maps are deep-copied element by element. Unknown fields are copied via a defensive byte slice copy.

If src is nil, Clone returns nil.

Clone delegates to the fast-path src.Clone() method via the Cloner interface, which is embedded in proto.Message and therefore always available.

The returned Message wraps the same concrete type as the source; callers can type-assert back to the original concrete type.

type MessageReflection

type MessageReflection = protoreflect.Message

MessageReflection is a type alias for protoreflect.Message, the runtime reflection interface for protobuf messages. It provides dynamic access to message fields by descriptor, including reading and writing fields, iterating over populated fields, and accessing oneof and map fields. See the protoreflect package for the full interface contract.

This is a type alias (=), not a new type definition, so existing code referencing proto.MessageReflection remains fully compatible.

type ProtoReflector

type ProtoReflector interface {
	ProtoReflect() MessageReflection
}

ProtoReflector is the interface for access to runtime message reflection and descriptor metadata. An implementation returns a MessageReflection value (which resolves to protoreflect.Message via the type alias) that provides dynamic access to field descriptors, message structure, field reading and writing by descriptor, iteration over populated fields, oneof inspection, and unknown field access. See the protoreflect.Message interface for the full method contract and panic conventions.

type Resetter

type Resetter interface {
	Reset()
}

Resetter is the interface for zero-state reset. An implementation returns the receiver to its zero state, clearing all fields for reuse. Resetter is intended for object pool and reuse patterns where callers reset a message before populating it with new data. Calling Reset on an already-zero message must be a no-op and must not panic.

type Sizer

type Sizer interface {
	Size() int
}

Sizer is the interface for deterministic serialized-size pre-computation. An implementation returns the exact number of bytes the serialized form will occupy, computed without allocations and without performing any encoding. Calling Size multiple times on an unmodified value must return the same result.

Sizer has a method signature structurally identical to pool.Sizer. Because Go uses structural typing for interface satisfaction, any concrete type that satisfies proto.Sizer also satisfies pool.Sizer, and vice versa, without any import relationship between the two packages.

type Unmarshaler

type Unmarshaler interface {
	Unmarshal(b []byte) error
}

Unmarshaler is the interface for wire-format deserialization. An implementation populates the receiver by decoding the wire-format bytes in b. The receiver must be a pointer type; decoding into a nil receiver is invalid. The error return covers malformed wire data, unknown fields policy violations, and truncation.

type UnsafeUnmarshalOptions

type UnsafeUnmarshalOptions struct {
	// ZeroCopyStrings enables zero-copy string and bytes field aliasing.
	// When true, generated UnmarshalUnsafe methods use unsafe.String to
	// create string values that alias the input buffer, and use three-index
	// slices for bytes fields that share the input buffer without copying.
	// When false, UnmarshalUnsafe behaves identically to the standard
	// Unmarshal method with full copies.
	ZeroCopyStrings bool
}

UnsafeUnmarshalOptions controls the behavior of the generated UnmarshalUnsafe method. When ZeroCopyStrings is true, string and bytes fields in the decoded message alias the input byte slice directly instead of copying, eliminating allocation overhead for high-throughput use cases.

Safety contract: when ZeroCopyStrings is true the caller MUST guarantee that the input []byte outlives the message and is not modified while the message is in use. Violation of this contract causes undefined behavior because the message's string and bytes fields will reference the same backing memory as the input buffer.

type Validator

type Validator interface {
	Validate() error
}

Validator is the interface for schema constraint validation. An implementation checks that the message satisfies its schema constraints, including required fields present, values within defined ranges, and string fields valid UTF-8 where required. Validate returns nil if the message is valid, or a descriptive error identifying the first violated constraint.

Jump to

Keyboard shortcuts

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