gapic-generator 0.1.4 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/lib/gapic/formatting_utils.rb +65 -14
  4. data/lib/gapic/generator/version.rb +1 -1
  5. data/lib/gapic/generators/base_generator.rb +0 -8
  6. data/lib/gapic/generators/default_generator.rb +2 -4
  7. data/lib/gapic/helpers/filepath_helper.rb +45 -0
  8. data/lib/gapic/helpers/namespace_helper.rb +51 -0
  9. data/lib/gapic/presenters.rb +44 -0
  10. data/{templates/default/helpers → lib/gapic}/presenters/enum_presenter.rb +19 -14
  11. data/{templates/default/helpers → lib/gapic}/presenters/enum_value_presenter.rb +19 -12
  12. data/lib/gapic/presenters/field_presenter.rb +154 -0
  13. data/lib/gapic/presenters/file_presenter.rb +59 -0
  14. data/lib/gapic/presenters/gem_presenter.rb +172 -0
  15. data/lib/gapic/presenters/message_presenter.rb +73 -0
  16. data/lib/gapic/presenters/method_presenter.rb +307 -0
  17. data/lib/gapic/presenters/package_presenter.rb +72 -0
  18. data/lib/gapic/presenters/resource_presenter.rb +99 -0
  19. data/lib/gapic/presenters/sample_presenter.rb +84 -0
  20. data/lib/gapic/presenters/service_presenter.rb +298 -0
  21. data/lib/gapic/resource_lookup.rb +8 -1
  22. data/lib/gapic/schema/api.rb +24 -0
  23. data/lib/gapic/schema/wrappers.rb +25 -2
  24. data/templates/default/gem/gemspec.erb +1 -1
  25. data/templates/default/gem/readme.erb +2 -2
  26. data/templates/default/gem/rubocop.erb +2 -0
  27. data/templates/default/helpers/filepath_helper.rb +2 -21
  28. data/templates/default/helpers/namespace_helper.rb +2 -27
  29. data/templates/default/layouts/_ruby.erb +1 -3
  30. data/templates/default/service/client/_client.erb +7 -1
  31. data/templates/default/service/client/_paths.erb +1 -0
  32. data/templates/default/service/client/method/def/_options_defaults.erb +1 -1
  33. data/templates/default/service/client/method/def/_response_normal.erb +1 -1
  34. metadata +16 -14
  35. data/templates/default/helpers/presenter_helper.rb +0 -24
  36. data/templates/default/helpers/presenters/field_presenter.rb +0 -146
  37. data/templates/default/helpers/presenters/file_presenter.rb +0 -53
  38. data/templates/default/helpers/presenters/gem_presenter.rb +0 -140
  39. data/templates/default/helpers/presenters/message_presenter.rb +0 -66
  40. data/templates/default/helpers/presenters/method_presenter.rb +0 -293
  41. data/templates/default/helpers/presenters/package_presenter.rb +0 -65
  42. data/templates/default/helpers/presenters/resource_presenter.rb +0 -92
  43. data/templates/default/helpers/presenters/sample_presenter.rb +0 -74
  44. data/templates/default/helpers/presenters/service_presenter.rb +0 -276
