| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 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 | |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 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: |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 26 | |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 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) |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 36 | */ |
| 37 | package reflection // import "google.golang.org/grpc/reflection" |
| 38 | |
| 39 | import ( |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 40 | "google.golang.org/grpc" |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 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" |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 48 | ) |
| 49 | |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 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 |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 56 | } |
| 57 | |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 58 | var _ GRPCServer = (*grpc.Server)(nil) |
| 59 | |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 60 | // Register registers the server reflection service on the given gRPC server. |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 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) |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 66 | } |
| 67 | |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 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) |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 74 | } |
| 75 | |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 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 |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 90 | } |
| 91 | |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 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) |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 102 | } |
| 103 | |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 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 |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 124 | } |
| 125 | |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 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)) |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 138 | } |
| 139 | |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 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 |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 151 | } |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 152 | if opts.ExtensionResolver == nil { |
| 153 | opts.ExtensionResolver = protoregistry.GlobalTypes |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 154 | } |
| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 155 | return &internal.ServerReflectionServer{ |
| 156 | S: opts.Services, |
| 157 | DescResolver: opts.DescriptorResolver, |
| 158 | ExtResolver: opts.ExtensionResolver, |
| Himani Chawla | 27f8121 | 2021-04-07 11:37:47 +0530 | [diff] [blame] | 159 | } |
| 160 | } |