Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In deprecating old APIs, what would be a reasonable upgrade for "github.com/jhump/protoreflect/desc" and "github.com/jhump/protoreflect/dynamic"? #633

Open
balena-zh opened this issue Jan 2, 2025 · 1 comment

Comments

@balena-zh
Copy link

balena-zh commented Jan 2, 2025

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)
	}
}
@balena-zh balena-zh changed the title In deprecating old APIs, what would be a reasonable upgrade? In deprecating old APIs, what would be a reasonable upgrade for "github.com/jhump/protoreflect/desc" and "github.com/jhump/protoreflect/dynamic"? Jan 2, 2025
@jhump
Copy link
Owner

jhump commented Jan 6, 2025

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?

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants