protowrap

package
v2.0.0-...-c9ae7ca Latest Latest
Warning

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

Go to latest
Published: Feb 7, 2024 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package protowrap contains types and utilities related to wrapping descriptors and descriptor protos. It has two categories of wrappers, described below.

Wrapping descriptor protos

The main implementations of protoreflect.Descriptor in the core protobuf runtime API are a separate model from the descriptor proto messages from which they were created. One can use the google.golang.org/protobuf/reflect/protodesc package to convert back to a proto, but the transformation is lossy: the resulting proto will not likely be identical to the one originally used to create the descriptor. Also, this is not a cheap operation as the entire FileDescriptorProto hierarchy must be re-created with each conversion.

The ProtoWrapper and related types (FileWrapper, MessageWrapper, etc) in this package are different. They *wrap* the descriptor proto from which they were created and provide methods to extract it. This extraction is cheap since nothing must be re-created. (Caution should be used so that callers do not MUTATE the returned protos, as this package does not make defensive copies.) Use the various ProtoFrom*Descriptor functions to extract the proto. If the given descriptor is not a wrapper of any sort, then these functions fall back to using the protodesc package to convert to a proto.

Wrapping descriptors

The second kind of wrapper is a value that wraps a protoreflect.Descriptor and also implements that same interface. This kind of implementation is often an "interceptor" or "decorator", that delegates methods to the wrapped descriptor, but provides some special or additional handling for one or more of the methods. This kind of wrapper implements WrappedDescriptor and provides an Unwrap method from which the underlying descriptor can be recovered.

The FromFileDescriptorProto and FromFileDescriptorSet functions in this package create wrappers of both kinds: the returned descriptors wrap both the core runtime implementation of descriptors as well as the protos from which they are created. So the returned descriptors implement ProtoWrapper, FileWrapper, and WrappedDescriptor.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FromFileDescriptorSet

func FromFileDescriptorSet(files *descriptorpb.FileDescriptorSet) (protoresolve.Resolver, error)

FromFileDescriptorSet is identical to protodesc.NewFiles except that all descriptors registered with the returned resolver will be FileWrapper instances.

func ProtoFromDescriptor

func ProtoFromDescriptor(d protoreflect.Descriptor) proto.Message

ProtoFromDescriptor extracts a descriptor proto from the given "rich" descriptor. For descriptors generated by the compiler, this is an inexpensive and non-lossy operation. Descriptors from other sources however may be expensive (to re-create a proto) and even lossy.

func ProtoFromEnumDescriptor

func ProtoFromEnumDescriptor(d protoreflect.EnumDescriptor) *descriptorpb.EnumDescriptorProto

ProtoFromEnumDescriptor extracts a descriptor proto from the given "rich" descriptor. For enum descriptors generated by the compiler, this is an inexpensive and non-lossy operation. Enum descriptors from other sources however may be expensive (to re-create a proto) and even lossy.

func ProtoFromEnumValueDescriptor

ProtoFromEnumValueDescriptor extracts a descriptor proto from the given "rich" descriptor. For enum value descriptors generated by the compiler, this is an inexpensive and non-lossy operation. Enum value descriptors from other sources however may be expensive (to re-create a proto) and even lossy.

func ProtoFromFieldDescriptor

ProtoFromFieldDescriptor extracts a descriptor proto from the given "rich" descriptor. For field descriptors generated by the compiler, this is an inexpensive and non-lossy operation. Field descriptors from other sources however may be expensive (to re-create a proto) and even lossy.

func ProtoFromFileDescriptor

func ProtoFromFileDescriptor(d protoreflect.FileDescriptor) *descriptorpb.FileDescriptorProto

ProtoFromFileDescriptor extracts a descriptor proto from the given "rich" descriptor. For file descriptors generated by the compiler, this is an inexpensive and non-lossy operation. File descriptors from other sources however may be expensive (to re-create a proto) and even lossy.

func ProtoFromMessageDescriptor

func ProtoFromMessageDescriptor(d protoreflect.MessageDescriptor) *descriptorpb.DescriptorProto

ProtoFromMessageDescriptor extracts a descriptor proto from the given "rich" descriptor. For message descriptors generated by the compiler, this is an inexpensive and non-lossy operation. Message descriptors from other sources however may be expensive (to re-create a proto) and even lossy.

func ProtoFromMethodDescriptor

ProtoFromMethodDescriptor extracts a descriptor proto from the given "rich" descriptor. For method descriptors generated by the compiler, this is an inexpensive and non-lossy operation. Method descriptors from other sources however may be expensive (to re-create a proto) and even lossy.

func ProtoFromOneofDescriptor

ProtoFromOneofDescriptor extracts a descriptor proto from the given "rich" descriptor. For oneof descriptors generated by the compiler, this is an inexpensive and non-lossy operation. Oneof descriptors from other sources however may be expensive (to re-create a proto) and even lossy.

func ProtoFromServiceDescriptor

ProtoFromServiceDescriptor extracts a descriptor proto from the given "rich" descriptor. For service descriptors generated by the compiler, this is an inexpensive and non-lossy operation. Service descriptors from other sources however may be expensive (to re-create a proto) and even lossy.

func Unwrap

Unwrap unwraps the given descriptor. If it implements WrappedDescriptor, the underlying descriptor is returned. Otherwise, d is returned as is.

func UnwrapEnum

UnwrapEnum unwraps the given enum descriptor. If it implements WrappedDescriptor, the underlying descriptor is returned. Otherwise, ed is returned as is.

func UnwrapEnumValue

UnwrapEnumValue unwraps the given enum value descriptor. If it implements WrappedDescriptor, the underlying descriptor is returned. Otherwise, evd is returned as is.

func UnwrapField

UnwrapField unwraps the given field descriptor. If it implements WrappedDescriptor, the underlying descriptor is returned. Otherwise, fld is returned as is.

func UnwrapFile

UnwrapFile unwraps the given file descriptor. If it implements WrappedDescriptor, the underlying descriptor is returned. Otherwise, fd is returned as is.

func UnwrapMessage

UnwrapMessage unwraps the given message descriptor. If it implements WrappedDescriptor, the underlying descriptor is returned. Otherwise, md is returned as is.

func UnwrapMethod

UnwrapMethod unwraps the given method descriptor. If it implements WrappedDescriptor, the underlying descriptor is returned. Otherwise, mtd is returned as is.

func UnwrapOneof

UnwrapOneof unwraps the given oneof descriptor. If it implements WrappedDescriptor, the underlying descriptor is returned. Otherwise, ood is returned as is.

func UnwrapService

UnwrapService unwraps the given service descriptor. If it implements WrappedDescriptor, the underlying descriptor is returned. Otherwise, sd is returned as is.

Types

type EnumValueWrapper

type EnumValueWrapper interface {
	protoreflect.EnumValueDescriptor
	EnumValueDescriptorProto() *descriptorpb.EnumValueDescriptorProto
}

EnumValueWrapper is a ProtoWrapper for enum values: it implements protoreflect.EnumValueDescriptor and wraps a *descriptorpb.EnumValueDescriptorProto.

type EnumWrapper

type EnumWrapper interface {
	protoreflect.EnumDescriptor
	EnumDescriptorProto() *descriptorpb.EnumDescriptorProto
}

EnumWrapper is a ProtoWrapper for enums: it implements protoreflect.EnumDescriptor and wraps a *descriptorpb.EnumDescriptorProto.

Implementations of this interface should return wrappers from the methods used to access child elements. For example, calling enum.Values().Get(0) should also return an EnumValueWrapper, not just a plain protoreflect.EnumValueDescriptor.

type FieldWrapper

type FieldWrapper interface {
	protoreflect.FieldDescriptor
	FieldDescriptorProto() *descriptorpb.FieldDescriptorProto
}

FieldWrapper is a ProtoWrapper for fields: it implements protoreflect.FieldDescriptor and wraps a *descriptorpb.FieldDescriptorProto.

