mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-03-09 13:13:32 +00:00
reflect/protoregistry: add Types registry
The first commit of protoregistry only added a registry for files. However, a separate type of registry is needed to provide a mapping between protobuf names and actual Go types representing those names. Additional high-level API: var GlobalTypes = new(Types) type Type interface{ ... } type Types struct{ ... } func NewTypes(...Type) *Types func (*Types) Register(...Type) error func (*Types) FindEnumByName(pref.FullName) (pref.EnumType, error) func (*Types) FindMessageByName(pref.FullName) (pref.MessageType, error) func (*Types) FindMessageByURL(string) (pref.MessageType, error) func (*Types) FindExtensionByName(pref.FullName) (pref.ExtensionType, error) func (*Types) FindExtensionByNumber(pref.FullName, pref.FieldNumber) (pref.ExtensionType, error) func (*Types) RangeEnums(func(pref.EnumType) bool) func (*Types) RangeMessages(func(pref.MessageType) bool) func (*Types) RangeExtensions(func(pref.ExtensionType) bool) func (*Types) RangeExtensionsByMessage(pref.FullName, func(pref.ExtensionType) bool) Change-Id: I0d07705801684a1eb5853bcd05fcce12598a0047 Reviewed-on: https://go-review.googlesource.com/c/131345 Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
parent
cf25308dea
commit
6e67a1d614
@ -4,9 +4,20 @@
|
||||
|
||||
// Package protoregistry provides data structures to register and lookup
|
||||
// protobuf descriptor types.
|
||||
//
|
||||
// The Files registry contains file descriptors and provides the ability
|
||||
// to iterate over the files or lookup a specific descriptor within the files.
|
||||
// Files only contains protobuf descriptors and has no understanding of Go
|
||||
// type information that may be associated with each descriptor.
|
||||
//
|
||||
// The Types registry contains descriptor types for which there is a known
|
||||
// Go type associated with that descriptor. It provides the ability to iterate
|
||||
// over the registered types or lookup a type by name.
|
||||
package protoregistry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@ -19,33 +30,12 @@ import (
|
||||
// registration issues. This presumes that we provide a way to disable automatic
|
||||
// registration in generated code.
|
||||
|
||||
// TODO: Add a type registry:
|
||||
/*
|
||||
var GlobalTypes = new(Types)
|
||||
|
||||
type Type interface {
|
||||
protoreflect.Descriptor
|
||||
GoType() reflect.Type
|
||||
}
|
||||
type Types struct {
|
||||
Parent *Types
|
||||
Resolver func(url string) (Type, error)
|
||||
}
|
||||
func NewTypes(typs ...Type) *Types
|
||||
func (*Types) Register(typs ...Type) error
|
||||
func (*Types) FindEnumByName(enum protoreflect.FullName) (protoreflect.EnumType, error)
|
||||
func (*Types) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error)
|
||||
func (*Types) FindMessageByURL(url string) (protoreflect.MessageType, error)
|
||||
func (*Types) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
|
||||
func (*Types) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
|
||||
func (*Types) RangeEnums(f func(protoreflect.EnumType) bool)
|
||||
func (*Types) RangeMessages(f func(protoreflect.MessageType) bool)
|
||||
func (*Types) RangeExtensions(f func(protoreflect.ExtensionType) bool)
|
||||
func (*Types) RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool)
|
||||
*/
|
||||
|
||||
// GlobalFiles is a global registry of file descriptors.
|
||||
var GlobalFiles = new(Files)
|
||||
var GlobalFiles *Files = new(Files)
|
||||
|
||||
// GlobalTypes is the registry used by default for type lookups
|
||||
// unless a local registry is provided by the user.
|
||||
var GlobalTypes *Types = new(Types)
|
||||
|
||||
// NotFound is a sentinel error value to indicate that the type was not found.
|
||||
var NotFound = errors.New("not found")
|
||||
@ -298,3 +288,337 @@ func rangeTopLevelDeclarations(fd protoreflect.FileDescriptor, f func(protorefle
|
||||
f(fd.Services().Get(i).Name())
|
||||
}
|
||||
}
|
||||
|
||||
// Type is an interface satisfied by protoreflect.EnumType,
|
||||
// protoreflect.MessageType, or protoreflect.ExtensionType.
|
||||
type Type interface {
|
||||
protoreflect.Descriptor
|
||||
GoType() reflect.Type
|
||||
}
|
||||
|
||||
var (
|
||||
_ Type = protoreflect.EnumType(nil)
|
||||
_ Type = protoreflect.MessageType(nil)
|
||||
_ Type = protoreflect.ExtensionType(nil)
|
||||
)
|
||||
|
||||
// Types is a registry for looking up or iterating over descriptor types.
|
||||
// The Find and Range methods are safe for concurrent use.
|
||||
type Types struct {
|
||||
// Parent sets the parent registry to consult if a find operation
|
||||
// could not locate the appropriate entry.
|
||||
//
|
||||
// Setting a parent results in each Range operation also iterating over the
|
||||
// entries contained within the parent. In such a case, it is possible for
|
||||
// Range to emit duplicates (since they may exist in both child and parent).
|
||||
// Range iteration is guaranteed to iterate over local entries before
|
||||
// iterating over parent entries.
|
||||
Parent *Types
|
||||
|
||||
// Resolver sets the local resolver to consult if the local registry does
|
||||
// not contain an entry. The resolver takes precedence over the parent.
|
||||
//
|
||||
// The url is a URL where the full name of the type is the last segment
|
||||
// of the path (i.e. string following the last '/' character).
|
||||
// When missing a '/' character, the URL is the full name of the type.
|
||||
// See documentation on the google.protobuf.Any.type_url field for details.
|
||||
//
|
||||
// If the resolver returns a result, it is not automatically registered
|
||||
// into the local registry. Thus, a resolver function should cache results
|
||||
// such that it deterministically returns the same result given the
|
||||
// same URL assuming the error returned is nil or NotFound.
|
||||
//
|
||||
// If the resolver returns the NotFound error, the registry will consult the
|
||||
// parent registry if it is set.
|
||||
//
|
||||
// Setting a resolver has no effect on the result of each Range operation.
|
||||
Resolver func(url string) (Type, error)
|
||||
|
||||
// TODO: The syntax of the URL is ill-defined and the protobuf team recently
|
||||
// changed the documented semantics in a way that breaks prior usages.
|
||||
// I do not believe they can do this and need to sync up with the
|
||||
// protobuf team again to hash out what the proper syntax of the URL is.
|
||||
|
||||
// TODO: Should we separate this out as a registry for each type?
|
||||
//
|
||||
// In Java, the extension and message registry are distinct classes.
|
||||
// Their extension registry has knowledge of distinct Java types,
|
||||
// while their message registry only contains descriptor information.
|
||||
//
|
||||
// In Go, we have always registered messages, enums, and extensions.
|
||||
// Messages and extensions are registered with Go information, while enums
|
||||
// are only registered with descriptor information. We cannot drop Go type
|
||||
// information for messages otherwise we would be unable to implement
|
||||
// portions of the v1 API such as ptypes.DynamicAny.
|
||||
//
|
||||
// There is no enum registry in Java. In v1, we used the enum registry
|
||||
// because enum types provided no reflective methods. The addition of
|
||||
// ProtoReflect removes that need.
|
||||
|
||||
typesByName typesByName
|
||||
extensionsByMessage extensionsByMessage
|
||||
}
|
||||
|
||||
type (
|
||||
typesByName map[protoreflect.FullName]Type
|
||||
extensionsByMessage map[protoreflect.FullName]extensionsByNumber
|
||||
extensionsByNumber map[protoreflect.FieldNumber]protoreflect.ExtensionType
|
||||
)
|
||||
|
||||
// NewTypes returns a registry initialized with the provided set of types.
|
||||
// If there are conflicts, the first one takes precedence.
|
||||
func NewTypes(typs ...Type) *Types {
|
||||
// TODO: Allow setting resolver and parent via constructor?
|
||||
r := new(Types)
|
||||
r.Register(typs...) // ignore errors; first takes precedence
|
||||
return r
|
||||
}
|
||||
|
||||
// Register registers the provided list of descriptor types.
|
||||
//
|
||||
// If a registration conflict occurs for enum, message, or extension types
|
||||
// (e.g., two different types have the same full name),
|
||||
// then the first type takes precedence and an error is returned.
|
||||
func (r *Types) Register(typs ...Type) error {
|
||||
var firstErr error
|
||||
typeLoop:
|
||||
for _, typ := range typs {
|
||||
switch typ.(type) {
|
||||
case protoreflect.EnumType, protoreflect.MessageType, protoreflect.ExtensionType:
|
||||
// Check for conflicts in typesByName.
|
||||
name := typ.FullName()
|
||||
if r.typesByName[name] != nil {
|
||||
if firstErr == nil {
|
||||
firstErr = errors.New("%v %v is already registered", typeName(typ), name)
|
||||
}
|
||||
continue typeLoop
|
||||
}
|
||||
|
||||
// Check for conflicts in extensionsByMessage.
|
||||
if xt, _ := typ.(protoreflect.ExtensionType); xt != nil {
|
||||
field := xt.Number()
|
||||
message := xt.ExtendedType().FullName()
|
||||
if r.extensionsByMessage[message][field] != nil {
|
||||
if firstErr == nil {
|
||||
firstErr = errors.New("extension %v is already registered on message %v", name, message)
|
||||
}
|
||||
continue typeLoop
|
||||
}
|
||||
|
||||
// Update extensionsByMessage.
|
||||
if r.extensionsByMessage == nil {
|
||||
r.extensionsByMessage = make(extensionsByMessage)
|
||||
}
|
||||
if r.extensionsByMessage[message] == nil {
|
||||
r.extensionsByMessage[message] = make(extensionsByNumber)
|
||||
}
|
||||
r.extensionsByMessage[message][field] = xt
|
||||
}
|
||||
|
||||
// Update typesByName.
|
||||
if r.typesByName == nil {
|
||||
r.typesByName = make(typesByName)
|
||||
}
|
||||
r.typesByName[name] = typ
|
||||
default:
|
||||
if firstErr == nil {
|
||||
firstErr = errors.New("invalid type: %v", typeName(typ))
|
||||
}
|
||||
}
|
||||
}
|
||||
return firstErr
|
||||
}
|
||||
|
||||
// FindEnumByName looks up an enum by its full name.
|
||||
// E.g., "google.protobuf.Field.Kind".
|
||||
//
|
||||
// This returns (nil, NotFound) if not found.
|
||||
func (r *Types) FindEnumByName(enum protoreflect.FullName) (protoreflect.EnumType, error) {
|
||||
r.globalCheck()
|
||||
if r == nil {
|
||||
return nil, NotFound
|
||||
}
|
||||
v, _ := r.typesByName[enum]
|
||||
if v == nil && r.Resolver != nil {
|
||||
var err error
|
||||
v, err = r.Resolver(string(enum))
|
||||
if err != nil && err != NotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if v != nil {
|
||||
if et, _ := v.(protoreflect.EnumType); et != nil {
|
||||
return et, nil
|
||||
}
|
||||
return nil, errors.New("found wrong type: got %v, want enum", typeName(v))
|
||||
}
|
||||
return r.Parent.FindEnumByName(enum)
|
||||
}
|
||||
|
||||
// FindMessageByName looks up a message by its full name.
|
||||
// E.g., "google.protobuf.Any"
|
||||
//
|
||||
// This return (nil, NotFound) if not found.
|
||||
func (r *Types) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {
|
||||
// The full name by itself is a valid URL.
|
||||
return r.FindMessageByURL(string(message))
|
||||
}
|
||||
|
||||
// FindMessageByURL looks up a message by a URL identifier.
|
||||
// See Resolver for the format of the URL.
|
||||
//
|
||||
// This returns (nil, NotFound) if not found.
|
||||
func (r *Types) FindMessageByURL(url string) (protoreflect.MessageType, error) {
|
||||
r.globalCheck()
|
||||
if r == nil {
|
||||
return nil, NotFound
|
||||
}
|
||||
message := protoreflect.FullName(url)
|
||||
if i := strings.LastIndexByte(url, '/'); i >= 0 {
|
||||
message = message[i+len("/"):]
|
||||
}
|
||||
|
||||
v, _ := r.typesByName[message]
|
||||
if v == nil && r.Resolver != nil {
|
||||
var err error
|
||||
v, err = r.Resolver(url)
|
||||
if err != nil && err != NotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if v != nil {
|
||||
if mt, _ := v.(protoreflect.MessageType); mt != nil {
|
||||
return mt, nil
|
||||
}
|
||||
return nil, errors.New("found wrong type: got %v, want message", typeName(v))
|
||||
}
|
||||
return r.Parent.FindMessageByURL(url)
|
||||
}
|
||||
|
||||
// FindExtensionByName looks up a extension field by the field's full name.
|
||||
// Note that this is the full name of the field as determined by
|
||||
// where the extension is declared and is unrelated to the full name of the
|
||||
// message being extended.
|
||||
//
|
||||
// This returns (nil, NotFound) if not found.
|
||||
func (r *Types) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
|
||||
r.globalCheck()
|
||||
if r == nil {
|
||||
return nil, NotFound
|
||||
}
|
||||
v, _ := r.typesByName[field]
|
||||
if v == nil && r.Resolver != nil {
|
||||
var err error
|
||||
v, err = r.Resolver(string(field))
|
||||
if err != nil && err != NotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if v != nil {
|
||||
if xt, _ := v.(protoreflect.ExtensionType); xt != nil {
|
||||
return xt, nil
|
||||
}
|
||||
return nil, errors.New("found wrong type: got %v, want extension", typeName(v))
|
||||
}
|
||||
return r.Parent.FindExtensionByName(field)
|
||||
}
|
||||
|
||||
// FindExtensionByNumber looks up a extension field by the field number
|
||||
// within some parent message, identified by full name.
|
||||
//
|
||||
// This returns (nil, NotFound) if not found.
|
||||
func (r *Types) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
|
||||
r.globalCheck()
|
||||
if r == nil {
|
||||
return nil, NotFound
|
||||
}
|
||||
if xt, ok := r.extensionsByMessage[message][field]; ok {
|
||||
return xt, nil
|
||||
}
|
||||
return r.Parent.FindExtensionByNumber(message, field)
|
||||
}
|
||||
|
||||
// RangeEnums iterates over all registered enums.
|
||||
// Iteration order is undefined.
|
||||
func (r *Types) RangeEnums(f func(protoreflect.EnumType) bool) {
|
||||
r.globalCheck()
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
for _, typ := range r.typesByName {
|
||||
if et, ok := typ.(protoreflect.EnumType); ok {
|
||||
if !f(et) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Parent.RangeEnums(f)
|
||||
}
|
||||
|
||||
// RangeMessages iterates over all registered messages.
|
||||
// Iteration order is undefined.
|
||||
func (r *Types) RangeMessages(f func(protoreflect.MessageType) bool) {
|
||||
r.globalCheck()
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
for _, typ := range r.typesByName {
|
||||
if mt, ok := typ.(protoreflect.MessageType); ok {
|
||||
if !f(mt) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Parent.RangeMessages(f)
|
||||
}
|
||||
|
||||
// RangeExtensions iterates over all registered extensions.
|
||||
// Iteration order is undefined.
|
||||
func (r *Types) RangeExtensions(f func(protoreflect.ExtensionType) bool) {
|
||||
r.globalCheck()
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
for _, typ := range r.typesByName {
|
||||
if xt, ok := typ.(protoreflect.ExtensionType); ok {
|
||||
if !f(xt) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Parent.RangeExtensions(f)
|
||||
}
|
||||
|
||||
// RangeExtensionsByMessage iterates over all registered extensions filtered
|
||||
// by a given message type. Iteration order is undefined.
|
||||
func (r *Types) RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool) {
|
||||
r.globalCheck()
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
for _, xt := range r.extensionsByMessage[message] {
|
||||
if !f(xt) {
|
||||
return
|
||||
}
|
||||
}
|
||||
r.Parent.RangeExtensionsByMessage(message, f)
|
||||
}
|
||||
|
||||
func (r *Types) globalCheck() {
|
||||
if r == GlobalTypes && (r.Parent != nil || r.Resolver != nil) {
|
||||
panic("GlobalTypes.Parent and GlobalTypes.Resolver cannot be set")
|
||||
}
|
||||
}
|
||||
|
||||
func typeName(t Type) string {
|
||||
switch t.(type) {
|
||||
case protoreflect.EnumType:
|
||||
return "enum"
|
||||
case protoreflect.MessageType:
|
||||
return "message"
|
||||
case protoreflect.ExtensionType:
|
||||
return "extension"
|
||||
default:
|
||||
return fmt.Sprintf("%T", t)
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,13 @@ import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
|
||||
"github.com/golang/protobuf/protoapi"
|
||||
"github.com/golang/protobuf/v2/internal/legacy"
|
||||
pref "github.com/golang/protobuf/v2/reflect/protoreflect"
|
||||
preg "github.com/golang/protobuf/v2/reflect/protoregistry"
|
||||
ptype "github.com/golang/protobuf/v2/reflect/prototype"
|
||||
|
||||
testpb "github.com/golang/protobuf/v2/reflect/protoregistry/testprotos"
|
||||
)
|
||||
|
||||
func TestFiles(t *testing.T) {
|
||||
@ -312,3 +316,357 @@ func TestFiles(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func extensionType(xd *protoapi.ExtensionDesc) pref.ExtensionType {
|
||||
return legacy.Export{}.ExtensionTypeFromDesc(xd)
|
||||
}
|
||||
|
||||
func TestTypes(t *testing.T) {
|
||||
// Suffix 1 in registry, 2 in parent, 3 in resolver.
|
||||
mt1 := (&testpb.Message1{}).ProtoReflect().Type()
|
||||
mt2 := (&testpb.Message2{}).ProtoReflect().Type()
|
||||
mt3 := (&testpb.Message3{}).ProtoReflect().Type()
|
||||
et1 := testpb.Enum1_ONE.ProtoReflect().Type()
|
||||
et2 := testpb.Enum2_UNO.ProtoReflect().Type()
|
||||
et3 := testpb.Enum3_YI.ProtoReflect().Type()
|
||||
// Suffix indicates field number.
|
||||
xt11 := extensionType(testpb.E_StringField)
|
||||
xt12 := extensionType(testpb.E_EnumField)
|
||||
xt13 := extensionType(testpb.E_MessageField)
|
||||
xt21 := extensionType(testpb.E_Message4_MessageField)
|
||||
xt22 := extensionType(testpb.E_Message4_EnumField)
|
||||
xt23 := extensionType(testpb.E_Message4_StringField)
|
||||
parent := &preg.Types{}
|
||||
if err := parent.Register(mt2, et2, xt12, xt22); err != nil {
|
||||
t.Fatalf("parent.Register() returns unexpected error: %v", err)
|
||||
}
|
||||
registry := &preg.Types{
|
||||
Parent: parent,
|
||||
Resolver: func(url string) (preg.Type, error) {
|
||||
switch {
|
||||
case strings.HasSuffix(url, "testprotos.Message3"):
|
||||
return mt3, nil
|
||||
case strings.HasSuffix(url, "testprotos.Enum3"):
|
||||
return et3, nil
|
||||
case strings.HasSuffix(url, "testprotos.message_field"):
|
||||
return xt13, nil
|
||||
case strings.HasSuffix(url, "testprotos.Message4.string_field"):
|
||||
return xt23, nil
|
||||
}
|
||||
return nil, preg.NotFound
|
||||
},
|
||||
}
|
||||
if err := registry.Register(mt1, et1, xt11, xt21); err != nil {
|
||||
t.Fatalf("registry.Register() returns unexpected error: %v", err)
|
||||
}
|
||||
|
||||
t.Run("FindMessageByName", func(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
messageType pref.MessageType
|
||||
wantErr bool
|
||||
wantNotFound bool
|
||||
}{{
|
||||
name: "testprotos.Message1",
|
||||
messageType: mt1,
|
||||
}, {
|
||||
name: "testprotos.Message2",
|
||||
messageType: mt2,
|
||||
}, {
|
||||
name: "testprotos.Message3",
|
||||
messageType: mt3,
|
||||
}, {
|
||||
name: "testprotos.NoSuchMessage",
|
||||
wantErr: true,
|
||||
wantNotFound: true,
|
||||
}, {
|
||||
name: "testprotos.Enum1",
|
||||
wantErr: true,
|
||||
}, {
|
||||
name: "testprotos.Enum2",
|
||||
wantErr: true,
|
||||
}, {
|
||||
name: "testprotos.Enum3",
|
||||
wantErr: true,
|
||||
}}
|
||||
for _, tc := range tests {
|
||||
got, err := registry.FindMessageByName(pref.FullName(tc.name))
|
||||
gotErr := err != nil
|
||||
if gotErr != tc.wantErr {
|
||||
t.Errorf("FindMessageByName(%v) = (_, %v), want error? %t", tc.name, err, tc.wantErr)
|
||||
continue
|
||||
}
|
||||
if tc.wantNotFound && err != preg.NotFound {
|
||||
t.Errorf("FindMessageByName(%v) got error: %v, want NotFound error", tc.name, err)
|
||||
continue
|
||||
}
|
||||
if got != tc.messageType {
|
||||
t.Errorf("FindMessageByName(%v) got wrong value: %v", tc.name, got)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("FindMessageByURL", func(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
messageType pref.MessageType
|
||||
wantErr bool
|
||||
wantNotFound bool
|
||||
}{{
|
||||
name: "testprotos.Message1",
|
||||
messageType: mt1,
|
||||
}, {
|
||||
name: "foo.com/testprotos.Message2",
|
||||
messageType: mt2,
|
||||
}, {
|
||||
name: "/testprotos.Message3",
|
||||
messageType: mt3,
|
||||
}, {
|
||||
name: "type.googleapis.com/testprotos.Nada",
|
||||
wantErr: true,
|
||||
wantNotFound: true,
|
||||
}, {
|
||||
name: "testprotos.Enum1",
|
||||
wantErr: true,
|
||||
}}
|
||||
for _, tc := range tests {
|
||||
got, err := registry.FindMessageByURL(tc.name)
|
||||
gotErr := err != nil
|
||||
if gotErr != tc.wantErr {
|
||||
t.Errorf("FindMessageByURL(%v) = (_, %v), want error? %t", tc.name, err, tc.wantErr)
|
||||
continue
|
||||
}
|
||||
if tc.wantNotFound && err != preg.NotFound {
|
||||
t.Errorf("FindMessageByURL(%v) got error: %v, want NotFound error", tc.name, err)
|
||||
continue
|
||||
}
|
||||
if got != tc.messageType {
|
||||
t.Errorf("FindMessageByURL(%v) got wrong value: %v", tc.name, got)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("FindEnumByName", func(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
enumType pref.EnumType
|
||||
wantErr bool
|
||||
wantNotFound bool
|
||||
}{{
|
||||
name: "testprotos.Enum1",
|
||||
enumType: et1,
|
||||
}, {
|
||||
name: "testprotos.Enum2",
|
||||
enumType: et2,
|
||||
}, {
|
||||
name: "testprotos.Enum3",
|
||||
enumType: et3,
|
||||
}, {
|
||||
name: "testprotos.None",
|
||||
wantErr: true,
|
||||
wantNotFound: true,
|
||||
}, {
|
||||
name: "testprotos.Message1",
|
||||
wantErr: true,
|
||||
}}
|
||||
for _, tc := range tests {
|
||||
got, err := registry.FindEnumByName(pref.FullName(tc.name))
|
||||
gotErr := err != nil
|
||||
if gotErr != tc.wantErr {
|
||||
t.Errorf("FindEnumByName(%v) = (_, %v), want error? %t", tc.name, err, tc.wantErr)
|
||||
continue
|
||||
}
|
||||
if tc.wantNotFound && err != preg.NotFound {
|
||||
t.Errorf("FindEnumByName(%v) got error: %v, want NotFound error", tc.name, err)
|
||||
continue
|
||||
}
|
||||
if got != tc.enumType {
|
||||
t.Errorf("FindEnumByName(%v) got wrong value: %v", tc.name, got)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("FindExtensionByName", func(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
extensionType pref.ExtensionType
|
||||
wantErr bool
|
||||
wantNotFound bool
|
||||
}{{
|
||||
name: "testprotos.string_field",
|
||||
extensionType: xt11,
|
||||
}, {
|
||||
name: "testprotos.enum_field",
|
||||
extensionType: xt12,
|
||||
}, {
|
||||
name: "testprotos.message_field",
|
||||
extensionType: xt13,
|
||||
}, {
|
||||
name: "testprotos.Message4.message_field",
|
||||
extensionType: xt21,
|
||||
}, {
|
||||
name: "testprotos.Message4.enum_field",
|
||||
extensionType: xt22,
|
||||
}, {
|
||||
name: "testprotos.Message4.string_field",
|
||||
extensionType: xt23,
|
||||
}, {
|
||||
name: "testprotos.None",
|
||||
wantErr: true,
|
||||
wantNotFound: true,
|
||||
}, {
|
||||
name: "testprotos.Message1",
|
||||
wantErr: true,
|
||||
}}
|
||||
for _, tc := range tests {
|
||||
got, err := registry.FindExtensionByName(pref.FullName(tc.name))
|
||||
gotErr := err != nil
|
||||
if gotErr != tc.wantErr {
|
||||
t.Errorf("FindExtensionByName(%v) = (_, %v), want error? %t", tc.name, err, tc.wantErr)
|
||||
continue
|
||||
}
|
||||
if tc.wantNotFound && err != preg.NotFound {
|
||||
t.Errorf("FindExtensionByName(%v) got error: %v, want NotFound error", tc.name, err)
|
||||
continue
|
||||
}
|
||||
if got != tc.extensionType {
|
||||
t.Errorf("FindExtensionByName(%v) got wrong value: %v", tc.name, got)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("FindExtensionByNumber", func(t *testing.T) {
|
||||
tests := []struct {
|
||||
parent string
|
||||
number int32
|
||||
extensionType pref.ExtensionType
|
||||
wantErr bool
|
||||
wantNotFound bool
|
||||
}{{
|
||||
parent: "testprotos.Message1",
|
||||
number: 11,
|
||||
extensionType: xt11,
|
||||
}, {
|
||||
parent: "testprotos.Message1",
|
||||
number: 12,
|
||||
extensionType: xt12,
|
||||
}, {
|
||||
// FindExtensionByNumber does not use Resolver.
|
||||
parent: "testprotos.Message1",
|
||||
number: 13,
|
||||
wantErr: true,
|
||||
wantNotFound: true,
|
||||
}, {
|
||||
parent: "testprotos.Message1",
|
||||
number: 21,
|
||||
extensionType: xt21,
|
||||
}, {
|
||||
parent: "testprotos.Message1",
|
||||
number: 22,
|
||||
extensionType: xt22,
|
||||
}, {
|
||||
// FindExtensionByNumber does not use Resolver.
|
||||
parent: "testprotos.Message1",
|
||||
number: 23,
|
||||
wantErr: true,
|
||||
wantNotFound: true,
|
||||
}, {
|
||||
parent: "testprotos.NoSuchMessage",
|
||||
number: 11,
|
||||
wantErr: true,
|
||||
wantNotFound: true,
|
||||
}, {
|
||||
parent: "testprotos.Message1",
|
||||
number: 30,
|
||||
wantErr: true,
|
||||
wantNotFound: true,
|
||||
}, {
|
||||
parent: "testprotos.Message1",
|
||||
number: 99,
|
||||
wantErr: true,
|
||||
wantNotFound: true,
|
||||
}}
|
||||
for _, tc := range tests {
|
||||
got, err := registry.FindExtensionByNumber(pref.FullName(tc.parent), pref.FieldNumber(tc.number))
|
||||
gotErr := err != nil
|
||||
if gotErr != tc.wantErr {
|
||||
t.Errorf("FindExtensionByNumber(%v, %d) = (_, %v), want error? %t", tc.parent, tc.number, err, tc.wantErr)
|
||||
continue
|
||||
}
|
||||
if tc.wantNotFound && err != preg.NotFound {
|
||||
t.Errorf("FindExtensionByNumber(%v, %d) got error %v, want NotFound error", tc.parent, tc.number, err)
|
||||
continue
|
||||
}
|
||||
if got != tc.extensionType {
|
||||
t.Errorf("FindExtensionByNumber(%v, %d) got wrong value: %v", tc.parent, tc.number, got)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
sortTypes := cmpopts.SortSlices(func(x, y preg.Type) bool {
|
||||
return x.FullName() < y.FullName()
|
||||
})
|
||||
compare := cmp.Comparer(func(x, y preg.Type) bool {
|
||||
return x == y
|
||||
})
|
||||
|
||||
t.Run("RangeMessages", func(t *testing.T) {
|
||||
// RangeMessages do not include messages from Resolver.
|
||||
want := []preg.Type{mt1, mt2}
|
||||
var got []preg.Type
|
||||
registry.RangeMessages(func(mt pref.MessageType) bool {
|
||||
got = append(got, mt)
|
||||
return true
|
||||
})
|
||||
|
||||
diff := cmp.Diff(want, got, sortTypes, compare)
|
||||
if diff != "" {
|
||||
t.Errorf("RangeMessages() mismatch (-want +got):\n%v", diff)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("RangeEnums", func(t *testing.T) {
|
||||
// RangeEnums do not include enums from Resolver.
|
||||
want := []preg.Type{et1, et2}
|
||||
var got []preg.Type
|
||||
registry.RangeEnums(func(et pref.EnumType) bool {
|
||||
got = append(got, et)
|
||||
return true
|
||||
})
|
||||
|
||||
diff := cmp.Diff(want, got, sortTypes, compare)
|
||||
if diff != "" {
|
||||
t.Errorf("RangeEnums() mismatch (-want +got):\n%v", diff)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("RangeExtensions", func(t *testing.T) {
|
||||
// RangeExtensions do not include messages from Resolver.
|
||||
want := []preg.Type{xt11, xt12, xt21, xt22}
|
||||
var got []preg.Type
|
||||
registry.RangeExtensions(func(xt pref.ExtensionType) bool {
|
||||
got = append(got, xt)
|
||||
return true
|
||||
})
|
||||
|
||||
diff := cmp.Diff(want, got, sortTypes, compare)
|
||||
if diff != "" {
|
||||
t.Errorf("RangeExtensions() mismatch (-want +got):\n%v", diff)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("RangeExtensionsByMessage", func(t *testing.T) {
|
||||
// RangeExtensions do not include messages from Resolver.
|
||||
want := []preg.Type{xt11, xt12, xt21, xt22}
|
||||
var got []preg.Type
|
||||
registry.RangeExtensionsByMessage(pref.FullName("testprotos.Message1"), func(xt pref.ExtensionType) bool {
|
||||
got = append(got, xt)
|
||||
return true
|
||||
})
|
||||
|
||||
diff := cmp.Diff(want, got, sortTypes, compare)
|
||||
if diff != "" {
|
||||
t.Errorf("RangeExtensionsByMessage() mismatch (-want +got):\n%v", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
582
reflect/protoregistry/testprotos/test.pb.go
Normal file
582
reflect/protoregistry/testprotos/test.pb.go
Normal file
@ -0,0 +1,582 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: reflect/protoregistry/testprotos/test.proto
|
||||
|
||||
package testprotos
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
|
||||
prototype "github.com/golang/protobuf/v2/reflect/prototype"
|
||||
protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type Enum1 int32
|
||||
|
||||
const (
|
||||
Enum1_ONE Enum1 = 1
|
||||
)
|
||||
|
||||
type xxx_Enum1 Enum1
|
||||
|
||||
func (e Enum1) ProtoReflect() protoreflect.Enum {
|
||||
return (xxx_Enum1)(e)
|
||||
}
|
||||
func (e xxx_Enum1) Type() protoreflect.EnumType {
|
||||
return xxx_Test_ProtoFile_EnumTypes[0]
|
||||
}
|
||||
func (e xxx_Enum1) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(e)
|
||||
}
|
||||
|
||||
var Enum1_name = map[int32]string{
|
||||
1: "ONE",
|
||||
}
|
||||
|
||||
var Enum1_value = map[string]int32{
|
||||
"ONE": 1,
|
||||
}
|
||||
|
||||
func (x Enum1) Enum() *Enum1 {
|
||||
p := new(Enum1)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Enum1) String() string {
|
||||
return proto.EnumName(Enum1_name, int32(x))
|
||||
}
|
||||
|
||||
func (x *Enum1) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(Enum1_value, data, "Enum1")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = Enum1(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (Enum1) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_3628d63611f7063d, []int{0}
|
||||
}
|
||||
|
||||
type Enum2 int32
|
||||
|
||||
const (
|
||||
Enum2_UNO Enum2 = 1
|
||||
)
|
||||
|
||||
type xxx_Enum2 Enum2
|
||||
|
||||
func (e Enum2) ProtoReflect() protoreflect.Enum {
|
||||
return (xxx_Enum2)(e)
|
||||
}
|
||||
func (e xxx_Enum2) Type() protoreflect.EnumType {
|
||||
return xxx_Test_ProtoFile_EnumTypes[1]
|
||||
}
|
||||
func (e xxx_Enum2) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(e)
|
||||
}
|
||||
|
||||
var Enum2_name = map[int32]string{
|
||||
1: "UNO",
|
||||
}
|
||||
|
||||
var Enum2_value = map[string]int32{
|
||||
"UNO": 1,
|
||||
}
|
||||
|
||||
func (x Enum2) Enum() *Enum2 {
|
||||
p := new(Enum2)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Enum2) String() string {
|
||||
return proto.EnumName(Enum2_name, int32(x))
|
||||
}
|
||||
|
||||
func (x *Enum2) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(Enum2_value, data, "Enum2")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = Enum2(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (Enum2) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_3628d63611f7063d, []int{1}
|
||||
}
|
||||
|
||||
type Enum3 int32
|
||||
|
||||
const (
|
||||
Enum3_YI Enum3 = 1
|
||||
)
|
||||
|
||||
type xxx_Enum3 Enum3
|
||||
|
||||
func (e Enum3) ProtoReflect() protoreflect.Enum {
|
||||
return (xxx_Enum3)(e)
|
||||
}
|
||||
func (e xxx_Enum3) Type() protoreflect.EnumType {
|
||||
return xxx_Test_ProtoFile_EnumTypes[2]
|
||||
}
|
||||
func (e xxx_Enum3) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(e)
|
||||
}
|
||||
|
||||
var Enum3_name = map[int32]string{
|
||||
1: "YI",
|
||||
}
|
||||
|
||||
var Enum3_value = map[string]int32{
|
||||
"YI": 1,
|
||||
}
|
||||
|
||||
func (x Enum3) Enum() *Enum3 {
|
||||
p := new(Enum3)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Enum3) String() string {
|
||||
return proto.EnumName(Enum3_name, int32(x))
|
||||
}
|
||||
|
||||
func (x *Enum3) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(Enum3_value, data, "Enum3")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = Enum3(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (Enum3) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_3628d63611f7063d, []int{2}
|
||||
}
|
||||
|
||||
type Message1 struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
proto.XXX_InternalExtensions `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
type xxx_Message1 struct{ m *Message1 }
|
||||
|
||||
func (m *Message1) ProtoReflect() protoreflect.Message {
|
||||
return xxx_Message1{m}
|
||||
}
|
||||
func (m xxx_Message1) Type() protoreflect.MessageType {
|
||||
return xxx_Test_ProtoFile_MessageTypes[0].Type
|
||||
}
|
||||
func (m xxx_Message1) KnownFields() protoreflect.KnownFields {
|
||||
return xxx_Test_ProtoFile_MessageTypes[0].KnownFieldsOf(m.m)
|
||||
}
|
||||
func (m xxx_Message1) UnknownFields() protoreflect.UnknownFields {
|
||||
return xxx_Test_ProtoFile_MessageTypes[0].UnknownFieldsOf(m.m)
|
||||
}
|
||||
func (m xxx_Message1) Interface() protoreflect.ProtoMessage {
|
||||
return m.m
|
||||
}
|
||||
|
||||
func (m *Message1) Reset() { *m = Message1{} }
|
||||
func (m *Message1) String() string { return proto.CompactTextString(m) }
|
||||
func (*Message1) ProtoMessage() {}
|
||||
func (*Message1) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_3628d63611f7063d, []int{0}
|
||||
}
|
||||
|
||||
var extRange_Message1 = []proto.ExtensionRange{
|
||||
{Start: 10, End: 536870911},
|
||||
}
|
||||
|
||||
func (*Message1) ExtensionRangeArray() []proto.ExtensionRange {
|
||||
return extRange_Message1
|
||||
}
|
||||
|
||||
func (m *Message1) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Message1.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Message1) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Message1.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Message1) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Message1.Merge(m, src)
|
||||
}
|
||||
func (m *Message1) XXX_Size() int {
|
||||
return xxx_messageInfo_Message1.Size(m)
|
||||
}
|
||||
func (m *Message1) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Message1.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Message1 proto.InternalMessageInfo
|
||||
|
||||
type Message2 struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
type xxx_Message2 struct{ m *Message2 }
|
||||
|
||||
func (m *Message2) ProtoReflect() protoreflect.Message {
|
||||
return xxx_Message2{m}
|
||||
}
|
||||
func (m xxx_Message2) Type() protoreflect.MessageType {
|
||||
return xxx_Test_ProtoFile_MessageTypes[1].Type
|
||||
}
|
||||
func (m xxx_Message2) KnownFields() protoreflect.KnownFields {
|
||||
return xxx_Test_ProtoFile_MessageTypes[1].KnownFieldsOf(m.m)
|
||||
}
|
||||
func (m xxx_Message2) UnknownFields() protoreflect.UnknownFields {
|
||||
return xxx_Test_ProtoFile_MessageTypes[1].UnknownFieldsOf(m.m)
|
||||
}
|
||||
func (m xxx_Message2) Interface() protoreflect.ProtoMessage {
|
||||
return m.m
|
||||
}
|
||||
|
||||
func (m *Message2) Reset() { *m = Message2{} }
|
||||
func (m *Message2) String() string { return proto.CompactTextString(m) }
|
||||
func (*Message2) ProtoMessage() {}
|
||||
func (*Message2) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_3628d63611f7063d, []int{1}
|
||||
}
|
||||
|
||||
func (m *Message2) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Message2.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Message2) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Message2.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Message2) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Message2.Merge(m, src)
|
||||
}
|
||||
func (m *Message2) XXX_Size() int {
|
||||
return xxx_messageInfo_Message2.Size(m)
|
||||
}
|
||||
func (m *Message2) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Message2.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Message2 proto.InternalMessageInfo
|
||||
|
||||
type Message3 struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
type xxx_Message3 struct{ m *Message3 }
|
||||
|
||||
func (m *Message3) ProtoReflect() protoreflect.Message {
|
||||
return xxx_Message3{m}
|
||||
}
|
||||
func (m xxx_Message3) Type() protoreflect.MessageType {
|
||||
return xxx_Test_ProtoFile_MessageTypes[2].Type
|
||||
}
|
||||
func (m xxx_Message3) KnownFields() protoreflect.KnownFields {
|
||||
return xxx_Test_ProtoFile_MessageTypes[2].KnownFieldsOf(m.m)
|
||||
}
|
||||
func (m xxx_Message3) UnknownFields() protoreflect.UnknownFields {
|
||||
return xxx_Test_ProtoFile_MessageTypes[2].UnknownFieldsOf(m.m)
|
||||
}
|
||||
func (m xxx_Message3) Interface() protoreflect.ProtoMessage {
|
||||
return m.m
|
||||
}
|
||||
|
||||
func (m *Message3) Reset() { *m = Message3{} }
|
||||
func (m *Message3) String() string { return proto.CompactTextString(m) }
|
||||
func (*Message3) ProtoMessage() {}
|
||||
func (*Message3) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_3628d63611f7063d, []int{2}
|
||||
}
|
||||
|
||||
func (m *Message3) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Message3.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Message3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Message3.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Message3) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Message3.Merge(m, src)
|
||||
}
|
||||
func (m *Message3) XXX_Size() int {
|
||||
return xxx_messageInfo_Message3.Size(m)
|
||||
}
|
||||
func (m *Message3) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Message3.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Message3 proto.InternalMessageInfo
|
||||
|
||||
type Message4 struct {
|
||||
BoolField *bool `protobuf:"varint,30,opt,name=bool_field,json=boolField" json:"bool_field,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
type xxx_Message4 struct{ m *Message4 }
|
||||
|
||||
func (m *Message4) ProtoReflect() protoreflect.Message {
|
||||
return xxx_Message4{m}
|
||||
}
|
||||
func (m xxx_Message4) Type() protoreflect.MessageType {
|
||||
return xxx_Test_ProtoFile_MessageTypes[3].Type
|
||||
}
|
||||
func (m xxx_Message4) KnownFields() protoreflect.KnownFields {
|
||||
return xxx_Test_ProtoFile_MessageTypes[3].KnownFieldsOf(m.m)
|
||||
}
|
||||
func (m xxx_Message4) UnknownFields() protoreflect.UnknownFields {
|
||||
return xxx_Test_ProtoFile_MessageTypes[3].UnknownFieldsOf(m.m)
|
||||
}
|
||||
func (m xxx_Message4) Interface() protoreflect.ProtoMessage {
|
||||
return m.m
|
||||
}
|
||||
|
||||
func (m *Message4) Reset() { *m = Message4{} }
|
||||
func (m *Message4) String() string { return proto.CompactTextString(m) }
|
||||
func (*Message4) ProtoMessage() {}
|
||||
func (*Message4) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_3628d63611f7063d, []int{3}
|
||||
}
|
||||
|
||||
func (m *Message4) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Message4.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Message4) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Message4.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Message4) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Message4.Merge(m, src)
|
||||
}
|
||||
func (m *Message4) XXX_Size() int {
|
||||
return xxx_messageInfo_Message4.Size(m)
|
||||
}
|
||||
func (m *Message4) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Message4.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Message4 proto.InternalMessageInfo
|
||||
|
||||
func (m *Message4) GetBoolField() bool {
|
||||
if m != nil && m.BoolField != nil {
|
||||
return *m.BoolField
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var E_StringField = &proto.ExtensionDesc{
|
||||
ExtendedType: (*Message1)(nil),
|
||||
ExtensionType: (*string)(nil),
|
||||
Field: 11,
|
||||
Name: "testprotos.string_field",
|
||||
Tag: "bytes,11,opt,name=string_field",
|
||||
Filename: "reflect/protoregistry/testprotos/test.proto",
|
||||
}
|
||||
|
||||
var E_EnumField = &proto.ExtensionDesc{
|
||||
ExtendedType: (*Message1)(nil),
|
||||
ExtensionType: (*Enum1)(nil),
|
||||
Field: 12,
|
||||
Name: "testprotos.enum_field",
|
||||
Tag: "varint,12,opt,name=enum_field,enum=testprotos.Enum1",
|
||||
Filename: "reflect/protoregistry/testprotos/test.proto",
|
||||
}
|
||||
|
||||
var E_MessageField = &proto.ExtensionDesc{
|
||||
ExtendedType: (*Message1)(nil),
|
||||
ExtensionType: (*Message2)(nil),
|
||||
Field: 13,
|
||||
Name: "testprotos.message_field",
|
||||
Tag: "bytes,13,opt,name=message_field",
|
||||
Filename: "reflect/protoregistry/testprotos/test.proto",
|
||||
}
|
||||
|
||||
var E_Message4_MessageField = &proto.ExtensionDesc{
|
||||
ExtendedType: (*Message1)(nil),
|
||||
ExtensionType: (*Message2)(nil),
|
||||
Field: 21,
|
||||
Name: "testprotos.Message4.message_field",
|
||||
Tag: "bytes,21,opt,name=message_field",
|
||||
Filename: "reflect/protoregistry/testprotos/test.proto",
|
||||
}
|
||||
|
||||
var E_Message4_EnumField = &proto.ExtensionDesc{
|
||||
ExtendedType: (*Message1)(nil),
|
||||
ExtensionType: (*Enum1)(nil),
|
||||
Field: 22,
|
||||
Name: "testprotos.Message4.enum_field",
|
||||
Tag: "varint,22,opt,name=enum_field,enum=testprotos.Enum1",
|
||||
Filename: "reflect/protoregistry/testprotos/test.proto",
|
||||
}
|
||||
|
||||
var E_Message4_StringField = &proto.ExtensionDesc{
|
||||
ExtendedType: (*Message1)(nil),
|
||||
ExtensionType: (*string)(nil),
|
||||
Field: 23,
|
||||
Name: "testprotos.Message4.string_field",
|
||||
Tag: "bytes,23,opt,name=string_field",
|
||||
Filename: "reflect/protoregistry/testprotos/test.proto",
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("reflect/protoregistry/testprotos/test.proto", fileDescriptor_3628d63611f7063d)
|
||||
proto.RegisterEnum("testprotos.Enum1", Enum1_name, Enum1_value)
|
||||
proto.RegisterEnum("testprotos.Enum2", Enum2_name, Enum2_value)
|
||||
proto.RegisterEnum("testprotos.Enum3", Enum3_name, Enum3_value)
|
||||
proto.RegisterType((*Message1)(nil), "testprotos.Message1")
|
||||
proto.RegisterType((*Message2)(nil), "testprotos.Message2")
|
||||
proto.RegisterType((*Message3)(nil), "testprotos.Message3")
|
||||
proto.RegisterType((*Message4)(nil), "testprotos.Message4")
|
||||
proto.RegisterExtension(E_StringField)
|
||||
proto.RegisterExtension(E_EnumField)
|
||||
proto.RegisterExtension(E_MessageField)
|
||||
proto.RegisterExtension(E_Message4_MessageField)
|
||||
proto.RegisterExtension(E_Message4_EnumField)
|
||||
proto.RegisterExtension(E_Message4_StringField)
|
||||
}
|
||||
|
||||
var fileDescriptor_3628d63611f7063d = []byte{
|
||||
// 304 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2e, 0x4a, 0x4d, 0xcb,
|
||||
0x49, 0x4d, 0x2e, 0xd1, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x2f, 0x4a, 0x4d, 0xcf, 0x2c, 0x2e, 0x29,
|
||||
0xaa, 0xd4, 0x2f, 0x49, 0x2d, 0x2e, 0x01, 0x8b, 0x14, 0x83, 0x99, 0x7a, 0x60, 0xb6, 0x10, 0x17,
|
||||
0x42, 0x58, 0x49, 0x84, 0x8b, 0xc3, 0x37, 0xb5, 0xb8, 0x38, 0x31, 0x3d, 0xd5, 0x50, 0x8b, 0x83,
|
||||
0x83, 0x4b, 0xa0, 0xa1, 0xa1, 0xa1, 0x81, 0x49, 0x89, 0x0b, 0x2e, 0x6a, 0x84, 0xc4, 0x36, 0x56,
|
||||
0xfa, 0xcd, 0x08, 0xe7, 0x98, 0x08, 0xc9, 0x72, 0x71, 0x25, 0xe5, 0xe7, 0xe7, 0xc4, 0xa7, 0x65,
|
||||
0xa6, 0xe6, 0xa4, 0x48, 0xc8, 0x29, 0x30, 0x6a, 0x70, 0x04, 0x71, 0x82, 0x44, 0xdc, 0x40, 0x02,
|
||||
0x46, 0xfe, 0x5c, 0xbc, 0xb9, 0x10, 0xa5, 0x10, 0x15, 0x42, 0x22, 0x7a, 0x08, 0x7b, 0xf5, 0x60,
|
||||
0x96, 0x4a, 0x88, 0x2a, 0x30, 0x6a, 0x70, 0x1b, 0x61, 0x93, 0x33, 0x0a, 0xe2, 0x81, 0x1a, 0x00,
|
||||
0x31, 0xd0, 0x8d, 0x8b, 0x2b, 0x35, 0xaf, 0x34, 0x17, 0xaf, 0x69, 0x62, 0x0a, 0x8c, 0x1a, 0x7c,
|
||||
0x46, 0x82, 0xc8, 0x72, 0xae, 0x79, 0xa5, 0xb9, 0x86, 0x41, 0x9c, 0x20, 0xad, 0x10, 0x73, 0xcc,
|
||||
0xb9, 0x78, 0x8a, 0x4b, 0x8a, 0x32, 0xf3, 0xd2, 0xf1, 0x9a, 0x24, 0xae, 0xc0, 0xa8, 0xc1, 0x19,
|
||||
0xc4, 0x0d, 0x51, 0x09, 0xd6, 0xa8, 0x25, 0xc0, 0xc5, 0x0a, 0x36, 0x4c, 0x88, 0x9d, 0x8b, 0xd9,
|
||||
0xdf, 0xcf, 0x55, 0x80, 0x11, 0x26, 0x62, 0x04, 0x12, 0x09, 0xf5, 0xf3, 0x17, 0x60, 0xd4, 0xe2,
|
||||
0x87, 0x88, 0x18, 0x0b, 0xb1, 0x71, 0x31, 0x45, 0x7a, 0x0a, 0x30, 0x5a, 0x11, 0x67, 0x1b, 0x37,
|
||||
0x86, 0x6d, 0x56, 0xc4, 0x78, 0x97, 0x87, 0xb0, 0x77, 0xad, 0x88, 0x8c, 0x07, 0x5e, 0x62, 0xe3,
|
||||
0xc1, 0xc9, 0x21, 0xca, 0x2e, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x3f,
|
||||
0x3d, 0x3f, 0x27, 0x31, 0x2f, 0x1d, 0x92, 0xee, 0x92, 0x4a, 0xd3, 0xf4, 0xcb, 0x8c, 0xf4, 0x09,
|
||||
0xa5, 0x45, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x76, 0x64, 0x81, 0x59, 0xae, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func init() {
|
||||
xxx_Test_ProtoFile_FileDesc.Enums = xxx_Test_ProtoFile_EnumDescs[0:3]
|
||||
xxx_Test_ProtoFile_FileDesc.Messages = xxx_Test_ProtoFile_MessageDescs[0:4]
|
||||
var err error
|
||||
Test_ProtoFile, err = prototype.NewFile(&xxx_Test_ProtoFile_FileDesc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
const _ = protoimpl.EnforceVersion(protoimpl.Version - 0)
|
||||
|
||||
var Test_ProtoFile protoreflect.FileDescriptor
|
||||
|
||||
var xxx_Test_ProtoFile_FileDesc = prototype.File{
|
||||
Syntax: protoreflect.Proto2,
|
||||
Path: "reflect/protoregistry/testprotos/test.proto",
|
||||
Package: "testprotos",
|
||||
}
|
||||
var xxx_Test_ProtoFile_EnumTypes = [3]protoreflect.EnumType{
|
||||
prototype.GoEnum(
|
||||
xxx_Test_ProtoFile_EnumDescs[0].Reference(),
|
||||
func(_ protoreflect.EnumType, n protoreflect.EnumNumber) protoreflect.ProtoEnum {
|
||||
return Enum1(n)
|
||||
},
|
||||
),
|
||||
prototype.GoEnum(
|
||||
xxx_Test_ProtoFile_EnumDescs[1].Reference(),
|
||||
func(_ protoreflect.EnumType, n protoreflect.EnumNumber) protoreflect.ProtoEnum {
|
||||
return Enum2(n)
|
||||
},
|
||||
),
|
||||
prototype.GoEnum(
|
||||
xxx_Test_ProtoFile_EnumDescs[2].Reference(),
|
||||
func(_ protoreflect.EnumType, n protoreflect.EnumNumber) protoreflect.ProtoEnum {
|
||||
return Enum3(n)
|
||||
},
|
||||
),
|
||||
}
|
||||
var xxx_Test_ProtoFile_EnumDescs = [3]prototype.Enum{
|
||||
{
|
||||
Name: "Enum1",
|
||||
Values: []prototype.EnumValue{
|
||||
{Name: "ONE", Number: 1},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Enum2",
|
||||
Values: []prototype.EnumValue{
|
||||
{Name: "UNO", Number: 1},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Enum3",
|
||||
Values: []prototype.EnumValue{
|
||||
{Name: "YI", Number: 1},
|
||||
},
|
||||
},
|
||||
}
|
||||
var xxx_Test_ProtoFile_MessageTypes = [4]protoimpl.MessageType{
|
||||
{Type: prototype.GoMessage(
|
||||
xxx_Test_ProtoFile_MessageDescs[0].Reference(),
|
||||
func(protoreflect.MessageType) protoreflect.ProtoMessage {
|
||||
return new(Message1)
|
||||
},
|
||||
)},
|
||||
{Type: prototype.GoMessage(
|
||||
xxx_Test_ProtoFile_MessageDescs[1].Reference(),
|
||||
func(protoreflect.MessageType) protoreflect.ProtoMessage {
|
||||
return new(Message2)
|
||||
},
|
||||
)},
|
||||
{Type: prototype.GoMessage(
|
||||
xxx_Test_ProtoFile_MessageDescs[2].Reference(),
|
||||
func(protoreflect.MessageType) protoreflect.ProtoMessage {
|
||||
return new(Message3)
|
||||
},
|
||||
)},
|
||||
{Type: prototype.GoMessage(
|
||||
xxx_Test_ProtoFile_MessageDescs[3].Reference(),
|
||||
func(protoreflect.MessageType) protoreflect.ProtoMessage {
|
||||
return new(Message4)
|
||||
},
|
||||
)},
|
||||
}
|
||||
var xxx_Test_ProtoFile_MessageDescs = [4]prototype.Message{
|
||||
{
|
||||
Name: "Message1",
|
||||
ExtensionRanges: [][2]protoreflect.FieldNumber{{10, 536870912}},
|
||||
},
|
||||
{
|
||||
Name: "Message2",
|
||||
},
|
||||
{
|
||||
Name: "Message3",
|
||||
},
|
||||
{
|
||||
Name: "Message4",
|
||||
Fields: []prototype.Field{
|
||||
{
|
||||
Name: "bool_field",
|
||||
Number: 30,
|
||||
Cardinality: protoreflect.Optional,
|
||||
Kind: protoreflect.BoolKind,
|
||||
JSONName: "boolField",
|
||||
IsPacked: prototype.False,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
45
reflect/protoregistry/testprotos/test.proto
Normal file
45
reflect/protoregistry/testprotos/test.proto
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Different proto type definitions for testing the Types registry.
|
||||
syntax = "proto2";
|
||||
|
||||
package testprotos;
|
||||
option go_package = "github.com/golang/protobuf/v2/reflect/protoregistry/testprotos";
|
||||
|
||||
message Message1 {
|
||||
extensions 10 to max;
|
||||
}
|
||||
|
||||
message Message2 {}
|
||||
|
||||
message Message3 {}
|
||||
|
||||
enum Enum1 {
|
||||
ONE = 1;
|
||||
}
|
||||
|
||||
enum Enum2 {
|
||||
UNO = 1;
|
||||
}
|
||||
|
||||
enum Enum3 {
|
||||
YI = 1;
|
||||
}
|
||||
|
||||
extend Message1 {
|
||||
optional string string_field = 11;
|
||||
optional Enum1 enum_field = 12;
|
||||
optional Message2 message_field = 13;
|
||||
}
|
||||
|
||||
message Message4 {
|
||||
optional bool bool_field = 30;
|
||||
|
||||
extend Message1 {
|
||||
optional Message2 message_field = 21;
|
||||
optional Enum1 enum_field = 22;
|
||||
optional string string_field = 23;
|
||||
}
|
||||
}
|
@ -53,3 +53,7 @@ cp $tmpdir/src/google/protobuf/compiler/plugin.pb.go ./types/plugin/plugin.pb.go
|
||||
echo "# encoding/textpb/testprotos/pb?/test.proto"
|
||||
PROTOC_GEN_GO_ENABLE_REFLECT=1 protoc --go_out=paths=source_relative:. \
|
||||
encoding/textpb/testprotos/pb?/test.proto
|
||||
|
||||
echo "# reflect/protoregistry/testprotos/test.proto"
|
||||
PROTOC_GEN_GO_ENABLE_REFLECT=1 protoc --go_out=paths=source_relative:. \
|
||||
reflect/protoregistry/testprotos/test.proto
|
||||
|
Loading…
x
Reference in New Issue
Block a user