gapic-generator 0.7.0 → 0.8.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -0
  3. data/lib/gapic/generator/version.rb +1 -1
  4. data/lib/gapic/generators/default_generator.rb +18 -5
  5. data/lib/gapic/generators/default_generator_parameters.rb +8 -4
  6. data/lib/gapic/presenters.rb +3 -0
  7. data/lib/gapic/presenters/field_presenter.rb +44 -0
  8. data/lib/gapic/presenters/gem_presenter.rb +47 -10
  9. data/lib/gapic/presenters/method_presenter.rb +36 -16
  10. data/lib/gapic/presenters/method_rest_presenter.rb +194 -0
  11. data/lib/gapic/presenters/package_presenter.rb +18 -0
  12. data/lib/gapic/presenters/service_presenter.rb +42 -4
  13. data/lib/gapic/presenters/service_rest_presenter.rb +139 -0
  14. data/lib/gapic/presenters/snippet_presenter.rb +103 -0
  15. data/lib/gapic/runner.rb +2 -1
  16. data/lib/gapic/schema/api.rb +58 -16
  17. data/lib/gapic/schema/request_param_parser.rb +46 -12
  18. data/lib/google/protobuf/any.pb.rb +1 -1
  19. data/lib/google/protobuf/compiler/plugin.pb.rb +9 -6
  20. data/lib/google/protobuf/descriptor.pb.rb +2 -2
  21. data/lib/google/protobuf/empty.pb.rb +1 -1
  22. data/templates/default/gem/readme.erb +2 -2
  23. data/templates/default/lib/_package.erb +11 -1
  24. data/templates/default/lib/_service.erb +31 -1
  25. data/templates/default/lib/rest/_rest.erb +11 -0
  26. data/templates/default/service/rest.erb +6 -0
  27. data/templates/default/service/rest/client.erb +6 -0
  28. data/templates/default/service/rest/client/_client.erb +115 -0
  29. data/templates/default/service/rest/client/_config.erb +74 -0
  30. data/templates/default/service/rest/client/_requires.erb +1 -0
  31. data/templates/default/service/rest/client/method/_def.erb +18 -0
  32. data/templates/default/service/rest/client/method/def/_options_defaults.erb +15 -0
  33. data/templates/default/service/rest/client/method/def/_rescue.erb +3 -0
  34. data/templates/default/service/rest/client/method/def/_response_normal.erb +17 -0
  35. data/templates/default/service/rest/client/method/docs/_error.erb +2 -0
  36. data/templates/default/service/rest/client/method/docs/_request.erb +27 -0
  37. data/templates/default/service/rest/client/method/docs/_result.erb +6 -0
  38. data/templates/default/service/rest/grpc_transcoding.erb +6 -0
  39. data/templates/default/service/rest/grpc_transcoding/_grpc_transcoding.erb +9 -0
  40. data/templates/default/service/rest/grpc_transcoding/method/_def.erb +21 -0
  41. data/templates/default/service/rest/grpc_transcoding/method/def/_query_string_param.erb +8 -0
  42. data/templates/default/service/rest/test/client.erb +18 -0
  43. data/templates/default/service/rest/test/method/_assert_response.erb +2 -0
  44. data/templates/default/service/rest/test/method/_configure.erb +19 -0
  45. data/templates/default/service/rest/test/method/_normal.erb +71 -0
  46. data/templates/default/service/rest/test/method/_setup.erb +38 -0
  47. data/templates/default/snippets/gemfile.erb +17 -0
  48. data/templates/default/snippets/snippet/_structure.erb +71 -0
  49. data/templates/default/snippets/standalone.erb +6 -0
  50. metadata +31 -3