Implementations of this interface should return wrappers from the methods used to access related elements. For example, calling field.ContainingOneof() should also return a OneofWrapper, not just a plain protoreflect.OneofDescriptor. This may not always be feasible, like if the related element (like the field's message or enum type) is defined in another file that was not created as a FileWrapper.

type FileWrapper

type FileWrapper interface {
	protoreflect.FileDescriptor
	FileDescriptorProto() *descriptorpb.FileDescriptorProto
}

FileWrapper is a ProtoWrapper for files: it implements protoreflect.FileDescriptor and wraps a *descriptorpb.FileDescriptorProto.

Implementations of this interface should return wrappers from the methods used to access child elements. For example, calling file.Messages().Get(0) should also return a MessageWrapper, not just a plain protoreflect.MessageDescriptor.

func AddToRegistry

AddToRegistry converts the given proto to a FileWrapper, using reg to resolve any imports, and also registers the wrapper with reg.

func FromFileDescriptorProto

FromFileDescriptorProto is identical to protodesc.NewFile except that it returns a FileWrapper, not just a protoreflect.FileDescriptor.

type MessageWrapper

type MessageWrapper interface {
	protoreflect.MessageDescriptor
	MessageDescriptorProto() *descriptorpb.DescriptorProto
}

MessageWrapper is a ProtoWrapper for messages: it implements protoreflect.MessageDescriptor and wraps a *descriptorpb.DescriptorProto.

Implementations of this interface should return wrappers from the methods used to access child elements. For example, calling msg.Fields().Get(0) should also return a FieldWrapper, not just a plain protoreflect.FieldDescriptor.

type MethodWrapper

type MethodWrapper interface {
	protoreflect.MethodDescriptor
	MethodDescriptorProto() *descriptorpb.MethodDescriptorProto
}

MethodWrapper is a ProtoWrapper for methods: it implements protoreflect.MethodDescriptor and wraps a *descriptorpb.MethodDescriptorProto.

Implementations of this interface should return wrappers from the methods used to access related elements. For example, calling method.Input() should also return an MessageWrapper, not just a plain protoreflect.MessageDescriptor. However, this may not always be feasible, such as if the message type is defined in another file that was not created as a FileWrapper.

type OneofWrapper

type OneofWrapper interface {
	protoreflect.OneofDescriptor
	OneofDescriptorProto() *descriptorpb.OneofDescriptorProto
}

OneofWrapper is a ProtoWrapper for oneofs: it implements protoreflect.OneofDescriptor and wraps a *descriptorpb.OneofDescriptorProto.

Implementations of this interface should return wrappers from the methods used to access child elements. For example, calling oneof.Fields().Get(0) should also return a FieldWrapper, not just a plain protoreflect.FieldDescriptor.

type ProtoWrapper

type ProtoWrapper interface {
	protoreflect.Descriptor
	// AsProto returns the underlying descriptor proto. The concrete
	// type of the proto message depends on the type of this
	// descriptor:
	//    Descriptor Type        Proto Message Type
	//   ---------------------+------------------------------------
	//    FileDescriptor      |  *descriptorpb.FileDescriptorProto
	//    MessageDescriptor   |  *descriptorpb.DescriptorProto
	//    FieldDescriptor     |  *descriptorpb.FieldDescriptorProto
	//    OneofDescriptor     |  *descriptorpb.OneofDescriptorProto
	//    EnumDescriptor      |  *descriptorpb.EnumDescriptorProto
	//    EnumValueDescriptor |  *descriptorpb.EnumValueDescriptorProto
	//    ServiceDescriptor   |  *descriptorpb.ServiceDescriptorProto
	//    MethodDescriptor    |  *descriptorpb.MethodDescriptorProto
	AsProto() proto.Message
}

ProtoWrapper is a protoreflect.Descriptor that wraps an underlying descriptor proto. It provides the same interface as Descriptor but with one extra operation, to efficiently query for the underlying descriptor proto.

Descriptors that implement this should also implement another method whose specified return type is the concrete type returned by the AsProto method. The name of this method varies by the type of this descriptor:

 Descriptor Type        Other Method Name
---------------------+------------------------------------
 FileDescriptor      |  FileDescriptorProto()
 MessageDescriptor   |  MessageDescriptorProto()
 FieldDescriptor     |  FieldDescriptorProto()
 OneofDescriptor     |  OneOfDescriptorProto()
 EnumDescriptor      |  EnumDescriptorProto()
 EnumValueDescriptor |  EnumValueDescriptorProto()
 ServiceDescriptor   |  ServiceDescriptorProto()
 MethodDescriptor    |  MethodDescriptorProto()

For example, a ProtoWrapper that implements FileDescriptor returns a *descriptorpb.FileDescriptorProto value from its AsProto method and also provides a method with the following signature:

FileDescriptorProto() *descriptorpb.FileDescriptorProto

type ServiceWrapper

type ServiceWrapper interface {
	protoreflect.ServiceDescriptor
	ServiceDescriptorProto() *descriptorpb.ServiceDescriptorProto
}

ServiceWrapper is a ProtoWrapper for services: it implements protoreflect.ServiceDescriptor and wraps a *descriptorpb.ServiceDescriptorProto.

Implementations of this interface should return wrappers from the methods used to access child elements. For example, calling svc.Methods().Get(0) should also return an MethodWrapper, not just a plain protoreflect.MethodDescriptor.

type WrappedDescriptor

type WrappedDescriptor interface {
	Unwrap() protoreflect.Descriptor
}

WrappedDescriptor represents a descriptor that has been wrapped or decorated. Its sole method allows recovery of the underlying, original descriptor.

Jump to

Keyboard shortcuts

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