In deprecating old APIs, what would be a reasonable upgrade for "github.com/jhump/protoreflect/desc" and "github.com/jhump/protoreflect/dynamic"?
I'm looking for ways to upgrade constructions such as those found in https://github.com/fullstorydev/grpcurl/blob/b9a11e9fea796d968e2dd83573312ead4b6fd831/desc_source.go.
In summary, I'm looking for ways to attend the interface grpcurl.DescriptorSource out of a protoregistry.GlobalFiles. Is there a simple way or would it involve deeper changes in grpcurl?
Example:
import (
...
"github.com/fullstorydev/grpcurl"
"github.com/jhump/protoreflect/desc"
"github.com/jhump/protoreflect/dynamic"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
...
)
type fileSource struct {
files map[string]*desc.FileDescriptor
er *dynamic.ExtensionRegistry
erInit sync.Once
}
func (fs *fileSource) ListServices() ([]string, error) {
set := map[string]bool{}
for _, fd := range fs.files {
for _, svc := range fd.GetServices() {
set[svc.GetFullyQualifiedName()] = true
}
}
sl := make([]string, 0, len(set))
for svc := range set {
sl = append(sl, svc)
}
return sl, nil
}
func (fs *fileSource) GetAllFiles() ([]*desc.FileDescriptor, error) {
files := make([]*desc.FileDescriptor, len(fs.files))
i := 0
for _, fd := range fs.files {
files[i] = fd
i++
}
return files, nil
}
func (fs *fileSource) FindSymbol(fullyQualifiedName string) (desc.Descriptor, error) {
for _, fd := range fs.files {
if dsc := fd.FindSymbol(fullyQualifiedName); dsc != nil {
return dsc, nil
}
}
return nil, fmt.Errorf("symbol not found %v", fullyQualifiedName)
}
func (fs *fileSource) AllExtensionsForType(typeName string) ([]*desc.FieldDescriptor, error) {
fs.erInit.Do(func() {
fs.er = &dynamic.ExtensionRegistry{}
for _, fd := range fs.files {
fs.er.AddExtensionsFromFile(fd)
}
})
return fs.er.AllExtensionsForType(typeName), nil
}
Which is consumed like
func DescriptorSourceFromGlobalRegistry() grpcurl.DescriptorSource {
files := []*desc.FileDescriptor{}
protoregistry.GlobalFiles.RangeFiles(func(fd protoreflect.FileDescriptor) bool {
wrap, err := desc.WrapFile(fd)
if err != nil {
return false
}
name := wrap.GetName()
if !strings.HasPrefix(name, "proto/") {
return true
}
files = append(files, wrap)
return true
})
fds := map[string]*desc.FileDescriptor{}
for _, fd := range files {
addFile(fd, fds)
}
return &fileSource{files: fds}
}
func addFile(fd *desc.FileDescriptor, fds map[string]*desc.FileDescriptor) {
name := fd.GetName()
if _, ok := fds[name]; ok {
return
}
fds[name] = fd
for _, dep := range fd.GetDependencies() {
addFile(dep, fds)
}
}
In summary, I'm looking for ways to attend the interface
grpcurl.DescriptorSourceout of aprotoregistry.GlobalFiles. Is there a simple way or would it involve deeper changes ingrpcurl?
You would use the desc.WrapDescriptor or desc.WrapFile to adapt the protoreflect.Descriptor types, returned from a *protoregistry.Files, to the desc.Descriptor types.
Ideally, the grpcurl module would be updated to directly use the google.golang.org/protobuf module and its reflection types instead of the github.com/jhump/protoreflect/desc types. In general, APIs that directly refer to types in github.com/jhump/protoreflect likely need a v2 release that instead refers to the types in the protobuf runtime. The reason they do not is that they were written before the google.golang.org/protobuf was first released and before it had any reflection support.