83 lines
2.3 KiB
Go
83 lines
2.3 KiB
Go
package appconfig
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"google.golang.org/protobuf/reflect/protodesc"
|
|
"google.golang.org/protobuf/reflect/protoreflect"
|
|
"google.golang.org/protobuf/reflect/protoregistry"
|
|
"google.golang.org/protobuf/types/dynamicpb"
|
|
)
|
|
|
|
// dynamic resolver allows marshaling gogo proto messages from the gogoproto.HybridResolver as long as those
|
|
// files have been imported before calling LoadJSON. There is similar code in autocli, this should probably
|
|
// eventually be moved into a library.
|
|
type dynamicTypeResolver struct {
|
|
resolver protodesc.Resolver
|
|
}
|
|
|
|
func (r dynamicTypeResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
|
|
ext, err := protoregistry.GlobalTypes.FindExtensionByName(field)
|
|
if err == nil {
|
|
return ext, nil
|
|
}
|
|
|
|
desc, err := r.resolver.FindDescriptorByName(field)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return dynamicpb.NewExtensionType(desc.(protoreflect.ExtensionTypeDescriptor)), nil
|
|
}
|
|
|
|
func (r dynamicTypeResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
|
|
ext, err := protoregistry.GlobalTypes.FindExtensionByNumber(message, field)
|
|
if err == nil {
|
|
return ext, nil
|
|
}
|
|
|
|
desc, err := r.resolver.FindDescriptorByName(message)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
messageDesc := desc.(protoreflect.MessageDescriptor)
|
|
exts := messageDesc.Extensions()
|
|
n := exts.Len()
|
|
for i := 0; i < n; i++ {
|
|
ext := exts.Get(i)
|
|
if ext.Number() == field {
|
|
return dynamicpb.NewExtensionType(ext), nil
|
|
}
|
|
}
|
|
|
|
return nil, protoregistry.NotFound
|
|
}
|
|
|
|
func (r dynamicTypeResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {
|
|
typ, err := protoregistry.GlobalTypes.FindMessageByName(message)
|
|
if err == nil {
|
|
return typ, nil
|
|
}
|
|
|
|
desc, err := r.resolver.FindDescriptorByName(message)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return dynamicpb.NewMessageType(desc.(protoreflect.MessageDescriptor)), nil
|
|
}
|
|
|
|
func (r dynamicTypeResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) {
|
|
if i := strings.LastIndexByte(url, '/'); i >= 0 {
|
|
url = url[i+1:]
|
|
}
|
|
|
|
return r.FindMessageByName(protoreflect.FullName(url))
|
|
}
|
|
|
|
var (
|
|
_ protoregistry.MessageTypeResolver = dynamicTypeResolver{}
|
|
_ protoregistry.ExtensionTypeResolver = dynamicTypeResolver{}
|
|
)
|