gapic-generator 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.
Files changed (148) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +13 -0
  3. data/CHANGELOG.md +26 -0
  4. data/CODE_OF_CONDUCT.md +43 -0
  5. data/CONTRIBUTING.md +28 -0
  6. data/LICENSE +202 -0
  7. data/README.md +72 -0
  8. data/bin/gapic-generator +103 -0
  9. data/bin/protoc-gen-ruby_gapic +33 -0
  10. data/default-rubocop.yml +10 -0
  11. data/gem_templates/binary.erb +20 -0
  12. data/gem_templates/dockerfile.erb +39 -0
  13. data/gem_templates/entrypoint.erb +24 -0
  14. data/gem_templates/gapic_sh.erb +97 -0
  15. data/gem_templates/gemfile.erb +8 -0
  16. data/gem_templates/gemspec.erb +36 -0
  17. data/gem_templates/generator.erb +37 -0
  18. data/gem_templates/gitignore.erb +10 -0
  19. data/gem_templates/rakefile.erb +29 -0
  20. data/gem_templates/readme.erb +69 -0
  21. data/gem_templates/rubocop.erb +16 -0
  22. data/gem_templates/shared/_header.erb +4 -0
  23. data/gem_templates/shared/_license.erb +13 -0
  24. data/gem_templates/shared/_warning.erb +1 -0
  25. data/gem_templates/test_generator.erb +13 -0
  26. data/gem_templates/test_helper.erb +25 -0
  27. data/gem_templates/version.erb +10 -0
  28. data/lib/gapic/file_formatter.rb +62 -0
  29. data/lib/gapic/gem_builder.rb +98 -0
  30. data/lib/gapic/generator.rb +30 -0
  31. data/lib/gapic/generator/version.rb +21 -0
  32. data/lib/gapic/generators/base_generator.rb +91 -0
  33. data/lib/gapic/generators/default_generator.rb +101 -0
  34. data/lib/gapic/grpc_service_config/method_config.rb +49 -0
  35. data/lib/gapic/grpc_service_config/parser.rb +196 -0
  36. data/lib/gapic/grpc_service_config/parsing_error.rb +25 -0
  37. data/lib/gapic/grpc_service_config/retry_policy.rb +51 -0
  38. data/lib/gapic/grpc_service_config/service_config.rb +42 -0
  39. data/lib/gapic/path_template.rb +35 -0
  40. data/lib/gapic/path_template/parser.rb +83 -0
  41. data/lib/gapic/path_template/segment.rb +67 -0
  42. data/lib/gapic/resource_lookup.rb +91 -0
  43. data/lib/gapic/runner.rb +76 -0
  44. data/lib/gapic/schema.rb +17 -0
  45. data/lib/gapic/schema/api.rb +264 -0
  46. data/lib/gapic/schema/loader.rb +269 -0
  47. data/lib/gapic/schema/wrappers.rb +718 -0
  48. data/lib/google/api/annotations.pb.rb +39 -0
  49. data/lib/google/api/client.pb.rb +43 -0
  50. data/lib/google/api/field_behavior.pb.rb +51 -0
  51. data/lib/google/api/http.pb.rb +60 -0
  52. data/lib/google/api/resource.pb.rb +80 -0
  53. data/lib/google/longrunning/operations.pb.rb +115 -0
  54. data/lib/google/protobuf/any.pb.rb +40 -0
  55. data/lib/google/protobuf/compiler/plugin.pb.rb +72 -0
  56. data/lib/google/protobuf/descriptor.pb.rb +359 -0
  57. data/lib/google/protobuf/empty.pb.rb +36 -0
  58. data/lib/google/rpc/status.pb.rb +46 -0
  59. data/templates/default/gem/_version.erb +2 -0
  60. data/templates/default/gem/changelog.erb +3 -0
  61. data/templates/default/gem/gemfile.erb +4 -0
  62. data/templates/default/gem/gemspec.erb +37 -0
  63. data/templates/default/gem/gitignore.erb +18 -0
  64. data/templates/default/gem/license.erb +22 -0
  65. data/templates/default/gem/rakefile.erb +27 -0
  66. data/templates/default/gem/readme.erb +24 -0
  67. data/templates/default/gem/rubocop.erb +59 -0
  68. data/templates/default/gem/version.erb +6 -0
  69. data/templates/default/gem/yardopts.erb +12 -0
  70. data/templates/default/helpers/default_helper.rb +45 -0
  71. data/templates/default/helpers/filepath_helper.rb +38 -0
  72. data/templates/default/helpers/namespace_helper.rb +44 -0
  73. data/templates/default/helpers/presenter_helper.rb +24 -0
  74. data/templates/default/helpers/presenters/enum_presenter.rb +35 -0
  75. data/templates/default/helpers/presenters/enum_value_presenter.rb +33 -0
  76. data/templates/default/helpers/presenters/field_presenter.rb +146 -0
  77. data/templates/default/helpers/presenters/file_presenter.rb +53 -0
  78. data/templates/default/helpers/presenters/gem_presenter.rb +140 -0
  79. data/templates/default/helpers/presenters/message_presenter.rb +66 -0
  80. data/templates/default/helpers/presenters/method_presenter.rb +293 -0
  81. data/templates/default/helpers/presenters/package_presenter.rb +65 -0
  82. data/templates/default/helpers/presenters/resource_presenter.rb +92 -0
  83. data/templates/default/helpers/presenters/sample_presenter.rb +74 -0
  84. data/templates/default/helpers/presenters/service_presenter.rb +276 -0
  85. data/templates/default/layouts/_ruby.erb +20 -0
  86. data/templates/default/package.erb +6 -0
  87. data/templates/default/proto_docs/_enum.erb +13 -0
  88. data/templates/default/proto_docs/_message.erb +23 -0
  89. data/templates/default/proto_docs/_proto_file.erb +9 -0
  90. data/templates/default/proto_docs/proto_file.erb +6 -0
  91. data/templates/default/proto_docs/readme.erb +5 -0
  92. data/templates/default/service.erb +8 -0
  93. data/templates/default/service/client.erb +6 -0
  94. data/templates/default/service/client/_client.erb +137 -0
  95. data/templates/default/service/client/_config.erb +155 -0
  96. data/templates/default/service/client/_credentials.erb +21 -0
  97. data/templates/default/service/client/_helpers.erb +9 -0
  98. data/templates/default/service/client/_operations.erb +88 -0
  99. data/templates/default/service/client/_paths.erb +8 -0
  100. data/templates/default/service/client/_requires.erb +1 -0
  101. data/templates/default/service/client/_resource.erb +6 -0
  102. data/templates/default/service/client/_self_configure.erb +29 -0
  103. data/templates/default/service/client/_self_configure_retry_policy.erb +15 -0
  104. data/templates/default/service/client/method/_def.erb +21 -0
  105. data/templates/default/service/client/method/def/_options_defaults.erb +29 -0
  106. data/templates/default/service/client/method/def/_request.erb +6 -0
  107. data/templates/default/service/client/method/def/_request_normal.erb +4 -0
  108. data/templates/default/service/client/method/def/_request_streaming.erb +9 -0
  109. data/templates/default/service/client/method/def/_rescue.erb +1 -0
  110. data/templates/default/service/client/method/def/_response.erb +6 -0
  111. data/templates/default/service/client/method/def/_response_normal.erb +8 -0
  112. data/templates/default/service/client/method/def/_response_paged.erb +9 -0
  113. data/templates/default/service/client/method/docs/_error.erb +2 -0
  114. data/templates/default/service/client/method/docs/_request.erb +6 -0
  115. data/templates/default/service/client/method/docs/_request_field.erb +7 -0
  116. data/templates/default/service/client/method/docs/_request_normal.erb +20 -0
  117. data/templates/default/service/client/method/docs/_request_streaming.erb +5 -0
  118. data/templates/default/service/client/method/docs/_response.erb +6 -0
  119. data/templates/default/service/client/method/docs/_sample.erb +20 -0
  120. data/templates/default/service/client/method/docs/_sample_response.erb +24 -0
  121. data/templates/default/service/client/method/docs/_samples.erb +6 -0
  122. data/templates/default/service/client/method/docs/request_field/_arg.erb +10 -0
  123. data/templates/default/service/client/method/docs/request_field/_hash.erb +19 -0
  124. data/templates/default/service/client/method/docs/sample_response/_comment.erb +5 -0
  125. data/templates/default/service/client/method/docs/sample_response/_define.erb +2 -0
  126. data/templates/default/service/client/method/docs/sample_response/_loop.erb +12 -0
  127. data/templates/default/service/client/method/docs/sample_response/_print.erb +2 -0
  128. data/templates/default/service/client/method/docs/sample_response/_write_file.erb +2 -0
  129. data/templates/default/service/client/resource/_def.erb +6 -0
  130. data/templates/default/service/client/resource/_doc.erb +8 -0
  131. data/templates/default/service/client/resource/_multi.erb +28 -0
  132. data/templates/default/service/client/resource/_single.erb +11 -0
  133. data/templates/default/service/credentials.erb +6 -0
  134. data/templates/default/service/operations.erb +6 -0
  135. data/templates/default/service/paths.erb +6 -0
  136. data/templates/default/service/test/client.erb +24 -0
  137. data/templates/default/service/test/client_operations.erb +24 -0
  138. data/templates/default/service/test/method/_assert_response.erb +11 -0
  139. data/templates/default/service/test/method/_bidi.erb +100 -0
  140. data/templates/default/service/test/method/_client.erb +84 -0
  141. data/templates/default/service/test/method/_normal.erb +69 -0
  142. data/templates/default/service/test/method/_server.erb +85 -0
  143. data/templates/default/service/test/method/_setup.erb +21 -0
  144. data/templates/default/service/test/smoke.erb +12 -0
  145. data/templates/default/shared/_header.erb +4 -0
  146. data/templates/default/shared/_license.erb +21 -0
  147. data/templates/default/shared/_warning.erb +1 -0
  148. metadata +349 -0