@@ -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 }
@@ -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
@@ -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
@@ -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
@@ -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,139 @@
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
+ ##
75
+ # @return [String]
76
+ #
77
+ def create_client_call
78
+ "#{client_name_full}.new"
79
+ end
80
+
81
+ ##
82
+ # @return [String]
83
+ #
84
+ def service_rest_require
85
+ ruby_file_path api, service_name_full
86
+ end
87
+
88
+ ##
89
+ # @return [String]
90
+ #
91
+ def service_rest_file_path
92
+ "#{service_rest_require}.rb"
93
+ end
94
+
95
+ ##
96
+ # @return [String]
97
+ #
98
+ def transcoding_helper_name
99
+ "GrpcTranscoding"
100
+ end
101
+
102
+ ##
103
+ # @return [String]
104
+ #
105
+ def transcoding_helper_name_full
106
+ fix_namespace api, "#{service_name_full}::#{transcoding_helper_name}"
107
+ end
108
+
109
+ ##
110
+ # @return [String]
111
+ #
112
+ def transcoding_helper_require
113
+ ruby_file_path api, transcoding_helper_name_full
114
+ end
115
+
116
+ ##
117
+ # @return [String]
118
+ #
119
+ def transcoding_helper_file_path
120
+ "#{transcoding_helper_require}.rb"
121
+ end
122
+
123
+ ##
124
+ # @return [String]
125
+ #
126
+ def test_client_file_path
127
+ main_service.service_file_path.sub ".rb", "_test.rb"
128
+ end
129
+
130
+
131
+ private
132
+
133
+ # @return [Gapic::Presenters::ServicePresenter]
134
+ attr_reader :main_service
135
+ # @return [Gapic::Schema::Api]
136
+ attr_reader :api
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,103 @@
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
+
19
+ module Gapic
20
+ module Presenters
21
+ ##
22
+ # A presenter for snippets.
23
+ #
24
+ class SnippetPresenter
25
+ def initialize method_presenter, api
26
+ @method_presenter = method_presenter
27
+ @api = api
28
+ end
29
+
30
+ def client_streaming?
31
+ @method_presenter.client_streaming?
32
+ end
33
+
34
+ def bidi_streaming?
35
+ @method_presenter.client_streaming? && @method_presenter.server_streaming?
36
+ end
37
+
38
+ def response_kind
39
+ if @method_presenter.server_streaming?
40
+ :streaming
41
+ elsif @method_presenter.paged?
42
+ :paged
43
+ elsif @method_presenter.lro?
44
+ :lro
45
+ else
46
+ :simple
47
+ end
48
+ end
49
+
50
+ def snippet_file_path
51
+ "#{@method_presenter.service.service_require.split('/').last}/#{@method_presenter.name}.rb"
52
+ end
53
+
54
+ def require_path
55
+ @method_presenter.service.service_require
56
+ end
57
+
58
+ def client_type
59
+ @method_presenter.service.client_name_full.sub(/^::/, "")
60
+ end
61
+
62
+ def request_type
63
+ @method_presenter.request_type.sub(/^::/, "")
64
+ end
65
+
66
+ def return_type
67
+ base_type = @method_presenter.return_type.sub(/^::/, "")
68
+ @method_presenter.server_streaming? ? "Enumerable<#{base_type}>" : base_type
69
+ end
70
+
71
+ def paged_response_type
72
+ @method_presenter.paged_response_type
73
+ end
74
+
75
+ def base_response_type
76
+ @method_presenter.return_type
77
+ end
78
+
79
+ # TODO: Determine type of LRO response
80
+
81
+ def method_name
82
+ @method_presenter.name
83
+ end
84
+
85
+ def region_tag
86
+ gem_presenter = @method_presenter.service.gem
87
+ api_id = gem_presenter.api_shortname || gem_presenter.api_id&.split(".")&.first
88
+ names = gem_presenter.name.split "-"
89
+ final_name = names.pop
90
+ if final_name =~ /^v\d/
91
+ api_version = final_name
92
+ api_id ||= names.last
93
+ else
94
+ api_id ||= final_name
95
+ api_version = "v0"
96
+ end
97
+ service_name = @method_presenter.service.module_name
98
+ method_name = @method_presenter.method.name
99
+ "#{api_id}_#{api_version}_generated_#{service_name}_#{method_name}_sync"
100
+ end
101
+ end
102
+ end
103
+ end
data/lib/gapic/runner.rb CHANGED
@@ -65,7 +65,8 @@ module Gapic
65
65
 
66
66
  # Create and write the response
67
67
  response = Google::Protobuf::Compiler::CodeGeneratorResponse.new file: output_files
68
- response.supported_features = Google::Protobuf::Compiler::CodeGeneratorResponse::FEATURE_PROTO3_OPTIONAL
68
+ feature_set = Google::Protobuf::Compiler::CodeGeneratorResponse::Feature::FEATURE_PROTO3_OPTIONAL.to_i
69
+ response.supported_features = feature_set
69
70
  response
70
71
  end
71
72
 
@@ -89,6 +89,10 @@ module Gapic
89
89
  matching_files.first
90
90
  end
91
91
 
92
+ def overrides_of key
93
+ configuration&.fetch(:overrides, nil)&.fetch(key, nil) || {}
94
+ end
95
+
92
96
  def fix_file_path str
93
97
  str = String str
94
98
  return str if configuration[:overrides].nil?
@@ -144,11 +148,9 @@ module Gapic
144
148
  # @return [Array<Hash>]
145
149
  # An array of the sample file hashes.
