| /* | |
| * | |
| * 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, | |
| } | |
| } |