gapic-generator 0.6.14 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
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