1 /*
2 *
3 * Copyright 2016 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18 19 /*
20 Package reflection implements server reflection service.
21 22 The service implemented is defined in:
23 https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto.
24 25 To register server reflection on a gRPC server:
26 27 import "google.golang.org/grpc/reflection"
28 29 s := grpc.NewServer()
30 pb.RegisterYourOwnServer(s, &server{})
31 32 // Register reflection service on gRPC server.
33 reflection.Register(s)
34 35 s.Serve(lis)
36 */
37 package reflection // import "google.golang.org/grpc/reflection"
38 39 import (
40 "google.golang.org/grpc"
41 "google.golang.org/grpc/reflection/internal"
42 "google.golang.org/protobuf/reflect/protodesc"
43 "google.golang.org/protobuf/reflect/protoreflect"
44 "google.golang.org/protobuf/reflect/protoregistry"
45 46 v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1"
47 v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
48 )
49 50 // GRPCServer is the interface provided by a gRPC server. It is implemented by
51 // *grpc.Server, but could also be implemented by other concrete types. It acts
52 // as a registry, for accumulating the services exposed by the server.
53 type GRPCServer interface {
54 grpc.ServiceRegistrar
55 ServiceInfoProvider
56 }
57 58 var _ GRPCServer = (*grpc.Server)(nil)
59 60 // Register registers the server reflection service on the given gRPC server.
61 // Both the v1 and v1alpha versions are registered.
62 func Register(s GRPCServer) {
63 svr := NewServerV1(ServerOptions{Services: s})
64 v1alphareflectiongrpc.RegisterServerReflectionServer(s, asV1Alpha(svr))
65 v1reflectiongrpc.RegisterServerReflectionServer(s, svr)
66 }
67 68 // RegisterV1 registers only the v1 version of the server reflection service
69 // on the given gRPC server. Many clients may only support v1alpha so most
70 // users should use Register instead, at least until clients have upgraded.
71 func RegisterV1(s GRPCServer) {
72 svr := NewServerV1(ServerOptions{Services: s})
73 v1reflectiongrpc.RegisterServerReflectionServer(s, svr)
74 }
75 76 // ServiceInfoProvider is an interface used to retrieve metadata about the
77 // services to expose.
78 //
79 // The reflection service is only interested in the service names, but the
80 // signature is this way so that *grpc.Server implements it. So it is okay
81 // for a custom implementation to return zero values for the
82 // grpc.ServiceInfo values in the map.
83 //
84 // # Experimental
85 //
86 // Notice: This type is EXPERIMENTAL and may be changed or removed in a
87 // later release.
88 type ServiceInfoProvider interface {
89 GetServiceInfo() map[string]grpc.ServiceInfo
90 }
91 92 // ExtensionResolver is the interface used to query details about extensions.
93 // This interface is satisfied by protoregistry.GlobalTypes.
94 //
95 // # Experimental
96 //
97 // Notice: This type is EXPERIMENTAL and may be changed or removed in a
98 // later release.
99 type ExtensionResolver interface {
100 protoregistry.ExtensionTypeResolver
101 RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool)
102 }
103 104 // ServerOptions represents the options used to construct a reflection server.
105 //
106 // # Experimental
107 //
108 // Notice: This type is EXPERIMENTAL and may be changed or removed in a
109 // later release.
110 type ServerOptions struct {
111 // The source of advertised RPC services. If not specified, the reflection
112 // server will report an empty list when asked to list services.
113 //
114 // This value will typically be a *grpc.Server. But the set of advertised
115 // services can be customized by wrapping a *grpc.Server or using an
116 // alternate implementation that returns a custom set of service names.
117 Services ServiceInfoProvider
118 // Optional resolver used to load descriptors. If not specified,
119 // protoregistry.GlobalFiles will be used.
120 DescriptorResolver protodesc.Resolver
121 // Optional resolver used to query for known extensions. If not specified,
122 // protoregistry.GlobalTypes will be used.
123 ExtensionResolver ExtensionResolver
124 }
125 126 // NewServer returns a reflection server implementation using the given options.
127 // This can be used to customize behavior of the reflection service. Most usages
128 // should prefer to use Register instead. For backwards compatibility reasons,
129 // this returns the v1alpha version of the reflection server. For a v1 version
130 // of the reflection server, see NewServerV1.
131 //
132 // # Experimental
133 //
134 // Notice: This function is EXPERIMENTAL and may be changed or removed in a
135 // later release.
136 func NewServer(opts ServerOptions) v1alphareflectiongrpc.ServerReflectionServer {
137 return asV1Alpha(NewServerV1(opts))
138 }
139 140 // NewServerV1 returns a reflection server implementation using the given options.
141 // This can be used to customize behavior of the reflection service. Most usages
142 // should prefer to use Register instead.
143 //
144 // # Experimental
145 //
146 // Notice: This function is EXPERIMENTAL and may be changed or removed in a
147 // later release.
148 func NewServerV1(opts ServerOptions) v1reflectiongrpc.ServerReflectionServer {
149 if opts.DescriptorResolver == nil {
150 opts.DescriptorResolver = protoregistry.GlobalFiles
151 }
152 if opts.ExtensionResolver == nil {
153 opts.ExtensionResolver = protoregistry.GlobalTypes
154 }
155 return &internal.ServerReflectionServer{
156 S: opts.Services,
157 DescResolver: opts.DescriptorResolver,
158 ExtResolver: opts.ExtensionResolver,
159 }
160 }
161