mirror of
https://github.com/gusaul/grpcox.git
synced 2025-01-26 06:14:40 +00:00
62 lines
2.1 KiB
Go
62 lines
2.1 KiB
Go
package grpcreflect
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
"github.com/jhump/protoreflect/desc"
|
|
)
|
|
|
|
// LoadServiceDescriptors loads the service descriptors for all services exposed by the
|
|
// given GRPC server.
|
|
func LoadServiceDescriptors(s *grpc.Server) (map[string]*desc.ServiceDescriptor, error) {
|
|
descs := map[string]*desc.ServiceDescriptor{}
|
|
for name, info := range s.GetServiceInfo() {
|
|
file, ok := info.Metadata.(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("service %q has unexpected metadata: expecting a string; got %v", name, info.Metadata)
|
|
}
|
|
fd, err := desc.LoadFileDescriptor(file)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
d := fd.FindSymbol(name)
|
|
if d == nil {
|
|
return nil, fmt.Errorf("file descriptor for %q has no element named %q", file, name)
|
|
}
|
|
sd, ok := d.(*desc.ServiceDescriptor)
|
|
if !ok {
|
|
return nil, fmt.Errorf("file descriptor for %q has incorrect element named %q: expecting a service descriptor; got %v", file, name, d)
|
|
}
|
|
descs[name] = sd
|
|
}
|
|
return descs, nil
|
|
}
|
|
|
|
// LoadServiceDescriptor loads a rich descriptor for a given service description
|
|
// generated by protoc-gen-go. Generated code contains an unexported symbol with
|
|
// a name like "_<Service>_serviceDesc" which is the service's description. It
|
|
// is used internally to register a service implementation with a GRPC server.
|
|
// But it can also be used by this package to retrieve the rich descriptor for
|
|
// the service.
|
|
func LoadServiceDescriptor(svc *grpc.ServiceDesc) (*desc.ServiceDescriptor, error) {
|
|
file, ok := svc.Metadata.(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("service %q has unexpected metadata: expecting a string; got %v", svc.ServiceName, svc.Metadata)
|
|
}
|
|
fd, err := desc.LoadFileDescriptor(file)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
d := fd.FindSymbol(svc.ServiceName)
|
|
if d == nil {
|
|
return nil, fmt.Errorf("file descriptor for %q has no element named %q", file, svc.ServiceName)
|
|
}
|
|
sd, ok := d.(*desc.ServiceDescriptor)
|
|
if !ok {
|
|
return nil, fmt.Errorf("file descriptor for %q has incorrect element named %q: expecting a service descriptor; got %v", file, svc.ServiceName, d)
|
|
}
|
|
return sd, nil
|
|
}
|