github.com/xiaoshude/protoreflect@v1.16.1-0.20220310024924-8c94d7247598/grpcreflect/server.go (about)

     1  package grpcreflect
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"google.golang.org/grpc"
     7  
     8  	"github.com/xiaoshude/protoreflect/desc"
     9  )
    10  
    11  // LoadServiceDescriptors loads the service descriptors for all services exposed by the
    12  // given GRPC server.
    13  func LoadServiceDescriptors(s *grpc.Server) (map[string]*desc.ServiceDescriptor, error) {
    14  	descs := map[string]*desc.ServiceDescriptor{}
    15  	for name, info := range s.GetServiceInfo() {
    16  		file, ok := info.Metadata.(string)
    17  		if !ok {
    18  			return nil, fmt.Errorf("service %q has unexpected metadata: expecting a string; got %v", name, info.Metadata)
    19  		}
    20  		fd, err := desc.LoadFileDescriptor(file)
    21  		if err != nil {
    22  			return nil, err
    23  		}
    24  		d := fd.FindSymbol(name)
    25  		if d == nil {
    26  			return nil, fmt.Errorf("file descriptor for %q has no element named %q", file, name)
    27  		}
    28  		sd, ok := d.(*desc.ServiceDescriptor)
    29  		if !ok {
    30  			return nil, fmt.Errorf("file descriptor for %q has incorrect element named %q: expecting a service descriptor; got %v", file, name, d)
    31  		}
    32  		descs[name] = sd
    33  	}
    34  	return descs, nil
    35  }
    36  
    37  // LoadServiceDescriptor loads a rich descriptor for a given service description
    38  // generated by protoc-gen-go. Generated code contains an unexported symbol with
    39  // a name like "_<Service>_serviceDesc" which is the service's description. It
    40  // is used internally to register a service implementation with a GRPC server.
    41  // But it can also be used by this package to retrieve the rich descriptor for
    42  // the service.
    43  func LoadServiceDescriptor(svc *grpc.ServiceDesc) (*desc.ServiceDescriptor, error) {
    44  	file, ok := svc.Metadata.(string)
    45  	if !ok {
    46  		return nil, fmt.Errorf("service %q has unexpected metadata: expecting a string; got %v", svc.ServiceName, svc.Metadata)
    47  	}
    48  	fd, err := desc.LoadFileDescriptor(file)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	d := fd.FindSymbol(svc.ServiceName)
    53  	if d == nil {
    54  		return nil, fmt.Errorf("file descriptor for %q has no element named %q", file, svc.ServiceName)
    55  	}
    56  	sd, ok := d.(*desc.ServiceDescriptor)
    57  	if !ok {
    58  		return nil, fmt.Errorf("file descriptor for %q has incorrect element named %q: expecting a service descriptor; got %v", file, svc.ServiceName, d)
    59  	}
    60  	return sd, nil
    61  }