protoresolve

package
v2.0.0-beta.1 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2024 License: Apache-2.0 Imports: 14 Imported by: 0

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:

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

View Source
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.

View Source
const (
	DescriptorKindUnknown = DescriptorKind(iota)
	DescriptorKindFile
	DescriptorKindMessage
	DescriptorKindField
	DescriptorKindOneof
	DescriptorKindEnum
	DescriptorKindEnumValue
	DescriptorKindExtension
	DescriptorKindService
	DescriptorKindMethod
)

The various supported DescriptorKind values.

Variables

View Source
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
)
View Source
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

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

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

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

func NewNotFoundError[T ~string](name T) error

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

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

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

func (r *Registry) AsTypePool() TypePool

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) NumFiles

func (r *Registry) NumFiles() int

NumFiles implements part of the FilePool 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

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

func Combine(res ...Resolver) Resolver

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).

func (TypeKind) String

func (k TypeKind) String() string

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

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)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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