grpc-server-reflection 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8ea2d3f5a48656af40960816f018562d38151cc067899fcd1ff22863c62b4cb9
4
+ data.tar.gz: 6f4abd7208859c1e297ce89f965e273414c25439b06dd2ac7e5600bd26ebf875
5
+ SHA512:
6
+ metadata.gz: aee60ebbad98713df2cda9d31fc63e52741d5740b19046ba13cdc4e3cfb9d397df2a7ec3f64766baac1471652eb71700abe9ff045c197c64ceac70a780bde1e4
7
+ data.tar.gz: 9681fa4ff9aedeb9f73693e92b3bd478e6e8f8a8bc29f080b6a792d2899d1efc3cc7d3d89a2bc0f336c6c246abc49c79ef0138f848d64381090e902d38b97d0f
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 zbokostya
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # grpc-server-reflection
2
+
3
+ Ruby gem implementing the [gRPC Server Reflection Protocol v1](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md). Enables tools like `grpcurl`, `grpcui`, and Postman to introspect your gRPC services without `.proto` files.
4
+
5
+ ## Installation
6
+
7
+ Add to your Gemfile:
8
+
9
+ ```ruby
10
+ gem 'grpc-server-reflection'
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ruby
16
+ require 'grpc_server_reflection'
17
+
18
+ server = GRPC::RpcServer.new
19
+ server.add_http2_port('0.0.0.0:50051', :this_port_is_insecure)
20
+ server.handle(MyApp::GreeterService)
21
+ server.handle(GrpcServerReflection::Service) # Add reflection
22
+ server.run
23
+ ```
24
+
25
+ Then use grpcurl to test:
26
+
27
+ ```bash
28
+ grpcurl -plaintext localhost:50051 list
29
+ ```
30
+
31
+ ## Requirements
32
+
33
+ - Ruby >= 2.7
34
+ - grpc gem (~> 1.0)
35
+ - google-protobuf gem (~> 3.0)
36
+
37
+ ## License
38
+
39
+ MIT
@@ -0,0 +1,146 @@
1
+ // Copyright 2016 The gRPC Authors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ // Service exported by server reflection. A more complete description of how
16
+ // server reflection works can be found at
17
+ // https://github.com/grpc/grpc/blob/master/doc/server-reflection.md
18
+ //
19
+ // The canonical version of this proto can be found at
20
+ // https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto
21
+
22
+ syntax = "proto3";
23
+
24
+ package grpc.reflection.v1;
25
+
26
+ option go_package = "google.golang.org/grpc/reflection/grpc_reflection_v1";
27
+ option java_multiple_files = true;
28
+ option java_package = "io.grpc.reflection.v1";
29
+ option java_outer_classname = "ServerReflectionProto";
30
+
31
+ service ServerReflection {
32
+ // The reflection service is structured as a bidirectional stream, ensuring
33
+ // all related requests go to a single server.
34
+ rpc ServerReflectionInfo(stream ServerReflectionRequest)
35
+ returns (stream ServerReflectionResponse);
36
+ }
37
+
38
+ // The message sent by the client when calling ServerReflectionInfo method.
39
+ message ServerReflectionRequest {
40
+ string host = 1;
41
+ // To use reflection service, the client should set one of the following
42
+ // fields in message_request. The server distinguishes requests by their
43
+ // defined field and then handles them using corresponding methods.
44
+ oneof message_request {
45
+ // Find a proto file by the file name.
46
+ string file_by_filename = 3;
47
+
48
+ // Find the proto file that declares the given fully-qualified symbol name.
49
+ // This field should be a fully-qualified symbol name
50
+ // (e.g. <package>.<service>[.<method>] or <package>.<type>).
51
+ string file_containing_symbol = 4;
52
+
53
+ // Find the proto file which defines an extension extending the given
54
+ // message type with the given field number.
55
+ ExtensionRequest file_containing_extension = 5;
56
+
57
+ // Finds the tag numbers used by all known extensions of the given message
58
+ // type, and appends them to ExtensionNumberResponse in an undefined order.
59
+ // Its corresponding method is best-effort: it's not guaranteed that the
60
+ // reflection service will implement this method, and it's not guaranteed
61
+ // that this method will provide all extensions. Returns
62
+ // StatusCode::UNIMPLEMENTED if it's not implemented.
63
+ // This field should be a fully-qualified type name. The format is
64
+ // <package>.<type>
65
+ string all_extension_numbers_of_type = 6;
66
+
67
+ // List the full names of registered services. The content will not be
68
+ // checked.
69
+ string list_services = 7;
70
+ }
71
+ }
72
+
73
+ // The type name and extension number sent by the client when requesting
74
+ // file_containing_extension.
75
+ message ExtensionRequest {
76
+ // Fully-qualified type name. The format should be <package>.<type>
77
+ string containing_type = 1;
78
+ int32 extension_number = 2;
79
+ }
80
+
81
+ // The message sent by the server to answer ServerReflectionInfo method.
82
+ message ServerReflectionResponse {
83
+ string valid_host = 1;
84
+ ServerReflectionRequest original_request = 2;
85
+ // The server sets one of the following fields according to the message_request
86
+ // in the request.
87
+ oneof message_response {
88
+ // This message is used to answer file_by_filename, file_containing_symbol,
89
+ // file_containing_extension requests with transitive dependencies.
90
+ // As the repeated label is not allowed in oneof fields, we use a
91
+ // FileDescriptorResponse message to encapsulate the repeated fields.
92
+ // The reflection service is allowed to avoid sending FileDescriptorProtos
93
+ // that were previously sent in response to earlier requests in the stream.
94
+ FileDescriptorResponse file_descriptor_response = 4;
95
+
96
+ // This message is used to answer all_extension_numbers_of_type requests.
97
+ ExtensionNumberResponse all_extension_numbers_response = 5;
98
+
99
+ // This message is used to answer list_services requests.
100
+ ListServiceResponse list_services_response = 6;
101
+
102
+ // This message is used when an error occurs.
103
+ ErrorResponse error_response = 7;
104
+ }
105
+ }
106
+
107
+ // Serialized FileDescriptorProto messages sent by the server answering
108
+ // a file_by_filename, file_containing_symbol, or file_containing_extension
109
+ // request.
110
+ message FileDescriptorResponse {
111
+ // Serialized FileDescriptorProto messages. We avoid taking a dependency on
112
+ // descriptor.proto, which uses proto2 only features, by making them opaque
113
+ // bytes instead.
114
+ repeated bytes file_descriptor_proto = 1;
115
+ }
116
+
117
+ // A list of extension numbers sent by the server answering
118
+ // all_extension_numbers_of_type request.
119
+ message ExtensionNumberResponse {
120
+ // Full name of the base type, including the package name. The format
121
+ // is <package>.<type>
122
+ string base_type_name = 1;
123
+ repeated int32 extension_number = 2;
124
+ }
125
+
126
+ // A list of ServiceResponse sent by the server answering list_services request.
127
+ message ListServiceResponse {
128
+ // The information of each service may be expanded in the future, so we use
129
+ // ServiceResponse message to encapsulate it.
130
+ repeated ServiceResponse service = 1;
131
+ }
132
+
133
+ // The information of a single service used by ListServiceResponse to answer
134
+ // list_services request.
135
+ message ServiceResponse {
136
+ // Full name of a registered service, including its package name. The format
137
+ // is <package>.<service>
138
+ string name = 1;
139
+ }
140
+
141
+ // The error code and error message sent by the server when an error occurs.
142
+ message ErrorResponse {
143
+ // This field uses the error codes defined in grpc::StatusCode.
144
+ int32 error_code = 1;
145
+ string error_message = 2;
146
+ }
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: grpc/reflection/v1/reflection.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+
8
+ descriptor_data = "\n#grpc/reflection/v1/reflection.proto\x12\x12grpc.reflection.v1\"\x85\x02\n\x17ServerReflectionRequest\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x1a\n\x10\x66ile_by_filename\x18\x03 \x01(\tH\x00\x12 \n\x16\x66ile_containing_symbol\x18\x04 \x01(\tH\x00\x12I\n\x19\x66ile_containing_extension\x18\x05 \x01(\x0b\x32$.grpc.reflection.v1.ExtensionRequestH\x00\x12\'\n\x1d\x61ll_extension_numbers_of_type\x18\x06 \x01(\tH\x00\x12\x17\n\rlist_services\x18\x07 \x01(\tH\x00\x42\x11\n\x0fmessage_request\"E\n\x10\x45xtensionRequest\x12\x17\n\x0f\x63ontaining_type\x18\x01 \x01(\t\x12\x18\n\x10\x65xtension_number\x18\x02 \x01(\x05\"\xb8\x03\n\x18ServerReflectionResponse\x12\x12\n\nvalid_host\x18\x01 \x01(\t\x12\x45\n\x10original_request\x18\x02 \x01(\x0b\x32+.grpc.reflection.v1.ServerReflectionRequest\x12N\n\x18\x66ile_descriptor_response\x18\x04 \x01(\x0b\x32*.grpc.reflection.v1.FileDescriptorResponseH\x00\x12U\n\x1e\x61ll_extension_numbers_response\x18\x05 \x01(\x0b\x32+.grpc.reflection.v1.ExtensionNumberResponseH\x00\x12I\n\x16list_services_response\x18\x06 \x01(\x0b\x32\'.grpc.reflection.v1.ListServiceResponseH\x00\x12;\n\x0e\x65rror_response\x18\x07 \x01(\x0b\x32!.grpc.reflection.v1.ErrorResponseH\x00\x42\x12\n\x10message_response\"7\n\x16\x46ileDescriptorResponse\x12\x1d\n\x15\x66ile_descriptor_proto\x18\x01 \x03(\x0c\"K\n\x17\x45xtensionNumberResponse\x12\x16\n\x0e\x62\x61se_type_name\x18\x01 \x01(\t\x12\x18\n\x10\x65xtension_number\x18\x02 \x03(\x05\"K\n\x13ListServiceResponse\x12\x34\n\x07service\x18\x01 \x03(\x0b\x32#.grpc.reflection.v1.ServiceResponse\"\x1f\n\x0fServiceResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\":\n\rErrorResponse\x12\x12\n\nerror_code\x18\x01 \x01(\x05\x12\x15\n\rerror_message\x18\x02 \x01(\t2\x89\x01\n\x10ServerReflection\x12u\n\x14ServerReflectionInfo\x12+.grpc.reflection.v1.ServerReflectionRequest\x1a,.grpc.reflection.v1.ServerReflectionResponse(\x01\x30\x01\x42\x66\n\x15io.grpc.reflection.v1B\x15ServerReflectionProtoP\x01Z4google.golang.org/grpc/reflection/grpc_reflection_v1b\x06proto3"
9
+
10
+ pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Grpc
14
+ module Reflection
15
+ module V1
16
+ ServerReflectionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ServerReflectionRequest").msgclass
17
+ ExtensionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ExtensionRequest").msgclass
18
+ ServerReflectionResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ServerReflectionResponse").msgclass
19
+ FileDescriptorResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.FileDescriptorResponse").msgclass
20
+ ExtensionNumberResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ExtensionNumberResponse").msgclass
21
+ ListServiceResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ListServiceResponse").msgclass
22
+ ServiceResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ServiceResponse").msgclass
23
+ ErrorResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ErrorResponse").msgclass
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,50 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # Source: grpc/reflection/v1/reflection.proto for package 'grpc.reflection.v1'
3
+ # Original file comments:
4
+ # Copyright 2016 The gRPC Authors
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ # Service exported by server reflection. A more complete description of how
19
+ # server reflection works can be found at
20
+ # https://github.com/grpc/grpc/blob/master/doc/server-reflection.md
21
+ #
22
+ # The canonical version of this proto can be found at
23
+ # https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto
24
+ #
25
+
26
+ require 'grpc'
27
+ require 'grpc/reflection/v1/reflection_pb'
28
+
29
+ module Grpc
30
+ module Reflection
31
+ module V1
32
+ module ServerReflection
33
+ class Service
34
+
35
+ include ::GRPC::GenericService
36
+
37
+ self.marshal_class_method = :encode
38
+ self.unmarshal_class_method = :decode
39
+ self.service_name = 'grpc.reflection.v1.ServerReflection'
40
+
41
+ # The reflection service is structured as a bidirectional stream, ensuring
42
+ # all related requests go to a single server.
43
+ rpc :ServerReflectionInfo, stream(::Grpc::Reflection::V1::ServerReflectionRequest), stream(::Grpc::Reflection::V1::ServerReflectionResponse)
44
+ end
45
+
46
+ Stub = Service.rpc_stub_class
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,136 @@
1
+ // Copyright 2016 gRPC authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ // Service exported by server reflection
16
+
17
+ syntax = "proto3";
18
+
19
+ package grpc.reflection.v1alpha;
20
+
21
+ service ServerReflection {
22
+ // The reflection service is structured as a bidirectional stream, ensuring
23
+ // all related requests go to a single server.
24
+ rpc ServerReflectionInfo(stream ServerReflectionRequest)
25
+ returns (stream ServerReflectionResponse);
26
+ }
27
+
28
+ // The message sent by the client when calling ServerReflectionInfo method.
29
+ message ServerReflectionRequest {
30
+ string host = 1;
31
+ // To use reflection service, the client should set one of the following
32
+ // fields in message_request. The server distinguishes requests by their
33
+ // defined field and then handles them using corresponding methods.
34
+ oneof message_request {
35
+ // Find a proto file by the file name.
36
+ string file_by_filename = 3;
37
+
38
+ // Find the proto file that declares the given fully-qualified symbol name.
39
+ // This field should be a fully-qualified symbol name
40
+ // (e.g. <package>.<service>[.<method>] or <package>.<type>).
41
+ string file_containing_symbol = 4;
42
+
43
+ // Find the proto file which defines an extension extending the given
44
+ // message type with the given field number.
45
+ ExtensionRequest file_containing_extension = 5;
46
+
47
+ // Finds the tag numbers used by all known extensions of the given message
48
+ // type, and appends them to ExtensionNumberResponse in an undefined order.
49
+ // Its corresponding method is best-effort: it's not guaranteed that the
50
+ // reflection service will implement this method, and it's not guaranteed
51
+ // that this method will provide all extensions. Returns
52
+ // StatusCode::UNIMPLEMENTED if it's not implemented.
53
+ // This field should be a fully-qualified type name. The format is
54
+ // <package>.<type>
55
+ string all_extension_numbers_of_type = 6;
56
+
57
+ // List the full names of registered services. The content will not be
58
+ // checked.
59
+ string list_services = 7;
60
+ }
61
+ }
62
+
63
+ // The type name and extension number sent by the client when requesting
64
+ // file_containing_extension.
65
+ message ExtensionRequest {
66
+ // Fully-qualified type name. The format should be <package>.<type>
67
+ string containing_type = 1;
68
+ int32 extension_number = 2;
69
+ }
70
+
71
+ // The message sent by the server to answer ServerReflectionInfo method.
72
+ message ServerReflectionResponse {
73
+ string valid_host = 1;
74
+ ServerReflectionRequest original_request = 2;
75
+ // The server set one of the following fields accroding to the message_request
76
+ // in the request.
77
+ oneof message_response {
78
+ // This message is used to answer file_by_filename, file_containing_symbol,
79
+ // file_containing_extension requests with transitive dependencies. As
80
+ // the repeated label is not allowed in oneof fields, we use a
81
+ // FileDescriptorResponse message to encapsulate the repeated fields.
82
+ // The reflection service is allowed to avoid sending FileDescriptorProtos
83
+ // that were previously sent in response to earlier requests in the stream.
84
+ FileDescriptorResponse file_descriptor_response = 4;
85
+
86
+ // This message is used to answer all_extension_numbers_of_type requst.
87
+ ExtensionNumberResponse all_extension_numbers_response = 5;
88
+
89
+ // This message is used to answer list_services request.
90
+ ListServiceResponse list_services_response = 6;
91
+
92
+ // This message is used when an error occurs.
93
+ ErrorResponse error_response = 7;
94
+ }
95
+ }
96
+
97
+ // Serialized FileDescriptorProto messages sent by the server answering
98
+ // a file_by_filename, file_containing_symbol, or file_containing_extension
99
+ // request.
100
+ message FileDescriptorResponse {
101
+ // Serialized FileDescriptorProto messages. We avoid taking a dependency on
102
+ // descriptor.proto, which uses proto2 only features, by making them opaque
103
+ // bytes instead.
104
+ repeated bytes file_descriptor_proto = 1;
105
+ }
106
+
107
+ // A list of extension numbers sent by the server answering
108
+ // all_extension_numbers_of_type request.
109
+ message ExtensionNumberResponse {
110
+ // Full name of the base type, including the package name. The format
111
+ // is <package>.<type>
112
+ string base_type_name = 1;
113
+ repeated int32 extension_number = 2;
114
+ }
115
+
116
+ // A list of ServiceResponse sent by the server answering list_services request.
117
+ message ListServiceResponse {
118
+ // The information of each service may be expanded in the future, so we use
119
+ // ServiceResponse message to encapsulate it.
120
+ repeated ServiceResponse service = 1;
121
+ }
122
+
123
+ // The information of a single service used by ListServiceResponse to answer
124
+ // list_services request.
125
+ message ServiceResponse {
126
+ // Full name of a registered service, including its package name. The format
127
+ // is <package>.<service>
128
+ string name = 1;
129
+ }
130
+
131
+ // The error code and error message sent by the server when an error occurs.
132
+ message ErrorResponse {
133
+ // This field uses the error codes defined in grpc::StatusCode.
134
+ int32 error_code = 1;
135
+ string error_message = 2;
136
+ }
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: grpc/reflection/v1alpha/reflection.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+
8
+ descriptor_data = "\n(grpc/reflection/v1alpha/reflection.proto\x12\x17grpc.reflection.v1alpha\"\x8a\x02\n\x17ServerReflectionRequest\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x1a\n\x10\x66ile_by_filename\x18\x03 \x01(\tH\x00\x12 \n\x16\x66ile_containing_symbol\x18\x04 \x01(\tH\x00\x12N\n\x19\x66ile_containing_extension\x18\x05 \x01(\x0b\x32).grpc.reflection.v1alpha.ExtensionRequestH\x00\x12\'\n\x1d\x61ll_extension_numbers_of_type\x18\x06 \x01(\tH\x00\x12\x17\n\rlist_services\x18\x07 \x01(\tH\x00\x42\x11\n\x0fmessage_request\"E\n\x10\x45xtensionRequest\x12\x17\n\x0f\x63ontaining_type\x18\x01 \x01(\t\x12\x18\n\x10\x65xtension_number\x18\x02 \x01(\x05\"\xd1\x03\n\x18ServerReflectionResponse\x12\x12\n\nvalid_host\x18\x01 \x01(\t\x12J\n\x10original_request\x18\x02 \x01(\x0b\x32\x30.grpc.reflection.v1alpha.ServerReflectionRequest\x12S\n\x18\x66ile_descriptor_response\x18\x04 \x01(\x0b\x32/.grpc.reflection.v1alpha.FileDescriptorResponseH\x00\x12Z\n\x1e\x61ll_extension_numbers_response\x18\x05 \x01(\x0b\x32\x30.grpc.reflection.v1alpha.ExtensionNumberResponseH\x00\x12N\n\x16list_services_response\x18\x06 \x01(\x0b\x32,.grpc.reflection.v1alpha.ListServiceResponseH\x00\x12@\n\x0e\x65rror_response\x18\x07 \x01(\x0b\x32&.grpc.reflection.v1alpha.ErrorResponseH\x00\x42\x12\n\x10message_response\"7\n\x16\x46ileDescriptorResponse\x12\x1d\n\x15\x66ile_descriptor_proto\x18\x01 \x03(\x0c\"K\n\x17\x45xtensionNumberResponse\x12\x16\n\x0e\x62\x61se_type_name\x18\x01 \x01(\t\x12\x18\n\x10\x65xtension_number\x18\x02 \x03(\x05\"P\n\x13ListServiceResponse\x12\x39\n\x07service\x18\x01 \x03(\x0b\x32(.grpc.reflection.v1alpha.ServiceResponse\"\x1f\n\x0fServiceResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\":\n\rErrorResponse\x12\x12\n\nerror_code\x18\x01 \x01(\x05\x12\x15\n\rerror_message\x18\x02 \x01(\t2\x93\x01\n\x10ServerReflection\x12\x7f\n\x14ServerReflectionInfo\x12\x30.grpc.reflection.v1alpha.ServerReflectionRequest\x1a\x31.grpc.reflection.v1alpha.ServerReflectionResponse(\x01\x30\x01\x62\x06proto3"
9
+
10
+ pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Grpc
14
+ module Reflection
15
+ module V1alpha
16
+ ServerReflectionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1alpha.ServerReflectionRequest").msgclass
17
+ ExtensionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1alpha.ExtensionRequest").msgclass
18
+ ServerReflectionResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1alpha.ServerReflectionResponse").msgclass
19
+ FileDescriptorResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1alpha.FileDescriptorResponse").msgclass
20
+ ExtensionNumberResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1alpha.ExtensionNumberResponse").msgclass
21
+ ListServiceResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1alpha.ListServiceResponse").msgclass
22
+ ServiceResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1alpha.ServiceResponse").msgclass
23
+ ErrorResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1alpha.ErrorResponse").msgclass
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,45 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # Source: grpc/reflection/v1alpha/reflection.proto for package 'grpc.reflection.v1alpha'
3
+ # Original file comments:
4
+ # Copyright 2016 gRPC authors.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ # Service exported by server reflection
19
+ #
20
+
21
+ require 'grpc'
22
+ require 'grpc/reflection/v1alpha/reflection_pb'
23
+
24
+ module Grpc
25
+ module Reflection
26
+ module V1alpha
27
+ module ServerReflection
28
+ class Service
29
+
30
+ include ::GRPC::GenericService
31
+
32
+ self.marshal_class_method = :encode
33
+ self.unmarshal_class_method = :decode
34
+ self.service_name = 'grpc.reflection.v1alpha.ServerReflection'
35
+
36
+ # The reflection service is structured as a bidirectional stream, ensuring
37
+ # all related requests go to a single server.
38
+ rpc :ServerReflectionInfo, stream(::Grpc::Reflection::V1alpha::ServerReflectionRequest), stream(::Grpc::Reflection::V1alpha::ServerReflectionResponse)
39
+ end
40
+
41
+ Stub = Service.rpc_stub_class
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,42 @@
1
+ module GrpcServerReflection
2
+ class DescriptorRegistry
3
+ class DependencyResolver
4
+ def collect_file_dependencies(file_proto, local_symbols, dependencies, symbol_to_filename)
5
+ file_proto.message_type.each do |msg|
6
+ collect_msg_dependencies(msg, local_symbols, dependencies, symbol_to_filename)
7
+ end
8
+
9
+ file_proto.service.each do |svc|
10
+ svc['method'].each do |m|
11
+ check_type_dependency(m.input_type, local_symbols, dependencies, symbol_to_filename)
12
+ check_type_dependency(m.output_type, local_symbols, dependencies, symbol_to_filename)
13
+ end
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def collect_msg_dependencies(msg_proto, local_symbols, dependencies, symbol_to_filename)
20
+ msg_proto.field.each do |field|
21
+ next if field.type_name.nil? || field.type_name.empty?
22
+ check_type_dependency(field.type_name, local_symbols, dependencies, symbol_to_filename)
23
+ end
24
+
25
+ msg_proto.nested_type.each do |nested|
26
+ collect_msg_dependencies(nested, local_symbols, dependencies, symbol_to_filename)
27
+ end
28
+ end
29
+
30
+ def check_type_dependency(type_name, local_symbols, dependencies, symbol_to_filename)
31
+ return if type_name.nil? || type_name.empty?
32
+
33
+ full_name = type_name.start_with?('.') ? type_name[1..] : type_name
34
+
35
+ unless local_symbols[full_name]
36
+ dep_filename = symbol_to_filename[full_name]
37
+ dependencies << dep_filename if dep_filename
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,68 @@
1
+ module GrpcServerReflection
2
+ class DescriptorRegistry
3
+ class FileDescriptorIndexer
4
+ def initialize(allowed_services:)
5
+ @allowed_services = allowed_services
6
+ end
7
+
8
+ def build_index(pool, files_by_symbol:, serialized_files:, dependencies:, service_names:)
9
+ pool.each_file_descriptor do |fd|
10
+ serialized = fd.to_proto
11
+ filename = fd.name
12
+
13
+ serialized_files[filename] = serialized
14
+
15
+ decoded = Google::Protobuf::FileDescriptorProto.decode(serialized)
16
+ dependencies[filename] = decoded.dependency.to_a
17
+
18
+ index_services(fd, filename, files_by_symbol: files_by_symbol, service_names: service_names)
19
+ index_messages(fd, filename, files_by_symbol: files_by_symbol)
20
+ index_enums(fd, filename, files_by_symbol: files_by_symbol)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def index_services(fd, filename, files_by_symbol:, service_names:)
27
+ fd.each_service do |service|
28
+ full_name = service.name
29
+ next if @allowed_services && !@allowed_services.include?(full_name)
30
+ service_names << full_name
31
+ files_by_symbol[full_name] = filename
32
+
33
+ service.each_method do |method|
34
+ files_by_symbol["#{full_name}.#{method.name}"] = filename
35
+ end
36
+ end
37
+ rescue NoMethodError => e
38
+ raise unless e.name == :each_service
39
+ end
40
+
41
+ def index_messages(fd, filename, files_by_symbol:)
42
+ fd.each_message do |msg|
43
+ index_message_recursive(msg, filename, files_by_symbol: files_by_symbol)
44
+ end
45
+ rescue NoMethodError => e
46
+ raise unless e.name == :each_message
47
+ end
48
+
49
+ def index_message_recursive(msg, filename, files_by_symbol:)
50
+ files_by_symbol[msg.name] = filename
51
+
52
+ msg.each_nested_type do |nested|
53
+ index_message_recursive(nested, filename, files_by_symbol: files_by_symbol)
54
+ end
55
+ rescue NoMethodError => e
56
+ raise unless e.name == :each_nested_type
57
+ end
58
+
59
+ def index_enums(fd, filename, files_by_symbol:)
60
+ fd.each_enum do |enum|
61
+ files_by_symbol[enum.name] = filename
62
+ end
63
+ rescue NoMethodError => e
64
+ raise unless e.name == :each_enum
65
+ end
66
+ end
67
+ end
68
+ end