146
150
  def samples
147
- @samples ||= begin
148
- protoc_options["samples"].to_s.split(";").flat_map do |sample_path|
149
- YAML.load_file sample_path
150
- end.compact
151
- end
151
+ @samples ||= protoc_options["samples"].to_s.split(";").flat_map do |sample_path|
152
+ YAML.load_file sample_path
153
+ end.compact
152
154
  end
153
155
 
154
156
  # Structured representation of the standalone samples configuration files.
@@ -174,10 +176,10 @@ module Gapic
174
176
  # An array of the standalone sample configuration hashes.
175
177
  def standalone_test_samples
176
178
  @standalone_test_samples ||= begin
177
- samples.select { |sample| sample["type"] == "test/samples" }
178
- .select { |sample| sample["schema_version"] == "1" || sample["schema_version"] == 1 }
179
- .map { |sample| sample["samples"] }
180
- .flatten.compact
179
+ test_samples = samples.select { |sample| sample["type"] == "test/samples" }
180
+ test_samples.select { |sample| sample["schema_version"] == "1" || sample["schema_version"] == 1 }
181
+ .map { |sample| sample["samples"] }
182
+ .flatten.compact
181
183
  end
182
184
  end
183
185
 
@@ -231,6 +233,29 @@ module Gapic
231
233
  configuration[:generate_path_helpers_output] ||= false
232
234
  end
233
235
 
236
+ # Whether to generate REST clients
237
+ def generate_rest_clients?
238
+ return false if configuration[:transports].nil?
239
+ configuration[:transports].include? "rest"
240
+ end
241
+
242
+ # Whether to generate GRPC clients
243
+ def generate_grpc_clients?
244
+ return true if configuration[:transports].nil?
245
+ configuration[:transports].include? "grpc"
246
+ end
247
+
248
+ # Whether to generate standalone snippets
249
+ def generate_standalone_snippets?
250
+ configuration[:generate_standalone_snippets] ||= false
251
+ end
252
+
253
+ # Whether to generate gapic metadata (drift manifest) file
254
+ # @return [Boolean]
255
+ def generate_metadata
256
+ configuration[:generate_metadata] ||= false
257
+ end
258
+
234
259
  # Whether the override_proto_namespaces parameter was given in the configuration
235
260
  def override_proto_namespaces_defined?
236
261
  configuration.key? :override_proto_namespaces
@@ -260,9 +285,7 @@ module Gapic
260
285
 
261
286
  # Parsed grpc service config
262
287
  def grpc_service_config
263
- @grpc_service_config ||= begin
264
- Gapic::GrpcServiceConfig::Parser.parse grpc_service_config_raw
265
- end
288
+ @grpc_service_config ||= Gapic::GrpcServiceConfig::Parser.parse grpc_service_config_raw
266
289
  end
267
290
 
268
291
  # Get a resource given its type string
@@ -272,10 +295,8 @@ module Gapic
272
295
 
273
296
  # Given a service, find all common services that use it as a delegate.
274
297
  def common_services_for delegate
275
- @delegate_to_common ||= begin
276
- (configuration[:common_services] || {}).each_with_object({}) do |(c, d), mapping|
277
- (mapping[d] ||= []) << c
278
- end
298
+ @delegate_to_common ||= (configuration[:common_services] || {}).each_with_object({}) do |(c, d), mapping|
299
+ (mapping[d] ||= []) << c
279
300
  end
280
301
  all_services = services
281
302
  @delegate_to_common.fetch(delegate.address.join("."), []).map do |addr|
@@ -292,6 +313,27 @@ module Gapic
292
313
  services.find { |s| s.address == addr }
293
314
  end
294
315
 
316
+ ##
317
+ # Whether configuration has an override for the wrapper gem name
318
+ # @return [Boolean]
319
+ def wrapper_gem_name_override?
320
+ configuration.key?(:overrides) &&
321
+ configuration[:overrides].key?(:wrapper_gem_name)
322
+ end
323
+
324
+ ##
325
+ # An override for the wrapper gem name in the configuration
326
+ # @return [String, Nil]
327
+ def wrapper_gem_name_override
328
+ return nil unless wrapper_gem_name_override?
329
+ return nil if configuration[:overrides][:wrapper_gem_name].nil?
330
+
331
+ wrapper_name_config = configuration[:overrides][:wrapper_gem_name].strip
332
+ return nil if wrapper_name_config.empty?
333
+
334
+ wrapper_name_config
335
+ end
336
+
295
337
  private
296
338
 
297
339
  # Perform a variety of sanity checks on the data, and prints errors to