/* * * Copyright 2016 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* Package reflection implements server reflection service. The service implemented is defined in: https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto. To register server reflection on a gRPC server: import "google.golang.org/grpc/reflection" s := grpc.NewServer() pb.RegisterYourOwnServer(s, &server{}) // Register reflection service on gRPC server. reflection.Register(s) s.Serve(lis) */ package reflection // import "google.golang.org/grpc/reflection" import ( "google.golang.org/grpc" "google.golang.org/grpc/reflection/internal" "google.golang.org/protobuf/reflect/protodesc" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1" v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" ) // GRPCServer is the interface provided by a gRPC server. It is implemented by // *grpc.Server, but could also be implemented by other concrete types. It acts // as a registry, for accumulating the services exposed by the server. type GRPCServer interface { grpc.ServiceRegistrar ServiceInfoProvider } var _ GRPCServer = (*grpc.Server)(nil) // Register registers the server reflection service on the given gRPC server. // Both the v1 and v1alpha versions are registered. func Register(s GRPCServer) { svr := NewServerV1(ServerOptions{Services: s}) v1alphareflectiongrpc.RegisterServerReflectionServer(s, asV1Alpha(svr)) v1reflectiongrpc.RegisterServerReflectionServer(s, svr) } // RegisterV1 registers only the v1 version of the server reflection service // on the given gRPC server. Many clients may only support v1alpha so most // users should use Register instead, at least until clients have upgraded. func RegisterV1(s GRPCServer) { svr := NewServerV1(ServerOptions{Services: s}) v1reflectiongrpc.RegisterServerReflectionServer(s, svr) } // ServiceInfoProvider is an interface used to retrieve metadata about the // services to expose. // // The reflection service is only interested in the service names, but the // signature is this way so that *grpc.Server implements it. So it is okay // for a custom implementation to return zero values for the // grpc.ServiceInfo values in the map. // // # Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. type ServiceInfoProvider interface { GetServiceInfo() map[string]grpc.ServiceInfo } // ExtensionResolver is the interface used to query details about extensions. // This interface is satisfied by protoregistry.GlobalTypes. // // # Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. type ExtensionResolver interface { protoregistry.ExtensionTypeResolver RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool) } // ServerOptions represents the options used to construct a reflection server. // // # Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. type ServerOptions struct { // The source of advertised RPC services. If not specified, the reflection // server will report an empty list when asked to list services. // // This value will typically be a *grpc.Server. But the set of advertised // services can be customized by wrapping a *grpc.Server or using an // alternate implementation that returns a custom set of service names. Services ServiceInfoProvider // Optional resolver used to load descriptors. If not specified, // protoregistry.GlobalFiles will be used. DescriptorResolver protodesc.Resolver // Optional resolver used to query for known extensions. If not specified, // protoregistry.GlobalTypes will be used. ExtensionResolver ExtensionResolver } // NewServer returns a reflection server implementation using the given options. // This can be used to customize behavior of the reflection service. Most usages // should prefer to use Register instead. For backwards compatibility reasons, // this returns the v1alpha version of the reflection server. For a v1 version // of the reflection server, see NewServerV1. // // # Experimental // // Notice: This function is EXPERIMENTAL and may be changed or removed in a // later release. func NewServer(opts ServerOptions) v1alphareflectiongrpc.ServerReflectionServer { return asV1Alpha(NewServerV1(opts)) } // NewServerV1 returns a reflection server implementation using the given options. // This can be used to customize behavior of the reflection service. Most usages // should prefer to use Register instead. // // # Experimental // // Notice: This function is EXPERIMENTAL and may be changed or removed in a // later release. func NewServerV1(opts ServerOptions) v1reflectiongrpc.ServerReflectionServer { if opts.DescriptorResolver == nil { opts.DescriptorResolver = protoregistry.GlobalFiles } if opts.ExtensionResolver == nil { opts.ExtensionResolver = protoregistry.GlobalTypes } return &internal.ServerReflectionServer{ S: opts.Services, DescResolver: opts.DescriptorResolver, ExtResolver: opts.ExtensionResolver, } }