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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f7df8b22a84359c27f6074aee1ac25ebdddf7838b8e420a908f9381df4c3217
4
- data.tar.gz: dc71fcaf60829fed44ceca3bc9d878a2d6d0787a2e01be0dfbc42d9693ebe6d1
3
+ metadata.gz: 5c8a401f416529802324b86833c5c3a9fcef01afd699439053ce868a7862c5c8
4
+ data.tar.gz: 6f794cc05eb33a4c201bdcc62dc62524406ae2fb003f0b2d9c536482517a4109
5
5
  SHA512:
6
- metadata.gz: cf3382a6c2303247e82b69030eead4bd8f97101b95d34ce00b043d4036ad95eafcd0688e5e79fcea93264d294f530f4453dc5138c73ed76aa1a1e01d273fb666
7
- data.tar.gz: 361aa578ba1afdc3fe27d7b617c36926b77458b48a080d03d0f568c9d2a60cb2410a6aa2870acb874a2c963ebed26f8c9e811ba2006473175cf83e02e6ee1ad7
6
+ metadata.gz: 536731d9a866b0c58540b6eb6f62469eef75f10f82a9fba3c45e0e5a2c5d08b7f5b97b0b385b3e6063e418e0faba687faf45c44cc700ab69da554c9d28a46049
7
+ data.tar.gz: c1b99ad4ebfae8c4085522924ba4fd11f1a2628b67d64dfc549f22df40aadf5d79ae127bcac73ca5fe2795937f29556b6f656d5b86c66aaef43c78ec644b6772
data/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # Release History for gapic-generator
2
2
 
3
+ ### 0.8.0 / 2021-06-16
4
+
5
+ * Initial implementation of standalone snippet generation.
6
+ * Updated gapic-common dependencies to require at least 0.5 and to support future 1.x versions.
7
+ * Generated unit tests for REST clients.
8
+ * Generated proper x-goog-api-client headers for REST clients.
9
+ * Added generation arguments to generated repo metadata.
10
+ * Allow multiple versions in the extra-dependency command line argument.
11
+ * Fixed treatment of boolean-valued command line arguments to the generator.
12
+ * Fixed behavior of wrapper-gem-override if given an empty value.
13
+ * Fixed default env_prefix computation to avoid the version part of the proto namespace.
14
+ * Fixed Bazel front-end to preserve file permissions.
15
+
16
+ ### 0.7.5 / 2021-05-18
17
+
18
+ * Bazel jobs now provide a prebuilt ruby binary.
19
+ * Fixed generated indentation for a few cases, by updating to Rubocop 1.15.
20
+ * Added library_type to generated repo metadata files.
21
+
22
+ ### 0.7.4 / 2021-05-07
23
+
24
+ * Fixed the broken link in the generated libraries' README.md
25
+ * Generated libraries with REST transport now use presense testing instead of rejecting defaults to determine which fields to transcode into the query string parameters
26
+
27
+ ### 0.7.3 / 2021-03-24
28
+
29
+ * Fixed gapic metadata (drift manifest) generation
30
+ * Gapic metadata generation is disabled by default in gapic-generator
31
+ (enabled by default in gapic-generator-cloud)
32
+ * Can now generate libraries with REST transport in addition to GRPC
33
+ * gapic-common 0.4 is the default version for the generated libraries now (was 0.3)
34
+ (required for the generated libraries with the REST transport)
35
+
36
+ ### 0.7.2 / 2021-03-05
37
+
38
+ * No changes.
39
+
40
+ ### 0.7.1 / 2021-02-27
41
+
42
+ * Update generated readmes to reflect that Ruby 2.5 or later is now required.
43
+
3
44
  ### 0.7.0 / 2021-02-27
4
45
 
5
46
  * Update minimum Ruby version to 2.5 for generated libraries.
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Gapic
18
18
  module Generator
19
- VERSION = "0.7.0"
19
+ VERSION = "0.8.0"
20
20
  end
21
21
  end
@@ -54,13 +54,24 @@ module Gapic
54
54
  package.services.each do |service|
55
55
  # Service level files
56
56
  files << g("service.erb", "lib/#{service.service_file_path}", service: service)
