gapic-generator 0.6.14 → 0.7.4

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/bin/protoc-gen-ruby_gapic +6 -6
  4. data/lib/gapic/file_formatter.rb +2 -1
  5. data/lib/gapic/formatting_utils.rb +4 -4
  6. data/lib/gapic/generator/version.rb +1 -1
  7. data/lib/gapic/generators/default_generator.rb +8 -5
  8. data/lib/gapic/generators/default_generator_parameters.rb +8 -4
  9. data/lib/gapic/grpc_service_config/method_config.rb +2 -1
  10. data/lib/gapic/grpc_service_config/retry_policy.rb +4 -1
  11. data/lib/gapic/grpc_service_config/service_config.rb +2 -1
  12. data/lib/gapic/path_pattern/parser.rb +1 -1
  13. data/lib/gapic/path_pattern/pattern.rb +2 -1
  14. data/lib/gapic/path_pattern/segment.rb +10 -3
  15. data/lib/gapic/presenters.rb +2 -0
  16. data/lib/gapic/presenters/field_presenter.rb +44 -0
  17. data/lib/gapic/presenters/gem_presenter.rb +4 -1
  18. data/lib/gapic/presenters/method_presenter.rb +32 -16
  19. data/lib/gapic/presenters/method_rest_presenter.rb +186 -0
  20. data/lib/gapic/presenters/package_presenter.rb +21 -3
  21. data/lib/gapic/presenters/resource_presenter.rb +2 -1
  22. data/lib/gapic/presenters/sample_presenter.rb +6 -1
  23. data/lib/gapic/presenters/service_presenter.rb +48 -10
  24. data/lib/gapic/presenters/service_rest_presenter.rb +157 -0
  25. data/lib/gapic/schema/api.rb +48 -19
  26. data/lib/gapic/schema/parameter_schema.rb +4 -1
  27. data/lib/gapic/schema/request_param_parser.rb +44 -10
  28. data/lib/gapic/schema/request_parameter.rb +5 -1
  29. data/lib/gapic/schema/wrappers.rb +31 -18
  30. data/lib/gapic/uri_template/parser.rb +4 -6
  31. data/templates/default/gem/gemspec.erb +2 -2
  32. data/templates/default/gem/readme.erb +2 -2
  33. data/templates/default/gem/rubocop.erb +2 -12
  34. data/templates/default/lib/_package.erb +11 -1
  35. data/templates/default/lib/_service.erb +31 -1
  36. data/templates/default/lib/rest/_rest.erb +11 -0
  37. data/templates/default/service/client/_config.erb +2 -2
  38. data/templates/default/service/rest.erb +6 -0
  39. data/templates/default/service/rest/client.erb +6 -0
  40. data/templates/default/service/rest/client/_client.erb +115 -0
  41. data/templates/default/service/rest/client/_config.erb +74 -0
  42. data/templates/default/service/rest/client/_requires.erb +1 -0
  43. data/templates/default/service/rest/client/method/_def.erb +18 -0
  44. data/templates/default/service/rest/client/method/def/_options_defaults.erb +14 -0
  45. data/templates/default/service/rest/client/method/def/_rescue.erb +3 -0
  46. data/templates/default/service/rest/client/method/def/_response_normal.erb +17 -0
  47. data/templates/default/service/rest/client/method/docs/_error.erb +2 -0
  48. data/templates/default/service/rest/client/method/docs/_request.erb +27 -0
  49. data/templates/default/service/rest/client/method/docs/_result.erb +6 -0
  50. data/templates/default/service/rest/grpc_transcoding.erb +6 -0
  51. data/templates/default/service/rest/grpc_transcoding/_grpc_transcoding.erb +9 -0
  52. data/templates/default/service/rest/grpc_transcoding/method/_def.erb +21 -0
  53. data/templates/default/service/rest/grpc_transcoding/method/def/_query_string_param.erb +8 -0
  54. data/templates/default/service/test/method/_normal.erb +1 -1
  55. data/templates/default/service/test/method/_server.erb +1 -1
  56. metadata +27 -8
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 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/uri_template"
18
+
19
+ module Gapic
20
+ module Presenters
21
+ ##
22
+ # A presenter for rpc methods (REST submethods)
23
+ #
24
+ class MethodRestPresenter
25
+ def initialize main_method
26
+ @main_method = main_method
27
+ @proto_method = main_method.method
28
+ end
29
+
30
+ ##
31
+ # @return [Boolean] Whether a http verb is present for this method
32
+ #
33
+ def verb?
34
+ !verb.nil?
35
+ end
36
+
37
+ ##
38
+ # @return [Symbol] a http verb for this method
39
+ #
40
+ def verb
41
+ return nil if @proto_method.http.nil?
42
+
43
+ method = {
44
+ get: @proto_method.http.get,
45
+ post: @proto_method.http.post,
46
+ put: @proto_method.http.put,
47
+ patch: @proto_method.http.patch,
48
+ delete: @proto_method.http.delete
49
+ }.find { |_, value| !value.empty? }
50
+
51
+ method[0] unless method.nil?
52
+ end
53
+
54
+ ##
55
+ # @return [Boolean] Whether a method path is present and non-empty
56
+ #
57
+ def path?
58
+ !path.empty?
59
+ end
60
+
61
+ ##
62
+ # @return [String] A method path or an empty string if not present
63
+ #
64
+ def path
65
+ return "" if @proto_method.http.nil?
66
+
67
+ verb_path = [
68
+ @proto_method.http.get, @proto_method.http.post, @proto_method.http.put,
69
+ @proto_method.http.patch, @proto_method.http.delete
70
+ ].find { |x| !x.empty? }
71
+
72
+ verb_path || @proto_method.http.custom&.path || ""
73
+ end
74
+
75
+ ##
76
+ # @return [Boolean] Whether any routing params are present
77
+ #
78
+ def routing_params?
79
+ routing_params.any?
80
+ end
81
+
82
+ ##
83
+ # @return [Array<String>] The segment key names.
84
+ #
85
+ def routing_params
86
+ Gapic::UriTemplate.parse_arguments path
87
+ end
88
+
89
+ ##
90
+ # Performs a limited version of grpc transcoding to create a string that will interpolate
91
+ # the values from the request object to create a request URI at runtime.
92
+ # Currently only supports "value" into "request_object.value"
93
+ # @param [String] request_obj_name the name of the request object for the interpolation
94
+ # defaults to "request_pb"
95
+ # @return [String] A string to interpolate values from the request object into URI
96
+ #
97
+ def uri_interpolated request_obj_name = "request_pb"
98
+ return path unless routing_params?
99
+
100
+ routing_params.reduce path do |uri, param|
101
+ param_esc = Regexp.escape param
102
+ uri.gsub(/{#{param_esc}[^}]*}/, "\#{#{request_obj_name}.#{param}}")
103
+ end
104
+ end
105
+
106
+ ##
107
+ # @return [Boolean] Whether method has body specified in proto
108
+ #
109
+ def body?
110
+ return false if @proto_method.http.nil?
111
+
112
+ !@proto_method.http.body.empty?
113
+ end
114
+
115
+ ##
116
+ # Name of the variable to use for storing the body result of the transcoding call
117
+ # Normally "body" but use "_body" for discarding the result for
118
+ # the calls that do not send body
119
+ # @return [String]
120
+ def body_var_name
121
+ body? ? "body" : "_body"
122
+ end
123
+
124
+ ##
125
+ # @return [String] A body specified for the given method in proto or an empty string if not specified
126
+ #
127
+ def body
128
+ @proto_method.http&.body || ""
129
+ end
130
+
131
+ ##
132
+ # Performs a limited version of grpc transcoding to create a string that will interpolate
133
+ # the values from the request object to create a request body at runtime.
134
+ # Currently only supports either "*" for "the whole request object" or
135
+ # "value" for "request_object.value"
136
+ #
137
+ # @param [String] request_obj_name the name of the request object for the interpolation
138
+ # defaults to "request_pb"
139
+ #
140
+ # @return [String] A string to interpolate values from the request object into body
141
+ #
142
+ def body_interpolated request_obj_name = "request_pb"
143
+ return "\"\"" unless body?
144
+
145
+ return "#{request_obj_name}.to_json" if body == "*"
146
+
147
+ "#{request_obj_name}.#{body}.to_json"
148
+ end
149
+
150
+ ##
151
+ # @return [Boolean] whether any query string parameters are present
152
+ #
153
+ def query_string_params?
154
+ query_string_params.any?
155
+ end
156
+
157
+ # @return [Array<String>]
158
+ def query_string_params
159
+ return [] if body?
160
+
161
+ routing_params_set = routing_params.to_set
162
+ @main_method.arguments
163
+ .reject { |arg| routing_params_set.include? arg.name }
164
+ .reject(&:message?)
165
+ .reject { |arg| arg.default_value_for_type.nil? }
166
+ end
167
+
168
+ ##
169
+ # Name of the variable to use for storing the query_string_params result of the transcoding call
170
+ # Normally "query_string_params" but use "_query_string_params" for discarding the result for
171
+ # the calls that do not sent query_string_params
172
+ # @return [String]
173
+ def query_string_params_var_name
174
+ query_string_params? ? "query_string_params" : "_query_string_params"
175
+ end
176
+
177
+ ##
178
+ # Name for the GRPC transcoding helper method
179
+ #
180
+ # @return [String]
181
+ def transcoding_helper_name
182
+ "transcode_#{@main_method.name}"
183
+ end
184
+ end
185
+ end
186
+ end
@@ -54,7 +54,10 @@ module Gapic
54
54
  namespace.split("::").last
55
55
  end
56
56
 
57
+ ##
57
58
  # Services whose clients should be generated in this package namespace.
59
+ # @return [Enumerable<Gapic::Presenters::ServicePresenter>]
60
+ #
58
61
  def services
59
62
  @services ||= begin
60
63
  files = @api.generate_files.select { |f| f.package == @package }
@@ -77,7 +80,7 @@ module Gapic
77
80
  end
78
81
 
79
82
  def package_file_path
80
- package_require + ".rb"
83
+ "#{package_require}.rb"
81
84
  end
82
85
 
83
86
  def package_directory_name
@@ -89,7 +92,7 @@ module Gapic
89
92
  end
90
93
 
91
94
  def helpers_file_path
92
- helpers_require + ".rb"
95
+ "#{helpers_require}.rb"
93
96
  end
94
97
 
95
98
  def helpers_file_name
@@ -97,7 +100,7 @@ module Gapic
97
100
  end
98
101
 
99
102
  def helpers_require
100
- package_require + "/_helpers"
103
+ "#{package_require}/_helpers"
101
104
  end
102
105
 
103
106
  ##
@@ -117,6 +120,21 @@ module Gapic
117
120
  services: services.map { |s| [s.grpc_service_name, s.drift_manifest] }.to_h
118
121
  }
119
122
  end
123
+
124
+ ##
125
+ # How comments in the generated libraries refer to the GRPC client
126
+ # if no REST code is generated, this should just be "client",
127
+ # if REST code is generated, this should be disambiguated into the "GRPC client"
128
+ #
129
+ # Since we are using first service for an indication of whether package generates
130
+ # REST code, it's OK to defer this to the first service as well.
131
+ # For packages with no services the value of this does not really matter as
132
+ # no client generation docs will be generated.
133
+ #
134
+ # @return [String]
135
+ def grpc_client_designation
136
+ services.first&.grpc_client_designation || ""
137
+ end
120
138
  end
121
139
  end
122
140
  end
@@ -59,7 +59,8 @@ module Gapic
59
59
  @path_string = build_path_string
60
60
  end
61
61
 
62
- attr_reader :pattern, :path_string
62
+ attr_reader :pattern
63
+ attr_reader :path_string
63
64
 
64
65
  def useful_for_helpers?
65
66
  !@parsed_pattern.positional_segments? && !@parsed_pattern.nontrivial_pattern_segments?
@@ -58,7 +58,12 @@ module Gapic
58
58
  # Representation of a request field.
59
59
  #
60
60
  class RequestField
61
- attr_reader :field, :value, :input_parameter, :comment, :value_is_file
61
+ attr_reader :field
62
+ attr_reader :value
63
+ attr_reader :input_parameter
64
+ attr_reader :comment
65
+ attr_reader :value_is_file
66
+
62
67
  def initialize field
63
68
  @field = field["field"]
64
69
  @value = convert field["value"]
@@ -27,11 +27,15 @@ module Gapic
27
27
  include Gapic::Helpers::FilepathHelper
28
28
  include Gapic::Helpers::NamespaceHelper
29
29
 
30
+ # @return [Gapic::Presenters::ServiceRestPresenter]
31
+ attr_reader :rest
32
+
30
33
  def initialize gem_presenter, api, service, parent_service: nil
31
34
  @gem_presenter = gem_presenter
32
35
  @api = api
33
36
  @service = service
34
37
  @parent_service = parent_service
38
+ @rest = ServiceRestPresenter.new self, api
35
39
  end
36
40
 
37
41
  def gem
@@ -46,10 +50,11 @@ module Gapic
46
50
  PackagePresenter.new @gem_presenter, @api, @service.parent.package
47
51
  end
48
52
 
53
+ ##
54
+ # @return [Enumerable<Gapic::Presenters::MethodPresenter>]
55
+ #
49
56
  def methods
50
- @methods ||= begin
51
- @service.methods.map { |m| MethodPresenter.new self, @api, m }
52
- end
57
+ @methods ||= @service.methods.map { |m| MethodPresenter.new self, @api, m }
53
58
  end
54
59
 
55
60
  def address
@@ -144,7 +149,7 @@ module Gapic
144
149
  end
145
150
 
146
151
  def service_file_path
147
- service_require + ".rb"
152
+ "#{service_require}.rb"
148
153
  end
149
154
 
150
155
  def service_file_name
@@ -180,7 +185,7 @@ module Gapic
180
185
  end
181
186
 
182
187
  def client_file_path
183
- client_require + ".rb"
188
+ "#{client_require}.rb"
184
189
  end
185
190
 
186
191
  def client_file_name
@@ -220,7 +225,7 @@ module Gapic
220
225
  end
221
226
 
222
227
  def credentials_file_path
223
- credentials_require + ".rb"
228
+ "#{credentials_require}.rb"
224
229
  end
225
230
 
226
231
  def credentials_file_name
@@ -232,7 +237,7 @@ module Gapic
232
237
  end
233
238
 
234
239
  def helpers_file_path
235
- helpers_require + ".rb"
240
+ "#{helpers_require}.rb"
236
241
  end
237
242
 
238
243
  def helpers_file_name
@@ -260,7 +265,7 @@ module Gapic
260
265
  end
261
266
 
262
267
  def paths_file_path
263
- paths_require + ".rb"
268
+ "#{paths_require}.rb"
264
269
  end
265
270
 
266
271
  def paths_file_name
@@ -271,6 +276,29 @@ module Gapic
271
276
  ruby_file_path @api, "#{service_name_full}::#{paths_name}"
272
277
  end
273
278
 
279
+ def generate_rest_clients?
280
+ @api.generate_rest_clients?
281
+ end
282
+
283
+ def generate_grpc_clients?
284
+ @api.generate_grpc_clients?
285
+ end
286
+
287
+ ##
288
+ # @return [Boolean] whether this service contains any methods with REST bindings
289
+ #
290
+ def methods_rest_bindings?
291
+ methods_rest_bindings.any?
292
+ end
293
+
294
+ ##
295
+ # @return [Enumerable<Gapic::Presenters::MethodPresenter>]
296
+ # List of mods for which REST bindings are present and REST methods can be generated
297
+ #
298
+ def methods_rest_bindings
299
+ methods.select { |method| method.rest.path? && method.rest.verb? }
300
+ end
301
+
274
302
  def test_client_file_path
275
303
  service_file_path.sub ".rb", "_test.rb"
276
304
  end
@@ -308,7 +336,7 @@ module Gapic
308
336
  end
309
337
 
310
338
  def operations_file_path
311
- operations_require + ".rb"
339
+ "#{operations_require}.rb"
312
340
  end
313
341
 
314
342
  def operations_file_name
@@ -361,12 +389,22 @@ module Gapic
361
389
  # their names are returned together in an array.
362
390
  # For Ruby currently we have 1:1 proto to code
363
391
  # correspondence for methods, so our generation is easier
364
- methods: methods.map { |m| [m.grpc_method_name, [m.name]] }.to_h
392
+ rpcs: methods.map { |m| [m.grpc_method_name, m.drift_manifest] }.to_h
365
393
  }