@@ -1,66 +0,0 @@
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 "active_support/inflector"
18
-
19
- require_relative "field_presenter"
20
-
21
- class MessagePresenter
22
- include NamespaceHelper
23
-
24
- def initialize api, message
25
- @api = api
26
- @message = message
27
- end
28
-
29
- def name
30
- @message.name
31
- end
32
-
33
- def doc_types
34
- type_name_full
35
- end
36
-
37
- def doc_description
38
- @message.docs_leading_comments
39
- end
40
-
41
- def default_value
42
- "{}"
43
- end
44
-
45
- def type_name_full
46
- message_ruby_type @message
47
- end
48
-
49
- def fields
50
- @fields = @message.fields.map { |f| FieldPresenter.new @api, @message, f }
51
- end
52
-
53
- def nested_enums
54
- @nested_enums ||= @message.nested_enums.map { |e| EnumPresenter.new e }
55
- end
56
-
57
- def nested_messages
58
- @nested_messages ||= @message.nested_messages.map { |m| MessagePresenter.new @api, m }
59
- end
60
-
61
- protected
62
-
63
- def message_ruby_type message
64
- ruby_namespace @api, message.address.join(".")
65
- end
66
- end
@@ -1,293 +0,0 @@
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 "active_support/inflector"
18
- require "gapic/path_template"
19
- require_relative "service_presenter"
20
- require_relative "field_presenter"
21
- require_relative "sample_presenter"
22
-
23
- class MethodPresenter
24
- include NamespaceHelper
25
-
26
- def initialize api, method
27
- @api = api
28
- @method = method
29
- end
30
-
31
- def service
32
- ServicePresenter.new @api, @method.parent
33
- end
34
-
35
- def name
36
- ActiveSupport::Inflector.underscore @method.name
37
- end
38
-
39
- def kind
40
- if client_streaming?
41
- if server_streaming?
42
- :bidi
43
- else
44
- :client
45
- end
46
- elsif server_streaming?
47
- :server
48
- else
49
- :normal
50
- end
51
- end
52
-
53
- def doc_description
54
- @method.docs_leading_comments
55
- end
56
-
57
- def doc_response_type
58
- ret = return_type
59
- ret = "Gapic::Operation" if lro?
60
- if server_streaming?
61
- ret = "Enumerable<#{ret}>"
62
- elsif paged?
63
- paged_type = paged_response_type
64
- paged_type = "Gapic::Operation" if paged_type == "Google::Longrunning::Operation"
65
- ret = "Gapic::PagedEnumerable<#{paged_type}>"
66
- end
67
- ret
68
- end
69
-
70
- def arguments
71
- arguments = @method.input.fields.reject(&:output_only?)
72
- arguments.map { |arg| FieldPresenter.new @api, @method.input, arg }
73
- end
74
-
75
- def fields
76
- @method.input.fields.map { |field| FieldPresenter.new @api, @method.input, field }
77
- end
78
-
79
- def fields_with_first_oneof
80
- return fields if @method.input.oneof_decl.empty?
81
-
82
- selected_fields = []
83
- have_oneof = []
84
-
85
- @method.input.fields.each do |field|
86
- idx = field.oneof_index
87
- selected_fields << field unless have_oneof.include? idx
88
- have_oneof << idx
89
- end
90
-
91
- selected_fields.map { |field| FieldPresenter.new @api, @method.input, field }
92
- end
93
-
94
- def request_type
95
- message_ruby_type @method.input
96
- end
97
-
98
- def return_type
99
- message_ruby_type @method.output
100
- end
101
-
102
- def yields?
103
- # Server streaming RCP calls are the only one that does not yield
104
- !server_streaming?
105
- end
106
-
107
- def yield_doc_description
108
- return "Register a callback to be run when an operation is done." if lro?
109
-
110
- "Access the result along with the RPC operation"
111
- end
112
-
113
- def yield_params
114
- if lro?
115
- return [
116
- OpenStruct.new(
117
- name: "operation",
118
- doc_types: "Gapic::Operation"
119
- )
120
- ]
121
- end
122
- [
123
- OpenStruct.new(
124
- name: "result",
125
- doc_types: return_type
126
- ),
127
- OpenStruct.new(
128
- name: "operation",
129
- doc_types: "GRPC::ActiveCall::Operation"
130
- )
131
- ]
132
- end
133
-
134
- # @api.incode samples and sample_configs are yaml configuration files such as
135
- # speech_transcribe_sync_gcs.yaml
136
- def samples
137
- sample_configs = @api.incode_samples.select do |sample_config|
138
- sample_config["service"] == @method.address[0...-1].join(".") &&
139
- sample_config["rpc"] == @method.name
140
- end
141
- sample_configs.map { |sample_config| SamplePresenter.new @api, sample_config }
142
- end
143
-
144
- def lro?
145
- return paged_response_type == "Google::Longrunning::Operation" if paged?
146
-
147
- message_ruby_type(@method.output) == "Google::Longrunning::Operation"
148
- end
149
-
150
- def client_streaming?
151
- @method.client_streaming
152
- end
153
-
154
- def server_streaming?
155
- @method.server_streaming
156
- end
157
-
158
- def paged?
159
- return false if server_streaming? # Cannot page a streaming response
160
- paged_request?(@method.input) && paged_response?(@method.output)
161
- end
162
-
163
- def paged_response_type
164
- return nil unless paged_response? @method.output
165
-
166
- repeated_field = @method.output.fields.find do |f|
167
- f.label == Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED &&
168
- f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE
169
- end
170
- message_ruby_type repeated_field.message
171
- end
172
-
173
- ##
174
- #
175
- # @return [Array<String>] The segment key names.
176
- #
177
- def routing_params
178
- segments = Gapic::PathTemplate.parse method_path
179
- segments.select { |s| s.is_a? Gapic::PathTemplate::Segment }.map(&:name)
180
- end
181
-
182
- def routing_params?
183
- routing_params.any?
184
- end
185
-
186
- def grpc_service_config
187
- if @api.grpc_service_config&.service_method_level_configs&.key?(service.grpc_full_name) &&
188
- @api.grpc_service_config.service_method_level_configs[service.grpc_full_name]&.key?(grpc_method_name)
189
- @api.grpc_service_config.service_method_level_configs[service.grpc_full_name][grpc_method_name]
190
- end
191
- end
192
-
193
- def grpc_method_name
194
- @method.name
195
- end
196
-
197
- protected
198
-
199
- def message_ruby_type message
200
- ruby_namespace @api, message.address.join(".")
201
- end
202
-
203
- def doc_types_for arg
204
- if arg.message?
205
- "#{message_ruby_type arg.message} | Hash"
206
- elsif arg.enum?
207
- # TODO: handle when arg message is nil and enum is the type
208
- message_ruby_type arg.enum
209
- else
210
- case arg.type
211
- when 1, 2 then "Float"
212
- when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "Integer"
213
- when 9, 12 then "String"
214
- when 8 then "Boolean"
215
- else
216
- "Object"
217
- end
218
- end
219
- end
220
-
221
- def doc_desc_for arg
222
- return nil if arg.docs.leading_comments.empty?
223
-
224
- arg.docs.leading_comments
225
- end
226
-
227
- def default_value_for arg
228
- if arg.message?
229
- "{}"
230
- elsif arg.enum?
231
- # TODO: select the first non-0 enum value
232
- # ":ENUM"
233
- arg.enum.values.first
234
- else
235
- case arg.type
236
- when 1, 2 then "3.14"
237
- when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "42"
238
- when 9, 12 then "\"hello world\""
239
- when 8 then "true"
240
- else
241
- "Object"
242
- end
243
- end
244
- end
245
-
246
- def method_path
247
- return "" if @method.http.nil?
248
-
249
- method = [
250
- @method.http.get, @method.http.post, @method.http.put,
251
- @method.http.patch, @method.http.delete
252
- ].find { |x| !x.empty? }
253
- return method unless method.nil?
254
-
255
- return @method.http.custom.path unless @method.http.custom.nil?
256
- end
257
-
258
- def paged_request? request
259
- page_token = request.fields.find do |f|
260
- f.name == "page_token" && f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
261
- end
262
- return false if page_token.nil?
263
-
264
- page_size_types = [
265
- Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT32,
266
- Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT64
267
- ]
268
- page_size = request.fields.find do |f|
269
- f.name == "page_size" && page_size_types.include?(f.type)
270
- end
271
- return false if page_size.nil?
272
-
273
- true
274
- end
275
-
276
- def paged_response? response
277
- next_page_token = response.fields.find do |f|
278
- f.name == "next_page_token" && f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
279
- end
280
- return false if next_page_token.nil?
281
-
282
- repeated_field = response.fields.find do |f|
283
- f.label == Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED &&
284
- f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE
285
- end
286
- return false if repeated_field.nil?
287
-
288
- # We want to make sure the first repeated field is also has the lowest field number,
289
- # but the google-protobuf gem sorts fields by number, so we lose the original order.
290
-
291
- true
292
- end
293
- end
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright 2019 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 "active_support/inflector"
18
- require_relative "gem_presenter"
19
- require_relative "service_presenter"
20
-
21
- class PackagePresenter
22
- include FilepathHelper
23
- include NamespaceHelper
24
-
25
- def initialize api, package
26
- @api = api
27
- @package = package
28
- end
29
-
30
- def gem
31
- GemPresenter.new @api
32
- end
33
-
34
- def name
35
- @package
36
- end
37
-
38
- def namespace
39
- return services.first&.namespace if services.first&.namespace
40
- ruby_namespace_for_address address
41
- end
42
-
43
- def services
44
- @services ||= begin
45
- files = @api.generate_files.select { |f| f.package == @package }
46
- files.map(&:services).flatten.map { |s| ServicePresenter.new @api, s }
47
- end
48
- end
49
-
50
- def address
51
- @package.split "."
52
- end
53
-
54
- def package_require
55
- ruby_file_path @api, namespace
56
- end
57
-
58
- def package_file_path
59
- package_require + ".rb"
60
- end
61
-
62
- def empty?
63
- services.empty?
64
- end
65
- end
@@ -1,92 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright 2019 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 "gapic/path_template"
18
- require "ostruct"
19
- require "active_support/inflector"
20
-
21
- class ResourcePresenter
22
- # @param resource [Google::Api::ResourceDescriptor]
23
- def initialize resource
24
- @resource = resource
25
-
26
- @patterns = resource.pattern.map do |template|
27
- segments = Gapic::PathTemplate.parse template
28
- OpenStruct.new(
29
- template: template,
30
- segments: segments,
31
- arguments: arguments_for(segments),
32
- path_string: path_string_for(segments)
33
- )
34
- end
35
-
36
- @patterns.each do |pattern|
37
- # URI path template verification for expected proto resource usage
38
- if named_arg_patterns? pattern.segments
39
- raise ArgumentError, "only resources without named patterns are supported, " \
40
- " not #{pattern.template}"
41
- elsif positional_args? pattern.segments
42
- raise ArgumentError, "only resources with named segments are supported, " \
43
- " not #{pattern.template}"
44
- end
45
- end
46
- end
47
-
48
- def name
49
- @resource.type.split("/").delete_if(&:empty?).last
50
- end
51
-
52
- def type
53
- @resource.type
54
- end
55
-
56
- def patterns
57
- @patterns
58
- end
59
-
60
- def path_helper
61
- "#{ActiveSupport::Inflector.underscore name}_path"
62
- end
63
-
64
- private
65
-
66
- def arguments_for segments
67
- arg_segments(segments).map(&:name)
68
- end
69
-
70
- def arg_segments segments
71
- segments.select { |segment| segment.is_a? Gapic::PathTemplate::Segment }
72
- end
73
-
74
- def path_string_for segments
75
- segments.map do |segment|
76
- if segment.is_a? Gapic::PathTemplate::Segment
77
- "\#{#{segment.name}}"
78
- else
79
- # Should be a String
80
- segment
81
- end
82
- end.join
83
- end
84
-
85
- def positional_args? segments
86
- arg_segments(segments).any?(&:positional?)
87
- end
88
-
89
- def named_arg_patterns? segments
90
- arg_segments(segments).any?(&:pattern)
91
- end
92
- end