57
- files << g("service/client.erb", "lib/#{service.client_file_path}", service: service)
57
+ files << g("service/rest.erb", "lib/#{service.rest.service_rest_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
58
+ files << g("service/client.erb", "lib/#{service.client_file_path}", service: service) unless @api.generate_rest_clients?
58
59
  files << g("service/credentials.erb", "lib/#{service.credentials_file_path}", service: service) unless gem.generic_endpoint?
59
60
  files << g("service/paths.erb", "lib/#{service.paths_file_path}", service: service) if service.paths?
60
- files << g("service/operations.erb", "lib/#{service.operations_file_path}", service: service) if service.lro?
61
- files << g("service/test/client.erb", "test/#{service.test_client_file_path}", service: service)
61
+ files << g("service/operations.erb", "lib/#{service.operations_file_path}", service: service) if service.lro? && !@api.generate_rest_clients?
62
+ files << g("service/rest/client.erb", "lib/#{service.rest.client_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
63
+ files << g("service/rest/grpc_transcoding.erb", "lib/#{service.rest.transcoding_helper_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
64
+ files << g("service/rest/test/client.erb", "test/#{service.rest.test_client_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
65
+ files << g("service/test/client.erb", "test/#{service.test_client_file_path}", service: service) unless @api.generate_rest_clients?
62
66
  files << g("service/test/client_paths.erb", "test/#{service.test_paths_file_path}", service: service) if service.paths?
63
- files << g("service/test/client_operations.erb", "test/#{service.test_client_operations_file_path}", service: service) if service.lro?
67
+ files << g("service/test/client_operations.erb", "test/#{service.test_client_operations_file_path}", service: service) if service.lro? && !@api.generate_rest_clients?
68
+
69
+ if @api.generate_standalone_snippets?
70
+ service.methods.each do |method|
71
+ snippet = method.snippet
72
+ files << g("snippets/standalone.erb", "snippets/#{snippet.snippet_file_path}", snippet: snippet)
73
+ end
74
+ end
64
75
  end
65
76
  end
66
77
 
@@ -77,7 +88,9 @@ module Gapic
77
88
  files << g("gem/yardopts.erb", ".yardopts", gem: gem)
78
89
  files << g("gem/license.erb", "LICENSE.md", gem: gem)
79
90
  files << g("gem/entrypoint.erb", "lib/#{gem.name}.rb", gem: gem)
80
- files << g("gem/gapic_metadata_json.erb", "gapic_metadata.json", gem: gem)
91
+ files << g("gem/gapic_metadata_json.erb", "gapic_metadata.json", gem: gem) if @api.generate_metadata
92
+
93
+ files << g("snippets/gemfile.erb", "snippets/Gemfile", gem: gem) if @api.generate_standalone_snippets?
81
94
 
82
95
  gem.proto_files.each do |proto_file|
83
96
  files << g("proto_docs/proto_file.erb", "proto_docs/#{proto_file.docs_file_path}", file: proto_file)
@@ -23,7 +23,8 @@ module Gapic
23
23
  BOOL_PARAMETERS = [
24
24
  ":gem.:free_tier",
25
25
  ":gem.:yard_strict",
26
- ":gem.:generic_endpoint"
26
+ ":gem.:generic_endpoint",
27
+ ":generate_metadata"
27
28
  ].freeze
28
29
 
29
30
  STRING_PARAMETERS = [
@@ -42,11 +43,13 @@ module Gapic
42
43
  ":gem.:api_shortname",
43
44
  ":gem.:factory_method_suffix",
44
45
  ":defaults.:service.:default_host",
45
- "grpc_service_config"
46
+ "grpc_service_config",
47
+ ":overrides.:wrapper_gem_name"
46
48
  ].freeze
47
49
 
48
50
  ARRAY_PARAMETERS = [
49
- ":defaults.:service.:oauth_scopes"
51
+ ":defaults.:service.:oauth_scopes",
52
+ ":transports"
50
53
  ].freeze
51
54
 
52
55
  MAP_PARAMETERS = [
@@ -83,7 +86,8 @@ module Gapic
83
86
  }.freeze
84
87
 
85
88
  ARRAY_PARAMETERS_ALIASES = {
86
- "default-oauth-scopes" => ":defaults.:service.:oauth_scopes"
89
+ "default-oauth-scopes" => ":defaults.:service.:oauth_scopes",
90
+ "transports" => ":transports"
87
91
  }.freeze
88
92
 
89
93
  MAP_PARAMETERS_ALIASES = {
@@ -21,10 +21,13 @@ require "gapic/presenters/file_presenter"
21
21
  require "gapic/presenters/gem_presenter"
22
22
  require "gapic/presenters/message_presenter"
23
23
  require "gapic/presenters/method_presenter"
24
+ require "gapic/presenters/method_rest_presenter"
24
25
  require "gapic/presenters/package_presenter"
25
26
  require "gapic/presenters/resource_presenter"
26
27
  require "gapic/presenters/sample_presenter"
27
28
  require "gapic/presenters/service_presenter"
29
+ require "gapic/presenters/service_rest_presenter"
30
+ require "gapic/presenters/snippet_presenter"
28
31
 
29
32
  module Gapic
30
33
  ##
@@ -88,6 +88,10 @@ module Gapic
88
88
  @field.repeated?
89
89
  end
90
90
 
91
+ def required?
92
+ @field.required?
93
+ end
94
+
91
95
  def map?
92
96
  @field.map?
93
97
  end
@@ -100,6 +104,34 @@ module Gapic
100
104
  @message.oneof_decl[@field.oneof_index].name
101
105
  end
102
106
 
107
+ ##
108
+ # Returns a stringified default value for the protobuf types
109
+ # that are possible to fit into the query string parameter
110
+ # and nil for the other types (e.g. Messages)
111
+ #
112
+ # @return [String, nil]
113
+ #
114
+ def default_value_for_type
115
+ if @field.message?
116
+ nil
117
+ elsif @field.enum?
118
+ ":#{@field.enum.values.first.name}"
119
+ else
120
+ case @field.type
121
+ when 1, 2, 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "0" # floating point or integer
122
+ when 9, 12 then "\"\""
123
+ when 8 then "false"
124
+ end
125
+ end
126
+ end
127
+
128
+ ##
129
+ # Name of this field, camel-cased
130
+ # @return [String]
131
+ def camel_name
132
+ camel_name_for name
133
+ end
134
+
103
135
  protected
104
136
 
105
137
  def field_doc_types field, output
@@ -161,6 +193,18 @@ module Gapic
161
193
  def message_ruby_type message
162
194
  ruby_namespace @api, message.address.join(".")
163
195
  end
196
+
197
+ ##
198
+ # Converts a snake_case parameter name into camelCase for query string parameters
199
+ # @param attr_name [String]
200
+ # @return [String] camel-cased parameter name
201
+ def camel_name_for attr_name
202
+ parts = attr_name.split "_"
203
+ first_part = parts[0]
204
+ other_parts = parts[1..-1]
205
+ other_parts_pascal = other_parts.map(&:capitalize).join
206
+ "#{first_part}#{other_parts_pascal}"
207
+ end
164
208
  end
165
209
  end
166
210
  end
@@ -32,6 +32,9 @@ module Gapic
32
32
  @api = api
33
33
  end
34
34
 
35
+ ##
36
+ # @return [Enumerable<Gapic::Presenters::PackagePresenter>]
37
+ #
35
38
  def packages
36
39
  @packages ||= begin
37
40
  packages = @api.generate_files.map(&:package).uniq.sort
@@ -124,7 +127,11 @@ module Gapic
124
127
  end
125
128
 
126
129
  def env_prefix
127
- (gem_config(:env_prefix) || name.split("-").last).upcase
130
+ prefix = gem_config(:env_prefix) || begin
131
+ segs = name.split("-").reverse
132
+ segs.find { |seg| seg !~ /^v\d/ } || segs.first || "UNKNOWN"
133
+ end
134
+ prefix.upcase
128
135
  end
129
136
 
130
137
  def iam_dependency?
@@ -153,18 +160,26 @@ module Gapic
153
160
  gem_config :issue_tracker_url
154
161
  end
155
162
 
163
+ ##
164
+ # @return [Boolean]
165
+ #
156
166
  def free_tier?
157
- # Default to false unless the config is explicitly set to "true"
158
- gem_config(:free_tier) == "true"
167
+ gem_config(:free_tier) || false
159
168
  end
160
169
 
170
+ ##
171
+ # @return [Boolean]
172
+ #
161
173
  def yard_strict?
162
174
  # Default to true unless the config is explicitly set to "false"
163
- gem_config(:yard_strict) != "false"
175
+ gem_config(:yard_strict).nil? || gem_config(:yard_strict)
164
176
  end
165
177
 
178
+ ##
179
+ # @return [Boolean]
180
+ #
166
181
  def generic_endpoint?
167
- gem_config(:generic_endpoint) == "true"
182
+ gem_config(:generic_endpoint) || false
168
183
  end
169
184
 
170
185
  def entrypoint_require
@@ -180,11 +195,13 @@ module Gapic
180
195
  end
181
196
 
182
197
  def dependencies
183
- deps = { "gapic-common" => "~> 0.3" }
184
- deps["grpc-google-iam-v1"] = [">= 0.6.10", "< 2.0"] if iam_dependency?
185
- extra_deps = gem_config :extra_dependencies
186
- deps.merge! extra_deps if extra_deps
187
- deps
198
+ @dependencies ||= begin
199
+ deps = { "gapic-common" => [">= 0.5", "< 2.a"] }
200
+ deps["grpc-google-iam-v1"] = [">= 0.6.10", "< 2.a"] if iam_dependency?
201
+ extra_deps = gem_config_dependencies
202
+ deps.merge! extra_deps if extra_deps
203
+ deps
204
+ end
188
205
  end
189
206
 
190
207
  def dependency_list
@@ -222,6 +239,26 @@ module Gapic
222
239
  @api.configuration[:gem][key]
223
240
  end
224
241
 
242
+ ##
243
+ # There is a special case (from PoV of generator parameters)
244
+ # in gem dependencies where a dependency needs to be an array of strings
245
+ # e.g. ">= 1.6", "< 2.a"
246
+ # Rather than creating a special generator param case for this I will special-case it here.
247
+ # '|' is the separator.
248
+ # The above would be represented as ">= 1.6|< 2.a"
249
+ #
250
+ # @return [Hash<String, String>, Hash{String=>Array<String>}, nil]
251
+ def gem_config_dependencies
252
+ return unless gem_config :extra_dependencies
253
+ gem_config(:extra_dependencies).map do |dep_name, dep_versions|
254
+ if dep_versions.include? "|"
255
+ [dep_name, dep_versions.split("|")]
256
+ else
257
+ [dep_name, dep_versions]
258
+ end
259
+ end.to_h
260
+ end
261
+
225
262
  def blacklist_protos
226
263
  blacklist = gem_config :blacklist
227
264
 
@@ -15,7 +15,6 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require "active_support/inflector"
18
- require "gapic/uri_template"
19
18
  require "gapic/ruby_info"
20
19
  require "gapic/helpers/namespace_helper"
21
20
 
@@ -27,16 +26,34 @@ module Gapic
27
26
  class MethodPresenter
28
27
  include Gapic::Helpers::NamespaceHelper
29
28
 
29
+ # @return [Gapic::Schema::Method]
30
+ attr_accessor :method
31
+
32
+ # @return [Gapic::Presenters::MethodRestPresenter]
33
+ attr_accessor :rest
34
+
35
+ ##
36
+ # @param service_presenter [Gapic::Presenters::ServicePresenter]
37
+ # @param api [Gapic::Schema::Api]
38
+ # @param method [Gapic::Schema::Method]
30
39
  def initialize service_presenter, api, method
31
40
  @service_presenter = service_presenter
32
41
  @api = api
33
42
  @method = method
43
+ @rest = MethodRestPresenter.new self
34
44
  end
35
45
 
46
+ ##
47
+ # @return [Gapic::Presenters::ServicePresenter]
48
+ #
36
49
  def service
37
50
  @service_presenter
38
51
  end
39
52
 
53
+ def snippet
54
+ SnippetPresenter.new self, @api
55
+ end
56
+
40
57
  def name
41
58
  @name ||= begin
42
59
  candidate = ActiveSupport::Inflector.underscore @method.name
@@ -195,15 +212,17 @@ module Gapic
195
212
  end
196
213
 
197
214
  ##
198
- #
199
215
  # @return [Array<String>] The segment key names.
200
216
  #
201
217
  def routing_params
202
- Gapic::UriTemplate.parse_arguments method_path
218
+ rest.routing_params
203
219
  end
204
220
 
221
+ ##
222
+ # @return [Boolean] Whether any routing params are present
223
+ #
205
224
  def routing_params?
206
- routing_params.any?
225
+ rest.routing_params?
207
226
  end
208
227
 
209
228
  def grpc_service_config
@@ -217,6 +236,19 @@ module Gapic
217
236
  @method.name
218
237
  end
219
238
 
239
+ ##
240
+ # Returns a hash with a drift_manifest of this rpc method
241
+ # describing correspondence between the proto description
242
+ # of the rpc with the generated code for the method.
243
+ # For ruby currently [03/2021] only one method is generated per RPC,
244
+ # so the correspondence is very basic.
245
+ # See https://github.com/googleapis/googleapis/blob/master/gapic/metadata/gapic_metadata.proto
246
+ #
247
+ # @return [Hash]
248
+ def drift_manifest
249
+ { methods: [name] }
250
+ end
251
+
220
252
  protected
221
253
 
222
254
  def message_ruby_type message
@@ -266,18 +298,6 @@ module Gapic
266
298
  end
267
299
  end
268
300
 
269
- def method_path
270
- return "" if @method.http.nil?
271
-
272
- method = [
273
- @method.http.get, @method.http.post, @method.http.put,
274
- @method.http.patch, @method.http.delete
275
- ].find { |x| !x.empty? }
276
- return method unless method.nil?
277
-
278
- return @method.http.custom.path unless @method.http.custom.nil?
279
- end
280
-
281
301
  def paged_request? request
282
302
  page_token = request.fields.find do |f|
283
303
  f.name == "page_token" && f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
@@ -0,0 +1,194 @@
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
+ # @return [Boolean] True if body contains full request object (`*` in the annotation), false otherwise
133
+ #
134
+ def body_is_request_object?
135
+ body == "*"
136
+ end
137
+
138
+ ##
139
+ # Performs a limited version of grpc transcoding to create a string that will interpolate
140
+ # the values from the request object to create a request body at runtime.
141
+ # Currently only supports either "*" for "the whole request object" or
142
+ # "value" for "request_object.value"
143
+ #
144
+ # @param [String] request_obj_name the name of the request object for the interpolation
145
+ # defaults to "request_pb"
146
+ #
147
+ # @return [String] A string to interpolate values from the request object into body
148
+ #
149
+ def body_interpolated request_obj_name = "request_pb"
150
+ return "\"\"" unless body?
151
+
152
+ return "#{request_obj_name}.to_json" if body_is_request_object?
153
+
154
+ "#{request_obj_name}.#{body}.to_json"
155
+ end
156
+
157
+ ##
158
+ # @return [Boolean] whether any query string parameters are present
159
+ #
160
+ def query_string_params?
161
+ query_string_params.any?
162
+ end
163
+
164
+ # @return [Array<String>]
165
+ def query_string_params
166
+ return [] if body_is_request_object?
167
+
168
+ routing_params_set = routing_params.to_set
169
+ @main_method.arguments
170
+ .reject { |arg| routing_params_set.include? arg.name }
171
+ .reject { |arg| body == arg.name }
172
+ .reject(&:message?)
173
+ .reject { |arg| arg.default_value_for_type.nil? }
174
+ end
175
+
176
+ ##
177
+ # Name of the variable to use for storing the query_string_params result of the transcoding call
178
+ # Normally "query_string_params" but use "_query_string_params" for discarding the result for
179
+ # the calls that do not sent query_string_params
180
+ # @return [String]
181
+ def query_string_params_var_name
182
+ query_string_params? ? "query_string_params" : "_query_string_params"
183
+ end
184
+
185
+ ##
186
+ # Name for the GRPC transcoding helper method
187
+ #
188
+ # @return [String]
189
+ def transcoding_helper_name
190
+ "transcode_#{@main_method.name}"
191
+ end
192
+ end
193
+ end
194
+ end