366
394
  }
367
395
  }
368
396
  end
369
397
 
398
+ ##
399
+ # How comments in the generated libraries refer to the GRPC client
400
+ # if no REST code is generated, this should just be "client",
401
+ # if REST code is generated, this should be disambiguated into the "GRPC client"
402
+ #
403
+ # @return [String]
404
+ def grpc_client_designation
405
+ generate_rest_clients? ? "GRPC client" : "client"
406
+ end
407
+
370
408
  private
371
409
 
372
410
  def default_config key
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 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/helpers/filepath_helper"
19
+ require "gapic/helpers/namespace_helper"
20
+
21
+ module Gapic
22
+ module Presenters
23
+ ##
24
+ # A presenter for proto service (REST submethods)
25
+ #
26
+ class ServiceRestPresenter
27
+ include Gapic::Helpers::FilepathHelper
28
+ include Gapic::Helpers::NamespaceHelper
29
+
30
+ ##
31
+ # @param main_service [Gapic::Presenters::ServicePresenter]
32
+ # @param api [Gapic::Schema::Api]
33
+ #
34
+ def initialize main_service, api
35
+ @main_service = main_service
36
+ @api = api
37
+ end
38
+
39
+ ##
40
+ # @return [String]
41
+ #
42
+ def service_name_full
43
+ fix_namespace api, "#{main_service.service_name_full}::Rest"
44
+ end
45
+
46
+ ##
47
+ # @return [String]
48
+ #
49
+ def client_name
50
+ main_service.client_name
51
+ end
52
+
53
+ ##
54
+ # @return [String]
55
+ #
56
+ def client_name_full
57
+ fix_namespace api, "#{service_name_full}::#{client_name}"
58
+ end
59
+
60
+ ##
61
+ # @return [String]
62
+ #
63
+ def client_require
64
+ ruby_file_path api, client_name_full
65
+ end
66
+
67
+ ##
68
+ # @return [String]
69
+ #
70
+ def client_file_path
71
+ "#{client_require}.rb"
72
+ end
73
+
74
+ def create_client_call
75
+ "#{client_name_full}.new"
76
+ end
77
+
78
+ ##
79
+ # @return [String]
80
+ #
81
+ def service_stub_name
82
+ "ServiceStub"
83
+ end
84
+
85
+ ##
86
+ # @return [String]
87
+ #
88
+ def service_stub_name_full
89
+ fix_namespace api, "#{service_name_full}::#{service_stub_name}"
90
+ end
91
+
92
+ ##
93
+ # @return [String]
94
+ #
95
+ def service_stub_require
96
+ ruby_file_path api, service_stub_name_full
97
+ end
98
+
99
+ ##
100
+ # @return [String]
101
+ #
102
+ def service_stub_file_path
103
+ "#{service_stub_require}.rb"
104
+ end
105
+
106
+ ##
107
+ # @return [String]
108
+ #
109
+ def service_rest_require
110
+ ruby_file_path api, service_name_full
111
+ end
112
+
113
+ ##
114
+ # @return [String]
115
+ #
116
+ def service_rest_file_path
117
+ "#{service_rest_require}.rb"
118
+ end
119
+
120
+ ##
121
+ # @return [String]
122
+ #
123
+ def transcoding_helper_name
124
+ "GrpcTranscoding"
125
+ end
126
+
127
+ ##
128
+ # @return [String]
129
+ #
130
+ def transcoding_helper_name_full
131
+ fix_namespace api, "#{service_name_full}::#{transcoding_helper_name}"
132
+ end
133
+
134
+ ##
135
+ # @return [String]
136
+ #
137
+ def transcoding_helper_require
138
+ ruby_file_path api, transcoding_helper_name_full
139
+ end
140
+
141
+ ##
142
+ # @return [String]
143
+ #
144
+ def transcoding_helper_file_path
145
+ "#{transcoding_helper_require}.rb"
146
+ end
147
+
148
+
149
+ private
150
+
151
+ # @return [Gapic::Presenters::ServicePresenter]
152
+ attr_reader :main_service
153
+ # @return [Gapic::Schema::Api]
154
+ attr_reader :api
155
+ end
156
+ end
157
+ end