Documentation ¶
Overview ¶
Package protoresolve contains named types for various kinds of resolvers for use with Protobuf reflection.
Overview ¶
The core protobuf runtime API (provided by the google.golang.org/protobuf module) accepts resolvers for a number of things, such as unmarshalling from binary, JSON, and text formats and for creating protoreflect.FileDescriptor instances from *descriptorpb.FileDescriptorProto instances. However, it uses anonymous interface types for many of these cases. This package provides named types, useful for more compact parameter and field declarations as well as type assertions.
The core protobuf runtime API also includes two resolver implementations:
- *protoregistry.Files: for resolving descriptors.
- *protoregistry.Types: for resolving types.
When using descriptors, such that all types are dynamic, using the above two types requires double the work to register everything with both. The first must be used in order to process FileDescriptorProto instances into more useful FileDescriptor instances, and the second must be used to create a resolver that the other APIs accept.
The Registry type in this package, on the other hand, allows callers to register descriptors once, and the result can automatically be used as a type registry, too, with all dynamic types.
This package also provides functions for composition: layering resolvers such that one is tried first (the "preferred" resolver), and then others can be used if the first fails to resolve. This is useful to blend known and unknown types. (See Combine.)
You can use the Resolver interface in this package with the existing global registries (protoregistry.GlobalFiles and protoregistry.GlobalTypes) via the GlobalDescriptors value. This implements Resolver and is backed by these two global registries.
The next sections describe the taxonomy of elements in this package.
Resolvers ¶
Named resolver interfaces make up the majority of exported elements in this package. This provides nominal types so that type declarations (like in function parameters and return types) and type assertions can be more compact and readable without requiring packages redefine their own, small named types.
There are two broad classes of resolvers: those that provide *descriptors* and those that provide *types*. A resolver that provides types is the marriage of descriptors with Go's type system and generated types. A resolver that provides types might be able to return information about generated message structs. Whereas a resolver that provides descriptors can only return message descriptors and nothing that binds that message to a Go type. The bridge between the two is the dynamicpb package, which can generate dynamic types to represent a descriptor.
In this package, resolvers that provide types generally have "Type" or "TypeResolver" in their name. The other interfaces provide descriptors.
Below are the interfaces that are expected to be used the most:
Resolver: This provides an interface similar to that of protoregistry.Files except that it is broader and includes typed accessors for looking up descriptors. So instead of just the generic FindDescriptorByName, it also provides FindMessageDescriptorByName.
FileResolver & DescriptorResolver: These two interfaces are implemented by both Resolver implementations and the protoregistry.Files. So this can be used as a parameter type, and callers of the function could provide either (or some other implementation of just the necessary methods).
SerializationResolver: This kind of resolver is used for marshalling and unmarshalling Protobuf data. It provides types for messages and extensions. When marshalling or unmarshalling a message to/from JSON, for example, the contents of google.protobuf.Any messages must be resolved into descriptors in order to correctly transcode the data to JSON. When unmarshalling from the Protobuf binary format, tag numbers must be resolved into field and extension descriptors in order for the data to be interpreted.
The Resolver interface implements most of the other smaller resolver interfaces that provide descriptors. And it also includes an AsTypeResolver method, so it can be converted to a resolver that provides types.
Pools ¶
A pool is a special kind of resolver that can also be used to enumerate known elements. There are three kinds of pools:
- FilePool: A file pool allows enumeration of all file descriptors therein.
- ExtensionPool: An extension pool allows enumeration of all known extensions.
- TypePool: A type pool allows enumeration of all known types -- messages, enums, and extensions.
The latter provides types; both of the former provide descriptors.
Registries ¶
A registry is a special kind of pool that allows new entries to be registered. It is basically a mutable pool. There are two kinds of registries in this package:
- TypeRegistry: This interface allows users to record new types. This package does not actually contain any implementations. Instead, *protoregistry.Types is the recommended implementation.
- DescriptorRegistry: This interface allows users to record new descriptors. This package contains an implementation in the form of *Registry. It is also implemented by *protoregistry.Files.
The *Registry concrete type is a DescriptorRegistry that also provides the full API of the Resolver interface.
Helpers ¶
This package also contains myriad helper functions related to resolving and handling descriptors. Some of them are also useful to actually implement the resolver interfaces (FindExtensionByNumber, ExtensionType, TypeNameFromURL, and TypesFromResolver). And some are adapters, wrapping types that implement one interface to also provide another (ResolverFromPool, ResolverFromPools, TypesFromDescriptorPool, and TypesFromResolver).
Index ¶
- Constants
- Variables
- func CombinePools(res ...) interface{ ... }
- func ExtensionType(ext protoreflect.ExtensionDescriptor) protoreflect.ExtensionType
- func FindDescriptorByNameInFile(file protoreflect.FileDescriptor, sym protoreflect.FullName) protoreflect.Descriptor
- func FindExtensionByNumber(res DescriptorPool, message protoreflect.FullName, ...) protoreflect.ExtensionDescriptor
- func FindExtensionByNumberInFile(file protoreflect.FileDescriptor, message protoreflect.FullName, ...) protoreflect.ExtensionDescriptor
- func NewNotFoundError[T ~string](name T) error
- func RangeExtensionsByMessage(res DescriptorPool, message protoreflect.FullName, ...)
- func RegisterTypesInFile(file protoreflect.FileDescriptor, reg TypeRegistry, kindMask TypeKind) error
- func RegisterTypesInFileRecursive(file protoreflect.FileDescriptor, reg TypeRegistry, kindMask TypeKind) error
- func RegisterTypesInFilesRecursive(files FilePool, reg TypeRegistry, kindMask TypeKind) error
- func ResolverFromPools(descPool DescriptorPool, typePool TypePool) interface{ ... }
- func TypeNameFromURL(url string) protoreflect.FullName
- type DependencyResolver
- type DescriptorKind
- type DescriptorPool
- type DescriptorRegistry
- type DescriptorResolver
- type EnumTypeResolver
- type ErrUnexpectedType
- type ExtensionPool
- type ExtensionResolver
- type ExtensionTypeResolver
- type FilePool
- type FileResolver
- type MessageResolver
- type MessageTypeResolver
- type ProtoFileOracle
- type ProtoFileRegistry
- type ProtoOracle
- type Registry
- func (r *Registry) AsTypePool() TypePool
- func (r *Registry) AsTypeResolver() TypeResolver
- func (r *Registry) FindDescriptorByName(name protoreflect.FullName) (protoreflect.Descriptor, error)
- func (r *Registry) FindExtensionByName(name protoreflect.FullName) (protoreflect.ExtensionDescriptor, error)
- func (r *Registry) FindExtensionByNumber(message protoreflect.FullName, fieldNumber protoreflect.FieldNumber) (protoreflect.ExtensionDescriptor, error)
- func (r *Registry) FindFileByPath(path string) (protoreflect.FileDescriptor, error)
- func (r *Registry) FindMessageByName(name protoreflect.FullName) (protoreflect.MessageDescriptor, error)
- func (r *Registry) FindMessageByURL(url string) (protoreflect.MessageDescriptor, error)
- func (r *Registry) NumFiles() int
- func (r *Registry) NumFilesByPackage(name protoreflect.FullName) int
- func (r *Registry) ProtoFromFileDescriptor(file protoreflect.FileDescriptor) (*descriptorpb.FileDescriptorProto, error)
- func (r *Registry) RangeExtensionsByMessage(message protoreflect.FullName, fn func(protoreflect.ExtensionDescriptor) bool)
- func (r *Registry) RangeFiles(fn func(protoreflect.FileDescriptor) bool)
- func (r *Registry) RangeFilesByPackage(name protoreflect.FullName, fn func(protoreflect.FileDescriptor) bool)
- func (r *Registry) RegisterFile(file protoreflect.FileDescriptor) error
- func (r *Registry) RegisterFileProto(fd *descriptorpb.FileDescriptorProto) (protoreflect.FileDescriptor, error)
- type Resolver
- type SerializationResolver
- type TypeContainer
- type TypeKind
- type TypePool
- type TypeRegistry
- type TypeResolver
Constants ¶
const ( TypeKindMessage = TypeKind(1 << iota) TypeKindEnum TypeKindExtension // TypeKindsAll is a bitmask that represents all types. TypeKindsAll = TypeKindMessage | TypeKindEnum | TypeKindExtension // TypeKindsSerialization includes the kinds of types needed for serialization // and de-serialization: messages (for interpreting google.protobuf.Any messages) // and extensions. These are the same types as supported in a SerializationResolver. TypeKindsSerialization = TypeKindMessage | TypeKindExtension )
The various supported TypeKind values.
const ( DescriptorKindUnknown = DescriptorKind(iota) DescriptorKindFile DescriptorKindMessage DescriptorKindField DescriptorKindOneof DescriptorKindEnum DescriptorKindEnumValue DescriptorKindExtension DescriptorKindService DescriptorKindMethod )
The various supported DescriptorKind values.
Variables ¶
var ( // ErrNotFound is a sentinel error that is returned from resolvers to indicate that the named // element is not known to the registry. It is the same as protoregistry.NotFound. ErrNotFound = protoregistry.NotFound )
var ( // GlobalDescriptors provides a view of protoregistry.GlobalFiles and protoregistry.GlobalTypes // as a Resolver. GlobalDescriptors = ResolverFromPools(protoregistry.GlobalFiles, protoregistry.GlobalTypes) )
Functions ¶
func CombinePools ¶
func CombinePools(res ...interface { Resolver AsTypePool() TypePool }) interface { Resolver AsTypePool() TypePool }
CombinePools is just like Combine, except that the returned value provides am AsTypePool() method that returns a TypePool that iterates through the TypePools of the given resolvers to find and enumerate elements. The AsTypeResolver() method of the returned value will also implement the broader TypePool interface.
func ExtensionType ¶
func ExtensionType(ext protoreflect.ExtensionDescriptor) protoreflect.ExtensionType
ExtensionType returns a protoreflect.ExtensionType for the given descriptor. If the given descriptor implements protoreflect.ExtensionTypeDescriptor, then the corresponding type is returned. Otherwise, a dynamic extension type is returned (created using "google.golang.org/protobuf/types/dynamicpb").
func FindDescriptorByNameInFile ¶
func FindDescriptorByNameInFile(file protoreflect.FileDescriptor, sym protoreflect.FullName) protoreflect.Descriptor
FindDescriptorByNameInFile searches the given file for the element with the given fully-qualified name. This could be used to implement the [DescriptorResolver.FindDescriptorByName] method for a resolver that doesn't want to create an index of all descriptors. This returns nil if no element with the given name belongs to this file.
This does not perform a brute-force search of all elements to find the given name. It breaks up the given name into components and then descends the descriptor hierarchy one element at a time. If the given name does not start with the file's package, it immediately returns nil.
func FindExtensionByNumber ¶
func FindExtensionByNumber(res DescriptorPool, message protoreflect.FullName, field protoreflect.FieldNumber) protoreflect.ExtensionDescriptor
FindExtensionByNumber searches the given descriptor pool for the requested extension. This performs an inefficient search through all files and extensions in the pool. It returns nil if the extension is not found in the file.
func FindExtensionByNumberInFile ¶
func FindExtensionByNumberInFile(file protoreflect.FileDescriptor, message protoreflect.FullName, field protoreflect.FieldNumber) protoreflect.ExtensionDescriptor
FindExtensionByNumberInFile searches all extension in the given file for the requested extension. It returns nil if the extension is not found in the file.
func NewNotFoundError ¶
NewNotFoundError returns an error that wraps ErrNotFound with context indicating the given name as the element that could not be found.
The parameter is generic so that it will accept both plain strings and named string types like protoreflect.FullName.
func RangeExtensionsByMessage ¶
func RangeExtensionsByMessage(res DescriptorPool, message protoreflect.FullName, fn func(descriptor protoreflect.ExtensionDescriptor) bool)
RangeExtensionsByMessage enumerates all extensions in the given descriptor pool that extend the given message. It stops early if the given function returns false.
func RegisterTypesInFile ¶
func RegisterTypesInFile(file protoreflect.FileDescriptor, reg TypeRegistry, kindMask TypeKind) error
RegisterTypesInFile registers all the types (with kinds that match kindMask) with the given registry. Only the types directly in file are registered. This will result in an error if any of the types in the given file are already registered as belonging to a different file.
All types will be dynamic types, created with the "google.golang.org/protobuf/types/dynamicpb" package. The only exception is for extension descriptors that also implement protoreflect.ExtensionTypeDescriptor, in which case the corresponding extension type is used.
func RegisterTypesInFileRecursive ¶
func RegisterTypesInFileRecursive(file protoreflect.FileDescriptor, reg TypeRegistry, kindMask TypeKind) error
RegisterTypesInFileRecursive registers all the types (with kinds that match kindMask) with the given registry, for the given file and all of its transitive dependencies (i.e. its imports, and their imports, etc.). This will result in an error if any of the types in the given file (and its dependencies) are already registered as belonging to a different file.
All types will be dynamic types, created with the "google.golang.org/protobuf/types/dynamicpb" package. The only exception is for extension descriptors that also implement protoreflect.ExtensionTypeDescriptor, in which case the corresponding extension type is used.
func RegisterTypesInFilesRecursive ¶
func RegisterTypesInFilesRecursive(files FilePool, reg TypeRegistry, kindMask TypeKind) error
RegisterTypesInFilesRecursive registers all the types (with kinds that match kindMask) with the given registry, for all files in the given pool and their dependencies. This is essentially shorthand for this:
var err error files.RangeFiles(func(file protoreflect.FileDescriptor) bool { err = protoresolve.RegisterTypesInFileRecursive(file, reg, kindMask) return err == nil }) return err
However, the actual implementation is a little more efficient for cases where some files are imported by many other files.
All types will be dynamic types, created with the "google.golang.org/protobuf/types/dynamicpb" package. The only exception is for extension descriptors that also implement protoreflect.ExtensionTypeDescriptor, in which case the corresponding extension type is used.
func ResolverFromPools ¶
func ResolverFromPools(descPool DescriptorPool, typePool TypePool) interface { Resolver AsTypePool() TypePool }
ResolverFromPools (plural) is just like ResolverFromPool (singular) except it also accepts a TypePool that is used to implement the AsTypeResolver method. So instead of always returning dynamic types based on the given DescriptorPool, it uses the given TypePool.
func TypeNameFromURL ¶
func TypeNameFromURL(url string) protoreflect.FullName
TypeNameFromURL extracts the fully-qualified type name from the given URL. The URL is one that could be used with a google.protobuf.Any message. The last path component is the fully-qualified name.
Types ¶
type DependencyResolver ¶
type DependencyResolver interface { FileResolver DescriptorResolver }
DependencyResolver can resolve dependencies, which is needed when constructing a protoreflect.FileDescriptor from a FileDescriptorProto.
This interface is the same as protodesc.Resolver.
type DescriptorKind ¶
type DescriptorKind int
DescriptorKind represents the kind of a descriptor. Unlike other descriptor-related APIs, DescriptorKind distinguishes between extension fields (DescriptorKindExtension) and "regular", non-extension fields (DescriptorKindField).
func KindOf ¶
func KindOf(d protoreflect.Descriptor) DescriptorKind
KindOf returns the DescriptorKind of the given descriptor d.
func (DescriptorKind) String ¶
func (k DescriptorKind) String() string
String returns a textual representation of k.
type DescriptorPool ¶
type DescriptorPool interface { FilePool DescriptorResolver }
DescriptorPool is a FilePool that also functions as a DescriptorResolver.
type DescriptorRegistry ¶
type DescriptorRegistry interface { DescriptorPool RegisterFile(protoreflect.FileDescriptor) error }
DescriptorRegistry is a file and descriptor resolver that allows the caller to add files (and their contained descriptors) to the set of files and descriptors it can resolve.
type DescriptorResolver ¶
type DescriptorResolver interface {
FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error)
}
DescriptorResolver can resolve descriptors by full name.
type EnumTypeResolver ¶
type EnumTypeResolver interface {
FindEnumByName(enum protoreflect.FullName) (protoreflect.EnumType, error)
}
EnumTypeResolver can resolve enum types. An enum type includes more than just a descriptor but also refers to runtime types (which could be static types generated by the protoc-gen-go plugin).
type ErrUnexpectedType ¶
type ErrUnexpectedType struct { // Only one of URL or Name will be set, depending on whether // the type was looked up by URL or name. These fields indicate // the query that resulted in a descriptor of the wrong type. URL string Name protoreflect.FullName // The kind of descriptor that was expected. Expecting DescriptorKind // The kind of descriptor that was actually found. Actual DescriptorKind // Optional: the descriptor that was actually found. This may // be nil. If non-nil, this is the descriptor instance that // was resolved whose kind is Actual instead of Expecting. Descriptor protoreflect.Descriptor }
ErrUnexpectedType is an error that indicates a descriptor was resolved for a given URL or name, but it is of the wrong type. So a query may have been expecting a service descriptor, for example, but instead the queried name resolved to an extension descriptor.
See NewUnexpectedTypeError.
func NewUnexpectedTypeError ¶
func NewUnexpectedTypeError(expecting DescriptorKind, got protoreflect.Descriptor, url string) *ErrUnexpectedType
NewUnexpectedTypeError constructs a new *ErrUnexpectedType based on the given properties. The last parameter, url, is optional. If empty, the returned error will indicate that the given descriptor's full name as the query.
func (*ErrUnexpectedType) Error ¶
func (e *ErrUnexpectedType) Error() string
Error implements the error interface.
type ExtensionPool ¶
type ExtensionPool interface { ExtensionResolver RangeExtensionsByMessage(message protoreflect.FullName, fn func(protoreflect.ExtensionDescriptor) bool) }
ExtensionPool is an ExtensionResolver that also allows iteration over all extensions for a message.
type ExtensionResolver ¶
type ExtensionResolver interface { FindExtensionByName(protoreflect.FullName) (protoreflect.ExtensionDescriptor, error) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionDescriptor, error) }
ExtensionResolver can resolve extensions based on the containing message name and field number.
type ExtensionTypeResolver ¶
type ExtensionTypeResolver interface { FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) }
ExtensionTypeResolver can resolve extension types. An extension type includes more than just a descriptor but also refers to runtime types (which could be static types generated by the protoc-gen-go plugin).
This interface is the same as protoregistry.ExtensionTypeResolver.
type FilePool ¶
type FilePool interface { FileResolver NumFiles() int RangeFiles(fn func(protoreflect.FileDescriptor) bool) NumFilesByPackage(name protoreflect.FullName) int RangeFilesByPackage(name protoreflect.FullName, fn func(protoreflect.FileDescriptor) bool) }
FilePool is a FileResolver that also allows iteration over the known file descriptors.
type FileResolver ¶
type FileResolver interface {
FindFileByPath(string) (protoreflect.FileDescriptor, error)
}
FileResolver can resolve file descriptors by path.
type MessageResolver ¶
type MessageResolver interface { FindMessageByName(protoreflect.FullName) (protoreflect.MessageDescriptor, error) FindMessageByURL(url string) (protoreflect.MessageDescriptor, error) }
MessageResolver can resolve messages based on their name or a type URL. URLs must include the fully-qualified type name as the last URI path component.
type MessageTypeResolver ¶
type MessageTypeResolver interface { FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) FindMessageByURL(url string) (protoreflect.MessageType, error) }
MessageTypeResolver can resolve message types. A message type includes more than just a descriptor but also refers to runtime types (which could be static types generated by the protoc-gen-go plugin).
This interface is the same as protoregistry.MessageTypeResolver.
type ProtoFileOracle ¶
type ProtoFileOracle interface {
ProtoFromFileDescriptor(file protoreflect.FileDescriptor) (*descriptorpb.FileDescriptorProto, error)
}
ProtoFileOracle can recover a *descriptorpb.FileDescriptorProto for a given protoreflect.FileDescriptor. Implementations may be more efficient than the protodesc package, which re-creates the file descriptor proto each time.
Callers should treat all returned messages as read-only. Mutating any of them could corrupt internal state and invalidate the results of future calls to this method.
type ProtoFileRegistry ¶
type ProtoFileRegistry interface { ProtoFileOracle RegisterFileProto(fd *descriptorpb.FileDescriptorProto) (protoreflect.FileDescriptor, error) }
ProtoFileRegistry is a registry of descriptors that can work directly with descriptor protos. Registering a file requires registering all of its imports first. The registry will then use the registered dependencies to convert the given proto into a protoreflect.FileDescriptor and register the result.
Unlike a normal registry that registers already-built protoreflect.FileDescriptor values, this kind can make the original descriptor proto available to callers (without having to reconstruct it, such as via the protodesc package).
Callers should not mutate the proto after it has been registered, or attempt to re-use the message in a way that could cause it to be mutated. After this registration, the ProtoFileRegistry "owns" the proto.
type ProtoOracle ¶
type ProtoOracle interface { ProtoFileOracle ProtoFromDescriptor(protoreflect.Descriptor) (proto.Message, error) ProtoFromMessageDescriptor(protoreflect.MessageDescriptor) (*descriptorpb.DescriptorProto, error) ProtoFromFieldDescriptor(protoreflect.FieldDescriptor) (*descriptorpb.FieldDescriptorProto, error) ProtoFromOneofDescriptor(protoreflect.OneofDescriptor) (*descriptorpb.OneofDescriptorProto, error) ProtoFromEnumDescriptor(protoreflect.EnumDescriptor) (*descriptorpb.EnumDescriptorProto, error) ProtoFromEnumValueDescriptor(protoreflect.EnumValueDescriptor) (*descriptorpb.EnumValueDescriptorProto, error) ProtoFromServiceDescriptor(protoreflect.ServiceDescriptor) (*descriptorpb.ServiceDescriptorProto, error) ProtoFromMethodDescriptor(protoreflect.MethodDescriptor) (*descriptorpb.MethodDescriptorProto, error) }
ProtoOracle has methods for recovering descriptor proto messages that correspond to given protoreflect.Descriptor instances.
Callers should treat all returned messages as read-only. Mutating any of them could corrupt internal state and invalidate the results of future calls to these methods.
func NewProtoOracle ¶
func NewProtoOracle(fileOracle ProtoFileOracle) ProtoOracle
NewProtoOracle returns a value that can recover all kinds of descriptor proto messages given a function for recovering the file descriptor proto from a protoreflect.FileDescriptor.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry implements the full Resolver interface defined in this package. It is thread-safe and can be used for all kinds of operations where types or descriptors may need to be resolved from names or numbers.
Furthermore, it memoizes the underlying descriptor protos, so one can efficiently recover a FileDescriptorProto for a particular FileDescriptor, without having to fully reconstruct it (which is what the protodesc package does). In order for this to function most efficiently, use Registry.RegisterFileProto to convert the descriptor proto into a protoreflect.FileDescriptor and then use Registry.ProtoFromFileDescriptor to recover the original proto.
func FromFileDescriptorSet ¶
func FromFileDescriptorSet(files *descriptorpb.FileDescriptorSet) (*Registry, error)
FromFileDescriptorSet constructs a *Registry from the given file descriptor set.
func FromFiles ¶
func FromFiles(files *protoregistry.Files) (*Registry, error)
FromFiles returns a new registry that wraps the given files. After creating this registry, callers should not directly use files -- most especially, they should not register any additional descriptors with files and should instead use the RegisterFile method of the returned registry.
This may return an error if the given files includes conflicting extension definitions (i.e. more than one extension for the same extended message and tag number).
If protoregistry.GlobalFiles is supplied, a deep copy is made first. To avoid such a copy, use GlobalDescriptors instead.
func (*Registry) AsTypePool ¶
AsTypePool returns a view of this registry as a TypePool. This offers more methods than AsTypeResolver, providing the ability to enumerate types.
func (*Registry) AsTypeResolver ¶
func (r *Registry) AsTypeResolver() TypeResolver
AsTypeResolver implements part of the Resolver interface.
func (*Registry) FindDescriptorByName ¶
func (r *Registry) FindDescriptorByName(name protoreflect.FullName) (protoreflect.Descriptor, error)
FindDescriptorByName implements part of the Resolver interface.
func (*Registry) FindExtensionByName ¶
func (r *Registry) FindExtensionByName(name protoreflect.FullName) (protoreflect.ExtensionDescriptor, error)
FindExtensionByName implements part of the Resolver interface.
func (*Registry) FindExtensionByNumber ¶
func (r *Registry) FindExtensionByNumber(message protoreflect.FullName, fieldNumber protoreflect.FieldNumber) (protoreflect.ExtensionDescriptor, error)
FindExtensionByNumber implements part of the Resolver interface.
func (*Registry) FindFileByPath ¶
func (r *Registry) FindFileByPath(path string) (protoreflect.FileDescriptor, error)
FindFileByPath implements part of the Resolver interface.
func (*Registry) FindMessageByName ¶
func (r *Registry) FindMessageByName(name protoreflect.FullName) (protoreflect.MessageDescriptor, error)
FindMessageByName implements part of the Resolver interface.
func (*Registry) FindMessageByURL ¶
func (r *Registry) FindMessageByURL(url string) (protoreflect.MessageDescriptor, error)
FindMessageByURL implements part of the Resolver interface.
func (*Registry) NumFilesByPackage ¶
func (r *Registry) NumFilesByPackage(name protoreflect.FullName) int
NumFilesByPackage implements part of the FilePool interface.
func (*Registry) ProtoFromFileDescriptor ¶
func (r *Registry) ProtoFromFileDescriptor(file protoreflect.FileDescriptor) (*descriptorpb.FileDescriptorProto, error)
ProtoFromFileDescriptor recovers the file descriptor proto that corresponds to the given file.
If the given file was created using RegisterFileProto, this will return the original file descriptor proto that was supplied to that method.
Otherwise, a file descriptor proto will be created using the protodesc package. If the file does not already belong to this registry (i.e. was added via RegisterFile), this function will make a best effort attempt to add it. If the addition is successful or if the file already belonged to the registry, the resulting file descriptor proto will be memoized, so the same proto can be returned if this method is ever called again for the same file, without having to reconstruct it.
func (*Registry) RangeExtensionsByMessage ¶
func (r *Registry) RangeExtensionsByMessage(message protoreflect.FullName, fn func(protoreflect.ExtensionDescriptor) bool)
RangeExtensionsByMessage implements part of the Resolver interface.
func (*Registry) RangeFiles ¶
func (r *Registry) RangeFiles(fn func(protoreflect.FileDescriptor) bool)
RangeFiles implements part of the FilePool interface.
func (*Registry) RangeFilesByPackage ¶
func (r *Registry) RangeFilesByPackage(name protoreflect.FullName, fn func(protoreflect.FileDescriptor) bool)
RangeFilesByPackage implements part of the FilePool interface.
func (*Registry) RegisterFile ¶
func (r *Registry) RegisterFile(file protoreflect.FileDescriptor) error
RegisterFile implements part of the Resolver interface.
func (*Registry) RegisterFileProto ¶
func (r *Registry) RegisterFileProto(fd *descriptorpb.FileDescriptorProto) (protoreflect.FileDescriptor, error)
RegisterFileProto registers the given file descriptor proto and returns the corresponding protoreflect.FileDescriptor. All the file's dependencies must have already been registered.
This will retain the given proto message, so calling code should not attempt to mutate it (or re-use it in a way that could mutate it). The given proto message will be supplied to callers of [ProtoFromFileDescriptor], to improve performance and fidelity over use of the protodesc package to recover the descriptor proto.
In general, prefer calling this method instead of calling protodesc.NewFile followed by RegisterFile.
type Resolver ¶
type Resolver interface { DescriptorPool ExtensionPool MessageResolver AsTypeResolver() TypeResolver }
Resolver is a comprehensive resolver interface with methods for resolving all kinds of descriptors.
The AsTypeResolver method returns a view of the resolver as a TypeResolver. In most cases, the returned types will be dynamic types constructed using the resolver's descriptors and the google.golang.org/protobuf/types/dynamicpb package.
func Combine ¶
Combine returns a resolver that iterates through the given resolvers to find elements. The first resolver given is the first one checked, so will always be the preferred resolver. When that returns a protoregistry.NotFound error, the next resolver will be checked, and so on.
The NumFiles and NumFilesByPackage methods only return the number of files reported by the first resolver. (Computing an accurate number of files across all resolvers could be an expensive operation.) However, RangeFiles and RangeFilesByPackage do return files across all resolvers. They emit files for the first resolver first. If any subsequent resolver contains duplicates, they are suppressed such that the callback will only ever be invoked once for a given file path.
func ResolverFromPool ¶
func ResolverFromPool(pool DescriptorPool) Resolver
ResolverFromPool implements the full Resolver interface on top of the given DescriptorPool. This can be used to upgrade a *protoregistry.Files to the Resolver interface. The AsTypeResolver method uses TypesFromResolver, so it returns dynamic types.
See also ResolverFromPools.
type SerializationResolver ¶
type SerializationResolver interface { ExtensionTypeResolver MessageTypeResolver }
SerializationResolver is a named interface that can be used as a resolver for various marshalling and unmarshalling operations. For example it can be used to recognize extensions when unmarshalling the binary format. And it can be used for recognizing extensions and the contents of Any messages when marshalling and unmarshalling the JSON and text formats.
This type can be assigned to the following fields:
- proto.UnmarshalOptions.resolver
- protojson.MarshalOptions.resolver
- protojson.UnmarshalOptions.resolver
- prototext.MarshalOptions.resolver
- prototext.UnmarshalOptions.resolver
type TypeContainer ¶
type TypeContainer interface { Messages() protoreflect.MessageDescriptors Enums() protoreflect.EnumDescriptors Extensions() protoreflect.ExtensionDescriptors }
TypeContainer is a descriptor that contains types. Both protoreflect.FileDescriptor and protoreflect.MessageDescriptor can contain types so both satisfy this interface.
type TypeKind ¶
type TypeKind int
TypeKind represents a category of types that can be registered in a TypeRegistry. The value for a particular kind is a single bit, so a TypeKind value can also represent multiple kinds, by setting multiple bits (by combining values via bitwise-OR).
type TypePool ¶
type TypePool interface { TypeResolver RangeMessages(fn func(protoreflect.MessageType) bool) RangeEnums(fn func(protoreflect.EnumType) bool) RangeExtensions(fn func(protoreflect.ExtensionType) bool) RangeExtensionsByMessage(message protoreflect.FullName, fn func(protoreflect.ExtensionType) bool) }
TypePool is a type resolver that allows for iteration over all known types.
func TypesFromDescriptorPool ¶
func TypesFromDescriptorPool(pool DescriptorPool) TypePool
TypesFromDescriptorPool adapts a descriptor pool into a pool that returns types. This can be used by implementations of Resolver to implement the [Resolver.AsTypeResolver] method.
If the given resolver implements ExtensionResolver, then the returned type pool provides an efficient implementation for the [ExtensionTypeResolver.FindExtensionByNumber] method. Otherwise, it will use an inefficient implementation that searches through all files for the requested extension.
type TypeRegistry ¶
type TypeRegistry interface { TypePool RegisterMessage(protoreflect.MessageType) error RegisterEnum(protoreflect.EnumType) error RegisterExtension(protoreflect.ExtensionType) error }
TypeRegistry is a type resolver that allows the caller to add elements to the set of types it can resolve.
type TypeResolver ¶
type TypeResolver interface { ExtensionTypeResolver MessageTypeResolver EnumTypeResolver }
TypeResolver can resolve all types: extensions, messages, and enums.
func TypesFromResolver ¶
func TypesFromResolver(resolver interface { DescriptorResolver ExtensionResolver }) TypeResolver
TypesFromResolver adapts a resolver that returns descriptors into a resolver that returns types. This can be used by implementations of Resolver to implement the [Resolver.AsTypeResolver] method.
It returns all dynamic types except for extensions, in which case, if an extension implements protoreflect.ExtensionTypeDescriptor, it will return its associated protoreflect.ExtensionType. (Otherwise it returns a dynamic extension.)
If the given value implements DescriptorPool, then the returned value will implement TypePool.
If the given value implements ExtensionPool, then the returned value will implement an additional method:
RangeExtensionsByMessage(message protoreflect.FullName, fn func(protoreflect.ExtensionType) bool)