@@ -0,0 +1,269 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2018 Google LLC
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
+ # https://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
+ require "google/api/annotations.pb"
18
+ require "google/api/client.pb"
19
+ require "google/api/field_behavior.pb"
20
+ require "google/api/resource.pb"
21
+ require "google/longrunning/operations.pb"
22
+ require "google/protobuf/descriptor.pb"
23
+ require "gapic/schema/wrappers"
24
+
25
+ module Gapic
26
+ module Schema
27
+ # Loader
28
+ class Loader
29
+ # Initializes the loader
30
+ def initialize
31
+ @prior_messages = []
32
+ @prior_enums = []
33
+ end
34
+
35
+ # Loads a file.
36
+ #
37
+ # @param file_descriptor [Google::Protobuf::FileDescriptorProto] the
38
+ # descriptor of the proto file.
39
+ # @oaram file_to_generate [Boolean] Whether this file is to be
40
+ # generated.
41
+ def load_file file_descriptor, file_to_generate
42
+ # Setup.
43
+ address = file_descriptor.package.split "."
44
+ path = []
45
+ registry = {}
46
+
47
+ # Load the docs.
48
+ location = file_descriptor.source_code_info.location
49
+ docs = location.each_with_object({}) { |l, ans| ans[l.path] = l }
50
+
51
+ # Load top-level enums.
52
+ enums = file_descriptor.enum_type.each_with_index.map do |e, i|
53
+ load_enum registry, e, address, docs, [5, i]
54
+ end
55
+
56
+ # Load top-level messages.
57
+ messages = file_descriptor.message_type.each_with_index.map do |m, i|
58
+ load_message registry, m, address, docs, [4, i]
59
+ end
60
+ messages.each(&method(:update_fields!))
61
+
62
+ # Load services.
63
+ services = file_descriptor.service.each_with_index.map do |s, i|
64
+ load_service registry, s, address, docs, [6, i]
65
+ end
66
+
67
+ # Construct and return the file.
68
+ File.new file_descriptor, address, docs[path], messages, enums,
69
+ services, file_to_generate, registry
70
+ end
71
+
72
+ # Updates the fields of a message and it's nested messages.
73
+ #
74
+ # @param message [Message] the message whose fields and nested messages
75
+ # to update.
76
+ def update_fields! message
77
+ message.nested_messages.each(&method(:update_fields!))
78
+ non_primitives = message.fields.reject { |f| f.type_name.empty? }
79
+ non_primitives.each do |f|
80
+ f.message ||= cached_message f.type_name
81
+ f.enum ||= cached_enum f.type_name
82
+ end
83
+ end
84
+
85
+ # Loads an enum.
86
+ #
87
+ # @param descriptor [Google::Protobuf::EnumDescriptorProto] the
88
+ # descriptor of this enum.
89
+ # @param address [Enumerable<String>] The address of the parent.
90
+ # @param docs [Hash<Enumerable<Integer>,
91
+ # Google::Protobuf::SourceCodeInfo::Location>]
92
+ # A mapping of a path to the docs. See Proto#docs for more info.
93
+ # @param path [Enumerable<Integer>] The current path. This is used to
94
+ # get the docs for a proto. See Proto#docs for more info.
95
+ # @return [Enum] The loaded enum.
96
+ def load_enum registry, descriptor, address, docs, path
97
+ # Update Address.
98
+ address = address.clone << descriptor.name
99
+
100
+ # Load Enum Values
101
+ values = descriptor.value.each_with_index.map do |value, i|
102
+ load_enum_value registry, value, address, docs, path + [2, i]
103
+ end
104
+
105
+ # Construct, cache and return enum.
106
+ enum = Enum.new descriptor, address, docs[path], values
107
+ @prior_enums << enum
108
+ add_to_registry registry, address, enum
109
+ end
110
+
111
+ # Loads an enum value.
112
+ #
113
+ # @param descriptor [Google::Protobuf::EnumValueDescriptorProto] the
114
+ # descriptor of this enum value.
115
+ # @param address [Enumerable<String>] the address of the parent.
116
+ # @param docs [Hash<Enumerable<Integer>,
117
+ # Google::Protobuf::SourceCodeInfo::Location>]
118
+ # A mapping of a path to the docs. See Proto#docs for more info.
119
+ # @param path [Enumerable<Integer>] The current path. This is used to
120
+ # get the docs for a proto. See Proto#docs for more info.
121
+ # @return [EnumValue] The loaded enum value.
122
+ def load_enum_value registry, descriptor, address, docs, path
123
+ # Update Address.
124
+ address = address.clone << descriptor.name
125
+
126
+ # Construct and return value.
127
+ enum_value = EnumValue.new descriptor, address, docs[path]
128
+ add_to_registry registry, address, enum_value
129
+ end
130
+
131
+ # Loads a message. As a side effect, this alters @messages and @enums
132
+ # with the nested messages that are found.
133
+ #
134
+ # @param descriptor [Google::Protobuf::DescriptorProto] the
135
+ # descriptor of this message.
136
+ # @param address [Enumerable<String>] the address of the parent.
137
+ # @param docs [Hash<Enumerable<Integer>,
138
+ # Google::Protobuf::SourceCodeInfo::Location>]
139
+ # A mapping of a path to the docs. See Proto#docs for more info.
140
+ # @param path [Enumerable<Integer>] The current path. This is used to
141
+ # get the docs for a proto. See Proto#docs for more info.
142
+ # @return [Message] The loaded message.
143
+ def load_message registry, descriptor, address, docs, path
144
+ # Update Address.
145
+ address = address.clone << descriptor.name
146
+
147
+ # Load Children
148
+ nested_messages = descriptor.nested_type.each_with_index.map do |m, i|
149
+ load_message registry, m, address, docs, path + [3, i]
150
+ end
151
+ nested_enums = descriptor.enum_type.each_with_index.map do |e, i|
152
+ load_enum registry, e, address, docs, path + [4, i]
153
+ end
154
+ fields = descriptor.field.each_with_index.map do |f, i|
155
+ load_field registry, f, address, docs, path + [2, i]
156
+ end
157
+ extensions = descriptor.extension.each_with_index.map do |e, i|
158
+ load_field registry, e, address, docs, path + [6, i]
159
+ end
160
+
161
+ # Construct, cache, and return.
162
+ msg = Message.new(descriptor, address, docs[path], fields, extensions,
163
+ nested_messages, nested_enums)
164
+ @prior_messages << msg
165
+ add_to_registry registry, address, msg
166
+ end
167
+
168
+ # Loads a field.
169
+ #
170
+ # @param descriptor [Google::Protobuf::FieldDescriptorProto] the
171
+ # descriptor of this field.
172
+ # @param address [Enumerable<String>] The address of the parent.
173
+ # @param docs [Hash<Enumerable<Integer>,
174
+ # Google::Protobuf::SourceCodeInfo::Location>]
175
+ # A mapping of a path to the docs. See Proto#docs for more info.
176
+ # @param path [Enumerable<Integer>] The current path. This is used to
177
+ # get the docs for a proto. See Proto#docs for more info.
178
+ # @return [Field] The loaded field.
179
+ def load_field registry, descriptor, address, docs, path
180
+ # Update address.
181
+ address = address.clone << descriptor.name
182
+
183
+ # Construct and return the field.
184
+ field = Field.new(descriptor, address, docs[path],
185
+ cached_message(descriptor.type_name), cached_enum(descriptor.type_name))
186
+ add_to_registry registry, address, field
187
+ end
188
+
189
+ # Loads a service.
190
+ #
191
+ # @param descriptor [Google::Protobuf::ServiceDescriptorProto] the
192
+ # descriptor of this service.
193
+ # @param address [Enumerable<String>] The address of the parent.
194
+ # @param docs [Hash<Enumerable<Integer>,
195
+ # Google::Protobuf::SourceCodeInfo::Location>]
196
+ # A mapping of a path to the docs. See Proto#docs for more info.
197
+ # @param path [Enumerable<Integer>] The current path. This is used to
198
+ # get the docs for a proto. See Proto#docs for more info.
199
+ # @return [Service] The loaded service.
200
+ def load_service registry, descriptor, address, docs, path
201
+ # Update the address.
202
+ address = address.clone << descriptor.name
203
+
204
+ # Load children
205
+ methods = descriptor.method.each_with_index.map do |m, i|
206
+ load_method registry, m, address, docs, path + [2, i]
207
+ end
208
+
209
+ # Construct and return the service.
210
+ service = Service.new descriptor, address, docs[path], methods
211
+ add_to_registry registry, address, service
212
+ end
213
+
214
+ # Loads a method.
215
+ #
216
+ # @param descriptor [Google::Protobuf::MethodDescriptorProto] the
217
+ # descriptor of this service.
218
+ # @param address [Enumerable<String>] The address of the parent.
219
+ # @param docs [Hash<Enumerable<Integer>,
220
+ # Google::Protobuf::SourceCodeInfo::Location>]
221
+ # A mapping of a path to the docs. See Proto#docs for more info.
222
+ # @param path [Enumerable<Integer>] The current path. This is used to
223
+ # get the docs for a proto. See Proto#docs for more info.
224
+ # @return [Method] The loaded method.
225
+ def load_method registry, descriptor, address, docs, path
226
+ # Update the address.
227
+ address = address.clone << descriptor.name
228
+
229
+ # Construct and return the method.
230
+ method = Method.new(descriptor, address, docs[path],
231
+ cached_message(descriptor.input_type), cached_message(descriptor.output_type))
232
+ add_to_registry registry, address, method
233
+ end
234
+
235
+ # Retrieves an Enum if it has been seen before.
236
+ #
237
+ # @param type_name [String] the type name of the enum.
238
+ # @return [Enum | nil] The enum if it has already been seen or nil if
239
+ # no enum can be found.
240
+ def cached_enum type_name
241
+ cached_obj @prior_enums, type_name
242
+ end
243
+
244
+ # Retrieves a Message if it has been seen before.
245
+ #
246
+ # @param type_name [String] the type name of the message.
247
+ # @return [Enum | nil] The message if it has already been seen or nil if
248
+ # no message can be found.
249
+ def cached_message type_name
250
+ cached_obj @prior_messages, type_name
251
+ end
252
+
253
+ private
254
+
255
+ def add_to_registry registry, address, obj
256
+ registry[address.join(".")] = obj
257
+ obj
258
+ end
259
+
260
+ def cached_obj collection, type_name
261
+ # Remove leading dot.
262
+ type_name = type_name[1..-1] if type_name && type_name[0] == "."
263
+
264
+ # Create an address from the type & check cache.
265
+ collection.find { |m| m.address == type_name.split(".") }
266
+ end
267
+ end
268
+ end
269
+ end
@@ -0,0 +1,718 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2018 Google LLC
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
+ # https://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
+ module Gapic
18
+ module Schema
19
+ # Base class for all generic proto types including: enums, messages,
20
+ # methods and services.
21
+ #
22
+ # @!attribute [r] descriptor
23
+ # @return [Object] the descriptor of the proto
24
+ # @!attribute [r] address
25
+ # @return [Enumerable<String>] A sequence of names which determines
26
+ # the address of the proto. For example, a message named "Foo" in
27
+ # package "google.example.v1" will have the address:
28
+ # ["google", "example", "v1", "Foo"].
29
+ # and a nested message within "Foo" named "Bar" will have the address:
30
+ # ["google", "example", "v1", "Foo", "Bar"]
31
+ # @!attribute [r] docs
32
+ # @return [Google::Protobuf::SourceCodeInfo::Location]
33
+ # A Location identifies a piece of source code in a .proto file which
34
+ # corresponds to a particular definition. This information is
35
+ # intended to be useful to IDEs, code indexers, documentation
36
+ # generators, and similar tools.
37
+ #
38
+ # For example, say we have a file like:
39
+ # message Foo {
40
+ # optional string foo = 1;
41
+ # }
42
+ # Let's look at just the field definition:
43
+ # optional string foo = 1;
44
+ # ^ ^^ ^^ ^ ^^^
45
+ # a bc de f ghi
46
+ # We have the following locations:
47
+ # span path represents
48
+ # [a,i) [ 4, 0, 2, 0 ] The whole field definition.
49
+ # [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
50
+ # [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
51
+ # [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
52
+ # [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
53
+ #
54
+ # Notes:
55
+ # - A location may refer to a repeated field itself (i.e. not to any
56
+ # particular index within it). This is used whenever a set of
57
+ # elements are logically enclosed in a single code segment. For
58
+ # example, an entire extend block (possibly containing multiple
59
+ # extension definitions) will have an outer location whose path
60
+ # refers to the "extensions" repeated field without an index.
61
+ # - Multiple locations may have the same path. This happens when a
62
+ # single logical declaration is spread out across multiple places.
63
+ # The most obvious example is the "extend" block again -- there may
64
+ # be multiple extend blocks in the same scope, each of which will
65
+ # have the same path.
66
+ # - A location's span is not always a subset of its parent's span.
67
+ # For example, the "extendee" of an extension declaration appears at
68
+ # the beginning of the "extend" block and is shared by all
69
+ # extensions within the block.
70
+ # - Just because a location's span is a subset of some other
71
+ # location's span does not mean that it is a descendent. For
72
+ # example, a "group" defines both a type and a field in a single
73
+ # declaration. Thus, the locations corresponding to the type and
74
+ # field and their components will overlap.
75
+ # - Code which tries to interpret locations should probably be
76
+ # designed to ignore those that it doesn't understand, as more types
77
+ # of locations could be recorded in the future.
78
+ class Proto
79
+ extend Forwardable
80
+ attr_reader :descriptor, :address, :docs
81
+ attr_accessor :parent
82
+
83
+ # Initializes a Proto object.
84
+ # @param descriptor [Object] the protobuf
85
+ # representation of this service.
86
+ # @param address [Enumerable<String>] The address of the proto. See
87
+ # #address for more info.
88
+ # @param docs [Google::Protobuf::SourceCodeInfo::Location] The docs
89
+ # of the proto. See #docs for more info.
90
+ def initialize descriptor, address, docs
91
+ @descriptor = descriptor
92
+ @address = address
93
+ @docs = docs
94
+ end
95
+
96
+ # Gets the cleaned up leading comments documentation
97
+ def docs_leading_comments
98
+ return nil if @docs.nil?
99
+ return nil if @docs.leading_comments.empty?
100
+
101
+ @docs
102
+ .leading_comments
103
+ .each_line
104
+ .map { |line| line.start_with?(" ") ? line[1..-1] : line }
105
+ .join
106
+ .split("{").join("\\\\\\{") # The only safe way to replace with \ characters...
107
+ .split("}").join("\\}")
108
+ end
109
+
110
+ # @!method path
111
+ # @return [Array<Integer>]
112
+ # Identifies which part of the FileDescriptorProto was defined at
113
+ # this location.
114
+ #
115
+ # Each element is a field number or an index. They form a path from
116
+ # the root FileDescriptorProto to the place where the definition.
117
+ # For example, this path:
118
+ # [ 4, 3, 2, 7, 1 ]
119
+ # refers to:
120
+ # file.message_type(3) // 4, 3
121
+ # .field(7) // 2, 7
122
+ # .name() // 1
123
+ # This is because FileDescriptorProto.message_type has field number
124
+ # 4:
125
+ # repeated DescriptorProto message_type = 4;
126
+ # and DescriptorProto.field has field number 2:
127
+ # repeated FieldDescriptorProto field = 2;
128
+ # and FieldDescriptorProto.name has field number 1:
129
+ # optional string name = 1;
130
+ #
131
+ # Thus, the above path gives the location of a field name. If we
132
+ # removed the last element:
133
+ # [ 4, 3, 2, 7 ]
134
+ # this path refers to the whole field declaration (from the
135
+ # beginning of the label to the terminating semicolon).
136
+ # @!method span
137
+ # @return [Array<Integer
138
+ # Always has exactly three or four elements: start line, start
139
+ # column, end line (optional, otherwise assumed same as start line),
140
+ # end column. These are packed into a single field for efficiency.
141
+ # Note that line and column numbers are zero-based -- typically you
142
+ # will want to add 1 to each before displaying to a user.
143
+ # @!method leading_comments
144
+ # @return [String]
145
+ # If this SourceCodeInfo represents a complete declaration, these
146
+ # are any comments appearing before and after the declaration which
147
+ # appear to be attached to the declaration.
148
+ #
149
+ # A series of line comments appearing on consecutive lines, with no
150
+ # other tokens appearing on those lines, will be treated as a single
151
+ # comment.
152
+ #
153
+ # leading_detached_comments will keep paragraphs of comments that
154
+ # appear before (but not connected to) the current element. Each
155
+ # paragraph, separated by empty lines, will be one comment element
156
+ # in the repeated field.
157
+ #
158
+ # Only the comment content is provided; comment markers (e.g. //)
159
+ # are stripped out. For block comments, leading whitespace and an
160
+ # asterisk will be stripped from the beginning of each line other
161
+ # than the first. Newlines are included in the output.
162
+ #
163
+ # Examples:
164
+ #
165
+ # optional int32 foo = 1; // Comment attached to foo.
166
+ # // Comment attached to bar.
167
+ # optional int32 bar = 2;
168
+ #
169
+ # optional string baz = 3;
170
+ # // Comment attached to baz.
171
+ # // Another line attached to baz.
172
+ #
173
+ # // Comment attached to qux.
174
+ # //
175
+ # // Another line attached to qux.
176
+ # optional double qux = 4;
177
+ #
178
+ # // Detached comment for corge. This is not leading or trailing
179
+ # // comments to qux or corge because there are blank lines
180
+ # // separating it from both.
181
+ #
182
+ # // Detached comment for corge paragraph 2.
183
+ #
184
+ # optional string corge = 5;
185
+ # /* Block comment attached
186
+ # * to corge. Leading asterisks
187
+ # * will be removed. */
188
+ # /* Block comment attached to
189
+ # * grault. */
190
+ # optional int32 grault = 6;
191
+ #
192
+ # // ignored detached comments.
193
+ # @!method trailing_comments
194
+ # @return [String] (see #leading_comments)
195
+ # @!method leading_detached_comments
196
+ # @return [Array<String>] (see #leading_comments)
197
+ def_delegators(
198
+ :docs,
199
+ :path,
200
+ :leading_comments,
201
+ :trailing_comments,
202
+ :leading_detached_comments
203
+ )
204
+ end
205
+
206
+ # Wrapper for a protobuf service.
207
+ #
208
+ # @!attribute [r] methods
209
+ # @ return [Enumerable<Method>] The methods of this service.
210
+ class Service < Proto
211
+ extend Forwardable
212
+ attr_reader :methods
213
+
214
+ # Initializes a Service object.
215
+ # @param descriptor [Google::Protobuf::ServiceDescriptorProto] the
216
+ # protobuf representation of this service.
217
+ # @param address [Enumerable<String>] The address of the proto. See
218
+ # #address for more info.
219
+ # @param docs [Google::Protobuf::SourceCodeInfo::Location] The docs
220
+ # of the proto. See #docs for more info.
221
+ # @param methods [Enumerable<Method>] The methods of this service.
222
+ def initialize descriptor, address, docs, methods
223
+ super descriptor, address, docs
224
+ @methods = methods || []
225
+ @methods.each { |m| m.parent = self }
226
+ end
227
+
228
+ # @return [String] The hostname for this service
229
+ # (e.g. "foo.googleapis.com"). This should be specified with no
230
+ # prefix.
231
+ def host
232
+ options[:".google.api.default_host"] if options
233
+ end
234
+
235
+ # @return [Array<String>] The OAuth scopes information for the client.
236
+ def scopes
237
+ String(options[:".google.api.oauth_scopes"]).split "," if options
238
+ end
239
+
240
+ # @return [String] Ruby Package
241
+ def ruby_package
242
+ return nil if parent.nil?
243
+
244
+ parent.ruby_package
245
+ end
246
+
247
+ # @return [Array<Google::Api::ResourceDescriptor>] A representation of the resource.
248
+ # This is generally intended to be attached to the "name" field.
249
+ # See `google/api/resource.proto`.
250
+ def resources
251
+ require "gapic/resource_lookup"
252
+
253
+ @resources ||= Gapic::ResourceLookup.for_service self
254
+ end
255
+
256
+ # @!method name
257
+ # @return [String] the unqualified name of the service.
258
+ # @!method options
259
+ # @return [Google::Protobuf::ServiceOptions] the options of this
260
+ # service.
261
+ def_delegators(
262
+ :descriptor,
263
+ :name,
264
+ :options
265
+ )
266
+ end
267
+
268
+ # Wrapper for a protobuf method.
269
+ #
270
+ # @!attribute [r] input
271
+ # @ return [Message] The input message of this method.
272
+ # @!attribute [r] output
273
+ # @ return [Message] The output message of this method.
274
+ class Method < Proto
275
+ extend Forwardable
276
+ attr_reader :input, :output
277
+
278
+ # Initializes a method object.
279
+ # @param descriptor [Google::Protobuf::MethodDescriptorProto] the
280
+ # protobuf representation of this service.
281
+ # @param address [Enumerable<String>] The address of the proto. See
282
+ # #address for more info.
283
+ # @param docs [Google::Protobuf::SourceCodeInfo::Location] The docs
284
+ # of the proto. See #docs for more info.
285
+ # @param input [Message] The input message of this method.
286
+ # @param output [Message] The output message of this method.
287
+ def initialize descriptor, address, docs, input, output
288
+ super descriptor, address, docs
289
+ @input = input
290
+ @output = output
291
+ end
292
+
293
+ # @return [Array<Array<String>>] The parameter lists
294
+ # defined for this method. See `google/api/client.proto`.
295
+ def signatures
296
+ return [] if options.nil?
297
+
298
+ Array(options[:".google.api.method_signature"]).map do |sig|
299
+ String(sig).split ","
300
+ end
301
+ end
302
+
303
+ # @return [Google::Longrunning::OperationInfo] Additional information
304
+ # regarding long-running operations.
305
+ # In particular, this specifies the types that are returned from
306
+ # long-running operations.
307
+ # Required for methods that return `google.longrunning.Operation`;
308
+ # invalid otherwise.
309
+ def operation_info
310
+ options[:".google.longrunning.operation_info"] if options
311
+ end
312
+
313
+ # @return [Google::Api::HttpRule] The HTTP bindings for this method. See
314
+ # `google/api/http.proto`.
315
+ def http
316
+ options[:".google.api.http"] if options
317
+ end
318
+
319
+ # @!method name
320
+ # @return [String] the unqualified name of the method.
321
+ # @!method options
322
+ # @return [Google::Protobuf::MethodOptions] the options of this
323
+ # method.
324
+ # @!method client_streaming
325
+ # @return [Boolean]
326
+ # Identifies if client streams multiple client messages.
327
+ # @!method server_streaming
328
+ # @return [Boolean]
329
+ # Identifies if server streams multiple server messages.
330
+ def_delegators(
331
+ :descriptor,
332
+ :name,
333
+ :options,
334
+ :client_streaming,
335
+ :server_streaming
336
+ )
337
+ end
338
+
339
+ # Wrapper for a protobuf file.
340
+ #
341
+ # @!attribute [r] messages
342
+ # @ return [Enumerable<Message>] The top level messages contained in
343
+ # this file.
344
+ # @!attribute [r] enums
345
+ # @ return [Enumerable<Enum>] The top level enums contained in this
346
+ # file.
347
+ # @!attribute [r] services
348
+ # @ return [Enumerable<Service>] The services contained in this file.
349
+ class File < Proto
350
+ extend Forwardable
351
+ attr_reader :messages, :enums, :services, :registry
352
+
353
+ # Initializes a message object.
354
+ # @param descriptor [Google::Protobuf::DescriptorProto] the protobuf
355
+ # representation of this service.
356
+ # @param address [Enumerable<String>] The address of the proto. See
357
+ # #address for more info.
358
+ # @param docs [Google::Protobuf::SourceCodeInfo::Location] The docs
359
+ # of the proto. See #docs for more info.
360
+ # @param messages [Enumerable<Message>] The top level messages of this
361
+ # file.
362
+ # @param enums [Enumerable<Enum>] The top level enums of this file.
363
+ # @param services [Enumerable<Service>] The services of this file.
364
+ # @param generate [Boolean] Whether this file should be generated.
365
+ def initialize descriptor, address, docs, messages, enums, services,
366
+ generate, registry
367
+ super descriptor, address, docs
368
+ @messages = messages || []
369
+ @enums = enums || []
370
+ @services = services || []
371
+ @generate = generate
372
+ @registry = registry
373
+
374
+ # Apply parent
375
+ @messages.each { |m| m.parent = self }
376
+ @enums.each { |m| m.parent = self }
377
+ @services.each { |m| m.parent = self }
378
+ end
379
+
380
+ def lookup address
381
+ address = address.split(".").reject(&:empty?).join(".")
382
+ @registry[address]
383
+ end
384
+
385
+ def generate?
386
+ @generate
387
+ end
388
+
389
+ # @return [String] Ruby Package
390
+ def ruby_package
391
+ options[:ruby_package] if options
392
+ end
393
+
394
+ # @return [Array<Google::Api::ResourceDescriptor>] A representation of the resource.
395
+ # This is generally intended to be attached to the "name" field.
396
+ # See `google/api/resource.proto`.
397
+ def resources
398
+ options[:".google.api.resource_definition"] if options
399
+ end
400
+
401
+ # @!method name
402
+ # @return [String] file name, relative to root of source tree.
403
+ # @!method package
404
+ # @return [String] package of the file. e.g. "foo", "foo.bar", etc.
405
+ # @!method dependency
406
+ # @return [Array<String>] Names of files imported by this file.
407
+ # @!method public_dependency
408
+ # @return [Array<Integer>] Indexes of the public imported files in the
409
+ # dependency list returned by #dependency.
410
+ # @!method options
411
+ # @return [Google::Protobuf::FileOptions] the options of this file.
412
+ def_delegators(
413
+ :descriptor,
414
+ :name,
415
+ :package,
416
+ :dependency,
417
+ :public_dependency,
418
+ :options
419
+ )
420
+ end
421
+
422
+ # Wrapper for a protobuf enum.
423
+ #
424
+ # @!attribute [r] values
425
+ # @ return [EnumValue] the EnumValues contained in this file.
426
+ class Enum < Proto
427
+ extend Forwardable
428
+ attr_reader :values
429
+
430
+ # Initializes a message object.
431
+ # @param descriptor [Google::Protobuf::DescriptorProto] the protobuf
432
+ # representation of this service.
433
+ # @param address [Enumerable<String>] The address of the proto. See
434
+ # #address for more info.
435
+ # @param docs [Google::Protobuf::SourceCodeInfo::Location] The docs
436
+ # of the proto. See #docs for more info.
437
+ # @param values [Enumerable<EnumValue>] The EnumValues of this enum.
438
+ def initialize descriptor, address, docs, values
439
+ super descriptor, address, docs
440
+ @values = values || []
441
+ @values.each { |v| v.parent = self }
442
+ end
443
+
444
+ # @!method name
445
+ # @return [String] the unqualified name of the Enum.
446
+ # @!method options
447
+ # @return [Array<Google::Protobuf::EnumOptions>] the options of the
448
+ # enum.
449
+ def_delegators(
450
+ :descriptor,
451
+ :name,
452
+ :options
453
+ )
454
+ end
455
+
456
+ # Wrapper for a protobuf Enum Value.
457
+ class EnumValue < Proto
458
+ extend Forwardable
459
+
460
+ # Initializes a message object.
461
+ # @param descriptor [Google::Protobuf::DescriptorProto] the protobuf
462
+ # representation of this service.
463
+ # @param address [Enumerable<String>] The address of the proto. See
464
+ # #address for more info.
465
+ # @param docs [Google::Protobuf::SourceCodeInfo::Location] The docs
466
+ # of the proto. See #docs for more info.
467
+ def initialize descriptor, address, docs
468
+ super descriptor, address, docs
469
+ end
470
+
471
+ # @!method name
472
+ # @return [String] the unqualified name of the EnumValue
473
+ # @!method number
474
+ # @return [Integer] The number value.
475
+ # @!method options
476
+ # @return [Array<Google::Protobuf::EnumValueOptions>]
477
+ # The options of the enum value.
478
+ def_delegators(
479
+ :descriptor,
480
+ :name,
481
+ :number,
482
+ :options
483
+ )
484
+ end
485
+
486
+ # Wrapper for a protobuf Message.
487
+ #
488
+ # @!attribute [r] fields
489
+ # @ return [Enumerable<Field>] The fields of a message.
490
+ # @!attribute [r] extensions
491
+ # @ return [Enumerable<Field>] The extensions of a message.
492
+ # @!attribute [r] nested_messages
493
+ # @ return [Enumerable<Message>] The nested message declarations of a
494
+ # message.
495
+ # @!attribute [r] nested_enums
496
+ # @ return [Enumerable<Enum>] The nested enum declarations of a message.
497
+ class Message < Proto
498
+ extend Forwardable
499
+ attr_reader :fields, :extensions, :nested_messages, :nested_enums
500
+
501
+ # Initializes a message object.
502
+ # @param descriptor [Google::Protobuf::DescriptorProto] the protobuf
503
+ # representation of this service.
504
+ # @param address [Enumerable<String>] The address of the proto. See
505
+ # #address for more info.
506
+ # @param docs [Google::Protobuf::SourceCodeInfo::Location] The docs
507
+ # of the proto. See #docs for more info.
508
+ # @param fields [Enumerable<Field>] The fields of this message.
509
+ # @param extensions [Enumerable<Field>] The extensions of this message.
510
+ # @param nested_messages [Enumerable<Message>] The nested message
511
+ # declarations of this message.
512
+ # @param nested_enums [Enumerable<Enum>] The nested enum declarations
513
+ # of this message.
514
+ def initialize descriptor, address, docs, fields, extensions,
515
+ nested_messages, nested_enums
516
+ super descriptor, address, docs
517
+ @fields = fields || []
518
+ @extensions = extensions || []
519
+ @nested_messages = nested_messages || []
520
+ @nested_enums = nested_enums || []
521
+
522
+ @fields.each { |f| f.parent = self }
523
+ @extensions.each { |x| x.parent = self }
524
+ @nested_messages.each { |m| m.parent = self }
525
+ @nested_enums.each { |e| e.parent = self }
526
+ end
527
+
528
+ # @return [Google::Api::ResourceDescriptor] A representation of the resource.
529
+ # This is generally intended to be attached to the "name" field.
530
+ # See `google/api/resource.proto`.
531
+ def resource
532
+ options[:".google.api.resource"] if options
533
+ end
534
+
535
+ # @return [Boolean] whether this type is a map entry
536
+ def map_entry?
537
+ descriptor.options&.map_entry
538
+ end
539
+
540
+ # @!method name
541
+ # @return [String] the unqualified name of the message.
542
+ # @!method oneof_decl
543
+ # @return [Array<Google::Protobuf::OneofDescriptorProto>]
544
+ # The oneofs declared in this message.
545
+ # @!method options
546
+ # @return [Array<Google::Protobuf::MessageOptions>]
547
+ # The options of this meessage.
548
+ def_delegators(
549
+ :descriptor,
550
+ :name,
551
+ :oneof_decl,
552
+ :options
553
+ )
554
+ end
555
+
556
+ # Wrapper for a protobuf Field.
557
+ #
558
+ # @!attribute [r] message
559
+ # @ return [Message | nil] The message if the field is a message, nil
560
+ # otherwise.
561
+ # @!attribute [r] enum
562
+ # @ return [Enum | nil] The enum if the field is an enum, nil
563
+ # otherwise.
564
+ class Field < Proto
565
+ extend Forwardable
566
+ attr_reader :message, :enum
567
+ attr_writer :message, :enum
568
+
569
+ # Initializes a message object.
570
+ # @param descriptor [Google::Protobuf::FieldDescriptorProto] the
571
+ # protobuf representation of this service.
572
+ # @param address [Enumerable<String>] The address of the proto. See
573
+ # #address for more info.
574
+ # @param docs [Google::Protobuf::SourceCodeInfo::Location] The docs
575
+ # of the proto. See #docs for more info.
576
+ # @param message [Message | nil] The message if the field is a message,
577
+ # nil otherwise.
578
+ # @param enum [Enum | nil] The enum if the field is an enum, nil
579
+ # otherwise.
580
+ def initialize descriptor, address, docs, message, enum
581
+ super descriptor, address, docs
582
+ @message = message
583
+ @enum = enum
584
+ end
585
+
586
+ # Whether this field is a message.
587
+ # @return [Boolean]
588
+ def message?
589
+ return true if @message
590
+
591
+ false
592
+ end
593
+
594
+ # Whether this field is a repeated field.
595
+ # @return [Boolean]
596
+ def repeated?
597
+ label == Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED
598
+ end
599
+
600
+ # Whether this field is an enum.
601
+ # @return [Boolean]
602
+ def enum?
603
+ return true if @enum
604
+
605
+ false
606
+ end
607
+
608
+ # Whether this field is a map
609
+ # @return [Boolean]
610
+ def map?
611
+ return true if repeated? && @message&.map_entry?
612
+
613
+ false
614
+ end
615
+
616
+ # @return [String] A reference to another resource message or resource
617
+ # definition. See `google/api/resource.proto`.
618
+ def resource_reference
619
+ options[:".google.api.resource_reference"] if options
620
+ end
621
+
622
+ # @return [Array<Google::Api::FieldBehavior>] A designation of a
623
+ # specific field behavior (required, output only, etc.) in protobuf
624
+ # messages.
625
+ def field_behavior
626
+ return options[:".google.api.field_behavior"] if options
627
+
628
+ []
629
+ end
630
+
631
+ # Specifically denotes a field as optional. While all fields in protocol
632
+ # buffers are optional, this may be specified for emphasis if
633
+ # appropriate.
634
+ def optional?
635
+ field_behavior.include? Google::Api::FieldBehavior::OPTIONAL
636
+ end
637
+
638
+ # Denotes a field as required. This indicates that the field **must** be
639
+ # provided as part of the request, and failure to do so will cause an
640
+ # error (usually `INVALID_ARGUMENT`).
641
+ def required?
642
+ field_behavior.include? Google::Api::FieldBehavior::REQUIRED
643
+ end
644
+
645
+ # Denotes a field as output only. This indicates that the field is
646
+ # provided in responses, but including the field in a request does
647
+ # nothing (the server *must* ignore it and *must not* throw an error as
648
+ # a result of the field's presence).
649
+ def output_only?
650
+ field_behavior.include? Google::Api::FieldBehavior::OUTPUT_ONLY
651
+ end
652
+
653
+ # Denotes a field as input only. This indicates that the field is
654
+ # provided in requests, and the corresponding field is not included in
655
+ # output.
656
+ def input_only?
657
+ field_behavior.include? Google::Api::FieldBehavior::INPUT_ONLY
658
+ end
659
+
660
+ # Denotes a field as immutable. This indicates that the field may be set
661
+ # once in a request to create a resource, but may not be changed
662
+ # thereafter.
663
+ def immutable?
664
+ field_behavior.include? Google::Api::FieldBehavior::IMMUTABLE
665
+ end
666
+
667
+ # @!method name
668
+ # @return [String] the unqualified name of the field.
669
+ # @!method number
670
+ # @return [Integer] the number of the field.
671
+ # @!method label
672
+ # @return [Google::Protobuf::FieldDescriptorProto::Label]
673
+ # The label of the field.
674
+ # @!method type
675
+ # @return [Google::Protobuf::FieldDescriptorProto::Type]
676
+ # If type_name is set, this need not be set. If both this and
677
+ # type_name are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or
678
+ # TYPE_GROUP.
679
+ # @!method type_name
680
+ # @return [String]
681
+ # For message and enum types, this is the name of the type. If the
682
+ # name starts with a '.', it is fully-qualified. Otherwise,
683
+ # C++-like scoping rules are used to find the type (i.e. first the
684
+ # nested types within this message are searched, then within the
685
+ # parent, on up to the root namespace).
686
+ # @!method default_value
687
+ # @return [String]
688
+ # For numeric types, contains the original text representation of
689
+ # the value. For booleans, "true" or "false". For strings, contains
690
+ # the default text contents (not escaped in any way). For bytes,
691
+ # contains the C escaped value. All bytes >= 128 are escaped.
692
+ # @!method oneof_index
693
+ # @return [Integer]
694
+ # If set, gives the index of a oneof in the containing type's
695
+ # oneof_decl list. This field is a member of that oneof.
696
+ # @!method json_name
697
+ # @return [String]
698
+ # JSON name of this field. The value is set by protocol compiler. If
699
+ # the user has set a "json_name" option on this field, that option's
700
+ # value will be used. Otherwise, it's deduced from the field's name
701
+ # by converting it to camelCase.
702
+ # @!method options
703
+ # @return [Google::Protobuf::FieldOptions] the options of this field.
704
+ def_delegators(
705
+ :descriptor,
706
+ :name,
707
+ :number,
708
+ :label,
709
+ :type,
710
+ :type_name,
711
+ :default_value,
712
+ :oneof_index,
713
+ :json_name,
714
+ :options
715
+ )
716
+ end
717
+ end
718
+ end