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 ¶
type ProtoEnumResolver interface {
protoregistry.MessageTypeResolver
protoregistry.ExtensionTypeResolver
EnumResolver
}
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.