protofmt

package
v0.7.2 Latest Latest
Warning

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

Go to latest
Published: Jun 10, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package protofmt provides descriptor-aware PROTO and ENUM formatting plugins for spanvalue format configs.

The plugins in this package are opt-in. They are intended for display paths where protobuf descriptors are available, such as CLI table output. They do not change spanvalue preset defaults and do not replace descriptor-free SQL literal fallbacks such as github.com/apstndb/spanvalue.FormatProtoAsCast and github.com/apstndb/spanvalue.FormatEnumAsCast.

Generated protobuf types can be resolved through google.golang.org/protobuf/reflect/protoregistry.GlobalTypes when their generated packages are imported and linked into the binary, including by blank import.

To enable descriptor-aware display, clone an existing spanvalue format preset and prepend FormatProtoTextValue and FormatEnumNameValue before the preset's existing plugins. See the package examples for the minimal pattern.

Example (SpannerCLICompatibleFormatConfigWithProto)
package main

import (
	"fmt"

	"github.com/apstndb/spanvalue"
	"github.com/apstndb/spanvalue/gcvctor"
	"github.com/apstndb/spanvalue/protofmt"
	"google.golang.org/protobuf/reflect/protoregistry"
	"google.golang.org/protobuf/types/descriptorpb"
)

func main() {
	var fds *descriptorpb.FileDescriptorSet
	// Load fds in the application, for example from a descriptor set produced
	// with imports included. A nil fds is valid: it creates an empty resolver,
	// so the plugins fall through to the preset's descriptor-free formatting.
	dynamicResolver, err := protofmt.ProtoEnumResolverFromFileDescriptorSet(fds)
	if err != nil {
		panic(err)
	}

	resolver := protofmt.ComposeProtoEnumResolvers(
		dynamicResolver,
		protoregistry.GlobalTypes, // for generated protobuf packages linked into the binary
	)

	fc := spanvalue.SpannerCLICompatibleFormatConfig().Clone()
	fc.FormatComplexPlugins = append(
		[]spanvalue.FormatComplexFunc{
			protofmt.FormatProtoTextValue(protofmt.ProtoTextValueOptions{Resolver: resolver}),
			protofmt.FormatEnumNameValue(protofmt.EnumNameValueOptions{Resolver: resolver}),
		},
		fc.FormatComplexPlugins...,
	)

	out, err := fc.FormatToplevelColumn(gcvctor.EnumValue(
		"google.protobuf.FieldDescriptorProto.Type",
		int64(descriptorpb.FieldDescriptorProto_TYPE_STRING.Number()),
	))
	if err != nil {
		panic(err)
	}
	fmt.Println(out)
}
Output:
TYPE_STRING

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatEnumNameValue

func FormatEnumNameValue(opts EnumNameValueOptions) spanvalue.FormatComplexFunc

FormatEnumNameValue returns a spanvalue plugin that formats Spanner ENUM values as enum value names when opts.Resolver can resolve the enum type and value number.

The plugin returns spanvalue.ErrFallthrough for non-ENUM values, nil or missing resolvers, empty type names, and missing enum types. Typed NULL ENUM values return spanvalue.Formatter.GetNullString without consulting the resolver. Known enum types with unknown or out-of-range numeric values return the original numeric string.

func FormatProtoTextValue

func FormatProtoTextValue(opts ProtoTextValueOptions) spanvalue.FormatComplexFunc

FormatProtoTextValue returns a spanvalue plugin that formats Spanner PROTO values as protobuf text format when opts.Resolver can resolve the message type.

The plugin returns spanvalue.ErrFallthrough for non-PROTO values, nil or missing resolvers, empty type names, and missing message types. Typed NULL PROTO values return spanvalue.Formatter.GetNullString without consulting the resolver. Malformed non-NULL wire payloads, base64 decode failures, unmarshal failures, and marshal failures are returned as real errors.

Protobuf text output is display-oriented and intentionally not stable. Tests and callers must not depend on byte-for-byte stable output.

Types

type EnumNameValueOptions

type EnumNameValueOptions struct {
	Resolver EnumResolver
}

EnumNameValueOptions configures FormatEnumNameValue.

type EnumResolver

type EnumResolver interface {
	FindEnumByName(protoreflect.FullName) (protoreflect.EnumType, error)
}

EnumResolver resolves protobuf enum types for descriptor-aware Spanner ENUM display.

type ProtoEnumResolver

ProtoEnumResolver resolves protobuf message, extension, and enum types for descriptor-aware Spanner PROTO and ENUM display.

func ComposeProtoEnumResolvers

func ComposeProtoEnumResolvers(resolvers ...ProtoEnumResolver) ProtoEnumResolver

ComposeProtoEnumResolvers returns a resolver that tries resolvers in order.

Nil resolvers are skipped. Lookup continues only when a resolver returns the exact protoregistry.NotFound sentinel; wrapped NotFound errors are returned as ordinary errors. If no resolver finds a type, the composed resolver returns exact protoregistry.NotFound.

func ProtoEnumResolverFromFileDescriptorSet

func ProtoEnumResolverFromFileDescriptorSet(fds *descriptorpb.FileDescriptorSet) (ProtoEnumResolver, error)

ProtoEnumResolverFromFileDescriptorSet builds a dynamic protobuf resolver from fds.

A nil fds returns an empty resolver with nil error. Non-nil descriptor sets must be self-contained enough for protodesc.NewFiles to resolve imports. Reading .proto files, fetching remote descriptors, invoking compilers, and merging descriptor sets are application responsibilities.

type ProtoTextValueOptions

type ProtoTextValueOptions struct {
	Resolver  ProtoEnumResolver
	Unmarshal proto.UnmarshalOptions
	Marshal   prototext.MarshalOptions
}

ProtoTextValueOptions configures FormatProtoTextValue.

Resolver is authoritative: FormatProtoTextValue copies Unmarshal and Marshal, then overwrites both local Resolver fields from Resolver without mutating caller-owned options.

Jump to

Keyboard shortcuts

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