gapic-generator 0.10.1 → 0.45.1

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 (257) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +333 -0
  3. data/CONTRIBUTING.md +1 -1
  4. data/README.md +71 -37
  5. data/bin/protoc-gen-ruby_gapic +2 -2
  6. data/lib/gapic/file_formatter.rb +23 -19
  7. data/lib/gapic/formatting_utils.rb +22 -9
  8. data/lib/gapic/gem_builder.rb +15 -17
  9. data/lib/gapic/generator/version.rb +1 -1
  10. data/lib/gapic/generators/base_generator.rb +6 -4
  11. data/lib/gapic/generators/default_generator.rb +70 -32
  12. data/lib/gapic/generators/default_generator_parameters.rb +11 -3
  13. data/lib/gapic/grpc_service_config/{service_config.rb → config.rb} +2 -2
  14. data/lib/gapic/grpc_service_config/parser.rb +10 -10
  15. data/lib/gapic/model/api_metadata.rb +173 -0
  16. data/lib/gapic/model/method/http_annotation.rb +221 -0
  17. data/lib/gapic/model/method/lro.rb +163 -0
  18. data/lib/gapic/model/method/routing.rb +248 -0
  19. data/lib/gapic/model/mixins.rb +247 -0
  20. data/lib/gapic/model/model_error.rb +26 -0
  21. data/lib/gapic/model/service/nonstandard_lro_provider.rb +292 -0
  22. data/lib/gapic/model.rb +22 -0
  23. data/lib/gapic/package_snippets.rb +159 -0
  24. data/lib/gapic/path_pattern/parser.rb +11 -2
  25. data/lib/gapic/path_pattern/pattern.rb +64 -1
  26. data/lib/gapic/path_pattern/segment.rb +108 -13
  27. data/lib/gapic/presenters/enum_presenter.rb +14 -0
  28. data/lib/gapic/presenters/enum_value_presenter.rb +4 -1
  29. data/lib/gapic/presenters/field_presenter.rb +78 -21
  30. data/lib/gapic/presenters/gem_presenter.rb +140 -34
  31. data/lib/gapic/presenters/{service_config_presenter.rb → grpc_service_config_presenter.rb} +1 -1
  32. data/lib/gapic/presenters/message_presenter.rb +15 -0
  33. data/lib/gapic/presenters/method/http_binding_presenter.rb +128 -0
  34. data/lib/gapic/presenters/method/rest_pagination_info.rb +25 -16
  35. data/lib/gapic/presenters/method_presenter.rb +149 -35
  36. data/lib/gapic/presenters/method_rest_presenter.rb +79 -168
  37. data/lib/gapic/presenters/package_presenter.rb +63 -18
  38. data/lib/gapic/presenters/resource_presenter.rb +9 -3
  39. data/lib/gapic/presenters/service/lro_client_presenter.rb +90 -0
  40. data/lib/gapic/presenters/service/mixin_client_presenter.rb +89 -0
  41. data/lib/gapic/presenters/service/sub_client_presenter.rb +84 -0
  42. data/lib/gapic/presenters/service_presenter.rb +361 -27
  43. data/lib/gapic/presenters/service_rest_presenter.rb +247 -13
  44. data/lib/gapic/presenters/snippet/client_call_presenter.rb +82 -0
  45. data/lib/gapic/presenters/snippet/client_initialization_presenter.rb +87 -0
  46. data/lib/gapic/presenters/snippet/declaration_presenter.rb +91 -0
  47. data/lib/gapic/presenters/snippet/expression_presenter.rb +135 -0
  48. data/lib/gapic/presenters/snippet/iteration_presenter.rb +118 -0
  49. data/lib/gapic/presenters/snippet/parameter_presenter.rb +67 -0
  50. data/lib/gapic/presenters/snippet/request_initialization_presenters.rb +202 -0
  51. data/lib/gapic/presenters/snippet/response_handling_presenters.rb +329 -0
  52. data/lib/gapic/presenters/snippet/statement_presenter.rb +134 -0
  53. data/lib/gapic/presenters/snippet/type_presenter.rb +98 -0
  54. data/lib/gapic/presenters/snippet_presenter.rb +199 -9
  55. data/lib/gapic/presenters.rb +5 -1
  56. data/lib/gapic/runner.rb +1 -1
  57. data/lib/gapic/schema/api.rb +105 -5
  58. data/lib/gapic/schema/loader.rb +69 -21
  59. data/lib/gapic/schema/parameter_schema.rb +8 -8
  60. data/lib/gapic/schema/proto_tools.rb +193 -0
  61. data/lib/gapic/schema/request_param_parser.rb +5 -7
  62. data/lib/gapic/schema/service_config_parser.rb +152 -0
  63. data/lib/gapic/schema/wrappers.rb +309 -25
  64. data/lib/gapic/uri_template/parser.rb +15 -7
  65. data/lib/google/cloud/tools/snippetgen/configlanguage/v1/snippet_config_language_pb.rb +104 -0
  66. data/lib/google/cloud/tools/snippetgen/snippetindex/v1/snippet_index_pb.rb +58 -0
  67. data/lib/google/protobuf/compiler/plugin_pb.rb +47 -0
  68. data/templates/default/binding_override.text.erb +6 -0
  69. data/templates/default/gem/gemfile.text.erb +12 -0
  70. data/templates/default/gem/{gemspec.erb → gemspec.text.erb} +3 -11
  71. data/templates/default/gem/{readme.erb → readme.text.erb} +10 -6
  72. data/templates/default/gem/{rubocop.erb → rubocop.text.erb} +3 -0
  73. data/templates/default/gem/{test_helper.erb → test_helper.text.erb} +4 -2
  74. data/templates/default/gem/toys.text.erb +12 -0
  75. data/templates/default/gem/{yardopts.erb → yardopts.text.erb} +1 -1
  76. data/templates/default/helpers/default_helper.rb +33 -1
  77. data/templates/default/lib/_binding_override.text.erb +49 -0
  78. data/templates/default/lib/{_package.erb → _package.text.erb} +7 -6
  79. data/templates/default/lib/_package_rest.text.erb +24 -0
  80. data/templates/default/lib/{_service.erb → _service.text.erb} +14 -20
  81. data/templates/default/lib/package/_self_configure.text.erb +16 -0
  82. data/templates/default/lib/package/_self_configure_defaults.text.erb +13 -0
  83. data/templates/default/lib/package/self_configure/_binding_default.text.erb +15 -0
  84. data/templates/default/lib/rest/_rest.text.erb +46 -0
  85. data/templates/default/package_rest.text.erb +6 -0
  86. data/templates/default/proto_docs/_deprecated.text.erb +9 -0
  87. data/templates/default/proto_docs/{_enum.erb → _enum.text.erb} +1 -0
  88. data/templates/default/proto_docs/{_message.erb → _message.text.erb} +2 -0
  89. data/templates/default/service/client/{_client.erb → _client.text.erb} +77 -17
  90. data/templates/default/service/client/{_config.erb → _config.text.erb} +39 -8
  91. data/templates/default/service/client/_nonstandard_lro.text.erb +57 -0
  92. data/templates/default/service/client/{_operations.erb → _operations.text.erb} +24 -3
  93. data/templates/default/service/client/{_self_configure_defaults.erb → _self_configure_defaults.text.erb} +2 -2
  94. data/templates/default/service/client/method/{_def.erb → _def.text.erb} +2 -2
  95. data/templates/default/service/client/method/def/{_options_defaults.erb → _options_defaults.text.erb} +3 -9
  96. data/templates/default/service/client/method/def/_request_normal.text.erb +18 -0
  97. data/templates/default/service/client/method/def/_request_streaming.text.erb +23 -0
  98. data/templates/default/service/client/method/def/_response.text.erb +10 -0
  99. data/templates/default/service/client/method/def/_response_nonstandard_lro.text.erb +23 -0
  100. data/templates/default/service/client/method/def/_response_normal.text.erb +4 -0
  101. data/templates/default/service/client/method/def/{_response_normal.erb → _response_normal_lro.text.erb} +1 -3
  102. data/templates/default/service/client/method/def/{_response_paged.erb → _response_paged.text.erb} +1 -1
  103. data/templates/default/service/client/method/def/_routing_params.text.erb +36 -0
  104. data/templates/default/service/client/method/docs/{_request_normal.erb → _request_normal.text.erb} +1 -1
  105. data/templates/default/service/client/method/docs/_snippets.text.erb +6 -0
  106. data/templates/default/service/client/resource/_def.text.erb +7 -0
  107. data/templates/default/service/nonstandard_lro.text.erb +6 -0
  108. data/templates/default/service/rest/client/_client.text.erb +202 -0
  109. data/templates/default/service/rest/client/_config.text.erb +178 -0
  110. data/templates/default/service/rest/client/_operations.text.erb +124 -0
  111. data/templates/default/service/rest/client/method/{_def.erb → _def.text.erb} +7 -1
  112. data/templates/default/service/rest/client/method/def/{_options_defaults.erb → _options_defaults.text.erb} +8 -3
  113. data/templates/default/service/rest/client/method/def/_response.text.erb +12 -0
  114. data/templates/default/service/rest/client/method/def/_response_nonstandard_lro.text.erb +24 -0
  115. data/templates/default/service/rest/client/method/def/_response_normal.text.erb +5 -0
  116. data/templates/default/service/rest/client/method/def/_response_normal_lro.text.erb +7 -0
  117. data/templates/default/service/rest/client/method/def/_response_paged.text.erb +7 -0
  118. data/templates/default/service/rest/client/method/def/_response_server_streaming.text.erb +11 -0
  119. data/templates/default/service/rest/client/method/docs/{_request.erb → _request.text.erb} +1 -3
  120. data/templates/default/service/rest/client/method/docs/_result.text.erb +10 -0
  121. data/templates/default/service/rest/client/method/docs/_snippets.text.erb +6 -0
  122. data/templates/default/service/rest/nonstandard_lro.text.erb +6 -0
  123. data/templates/default/service/rest/operations.text.erb +6 -0
  124. data/templates/default/service/rest/service_stub/_service_stub.text.erb +63 -0
  125. data/templates/default/service/rest/service_stub/grpc_transcoding_method/_def.text.erb +37 -0
  126. data/templates/default/service/rest/service_stub/method/_def.text.erb +35 -0
  127. data/templates/default/service/rest/service_stub/method/def/_response.text.erb +37 -0
  128. data/templates/default/service/rest/test/{client.erb → client.text.erb} +3 -3
  129. data/templates/default/service/rest/test/method/_assert_response.text.erb +2 -0
  130. data/templates/default/service/rest/test/method/{_configure.erb → _configure.text.erb} +3 -2
  131. data/templates/default/service/rest/test/method/_normal.text.erb +60 -0
  132. data/templates/default/service/rest/test/method/_server.text.erb +60 -0
  133. data/templates/default/service/rest/test/method/{_setup.erb → _setup.text.erb} +26 -10
  134. data/templates/default/service/test/{_resource.erb → _resource.text.erb} +1 -1
  135. data/templates/default/service/test/{client.erb → client.text.erb} +3 -2
  136. data/templates/default/service/test/client_paths.text.erb +33 -0
  137. data/templates/default/service/test/method/{_assert_response.erb → _assert_response.text.erb} +3 -0
  138. data/templates/default/service/test/method/{_bidi.erb → _bidi.text.erb} +1 -1
  139. data/templates/default/service/test/method/{_client.erb → _client.text.erb} +1 -1
  140. data/templates/default/service/test/method/{_configure.erb → _configure.text.erb} +2 -1
  141. data/templates/default/service/test/method/{_normal.erb → _normal.text.erb} +1 -1
  142. data/templates/default/service/test/method/{_server.erb → _server.text.erb} +1 -1
  143. data/templates/default/service/test/method/{_setup.erb → _setup.text.erb} +19 -2
  144. data/templates/default/snippets/{gemfile.erb → gemfile.text.erb} +2 -2
  145. data/templates/default/snippets/snippet/_body.text.erb +24 -0
  146. data/templates/default/snippets/snippet/_inline.text.erb +11 -0
  147. data/templates/default/snippets/snippet/_standalone.text.erb +25 -0
  148. data/templates/default/snippets/{standalone.erb → standalone.text.erb} +1 -1
  149. metadata +209 -230
  150. data/lib/google/api/annotations.pb.rb +0 -39
  151. data/lib/google/api/client.pb.rb +0 -43
  152. data/lib/google/api/field_behavior.pb.rb +0 -51
  153. data/lib/google/api/http.pb.rb +0 -60
  154. data/lib/google/api/resource.pb.rb +0 -80
  155. data/lib/google/longrunning/operations.pb.rb +0 -115
  156. data/lib/google/protobuf/any.pb.rb +0 -40
  157. data/lib/google/protobuf/compiler/plugin.pb.rb +0 -79
  158. data/lib/google/protobuf/descriptor.pb.rb +0 -360
  159. data/lib/google/protobuf/empty.pb.rb +0 -36
  160. data/lib/google/rpc/status.pb.rb +0 -46
  161. data/templates/default/gem/gemfile.erb +0 -4
  162. data/templates/default/lib/rest/_rest.erb +0 -9
  163. data/templates/default/service/client/method/def/_request_normal.erb +0 -4
  164. data/templates/default/service/client/method/def/_request_streaming.erb +0 -9
  165. data/templates/default/service/client/method/def/_response.erb +0 -6
  166. data/templates/default/service/client/method/docs/_deprecated.erb +0 -5
  167. data/templates/default/service/client/method/docs/_snippets.erb +0 -6
  168. data/templates/default/service/client/resource/_def.erb +0 -6
  169. data/templates/default/service/rest/client/_client.erb +0 -106
  170. data/templates/default/service/rest/client/_config.erb +0 -122
  171. data/templates/default/service/rest/client/method/def/_response.erb +0 -8
  172. data/templates/default/service/rest/client/method/def/_response_lro.erb +0 -7
  173. data/templates/default/service/rest/client/method/def/_response_normal.erb +0 -6
  174. data/templates/default/service/rest/client/method/def/_response_paged.erb +0 -7
  175. data/templates/default/service/rest/client/method/docs/_result.erb +0 -6
  176. data/templates/default/service/rest/service_stub/_service_stub.erb +0 -25
  177. data/templates/default/service/rest/service_stub/grpc_transcoding_method/_def.erb +0 -24
  178. data/templates/default/service/rest/service_stub/method/_def.erb +0 -20
  179. data/templates/default/service/rest/service_stub/method/def/_response.erb +0 -17
  180. data/templates/default/service/rest/test/method/_assert_response.erb +0 -2
  181. data/templates/default/service/rest/test/method/_normal.erb +0 -71
  182. data/templates/default/service/test/client_paths.erb +0 -15
  183. data/templates/default/snippets/snippet/_structure.erb +0 -71
  184. /data/gem_templates/{binary.erb → binary.text.erb} +0 -0
  185. /data/gem_templates/{dockerfile.erb → dockerfile.text.erb} +0 -0
  186. /data/gem_templates/{entrypoint.erb → entrypoint.text.erb} +0 -0
  187. /data/gem_templates/{gapic_sh.erb → gapic_sh.text.erb} +0 -0
  188. /data/gem_templates/{gemfile.erb → gemfile.text.erb} +0 -0
  189. /data/gem_templates/{gemspec.erb → gemspec.text.erb} +0 -0
  190. /data/gem_templates/{generator.erb → generator.text.erb} +0 -0
  191. /data/gem_templates/{gitignore.erb → gitignore.text.erb} +0 -0
  192. /data/gem_templates/{rakefile.erb → rakefile.text.erb} +0 -0
  193. /data/gem_templates/{readme.erb → readme.text.erb} +0 -0
  194. /data/gem_templates/{rubocop.erb → rubocop.text.erb} +0 -0
  195. /data/gem_templates/shared/{_header.erb → _header.text.erb} +0 -0
  196. /data/gem_templates/shared/{_license.erb → _license.text.erb} +0 -0
  197. /data/gem_templates/shared/{_warning.erb → _warning.text.erb} +0 -0
  198. /data/gem_templates/{test_generator.erb → test_generator.text.erb} +0 -0
  199. /data/gem_templates/{test_helper.erb → test_helper.text.erb} +0 -0
  200. /data/gem_templates/{version.erb → version.text.erb} +0 -0
  201. /data/templates/default/gem/{_version.erb → _version.text.erb} +0 -0
  202. /data/templates/default/gem/{changelog.erb → changelog.text.erb} +0 -0
  203. /data/templates/default/gem/{entrypoint.erb → entrypoint.text.erb} +0 -0
  204. /data/templates/default/gem/{gapic_metadata_json.erb → gapic_metadata_json.text.erb} +0 -0
  205. /data/templates/default/gem/{gitignore.erb → gitignore.text.erb} +0 -0
  206. /data/templates/default/gem/{license.erb → license.text.erb} +0 -0
  207. /data/templates/default/gem/{rakefile.erb → rakefile.text.erb} +0 -0
  208. /data/templates/default/gem/{version.erb → version.text.erb} +0 -0
  209. /data/templates/default/layouts/{_ruby.erb → _ruby.text.erb} +0 -0
  210. /data/templates/default/{package.erb → package.text.erb} +0 -0
  211. /data/templates/default/proto_docs/{_proto_file.erb → _proto_file.text.erb} +0 -0
  212. /data/templates/default/proto_docs/{proto_file.erb → proto_file.text.erb} +0 -0
  213. /data/templates/default/proto_docs/{readme.erb → readme.text.erb} +0 -0
  214. /data/templates/default/service/{_helpers.erb → _helpers.text.erb} +0 -0
  215. /data/templates/default/service/client/{_credentials.erb → _credentials.text.erb} +0 -0
  216. /data/templates/default/service/client/{_paths.erb → _paths.text.erb} +0 -0
  217. /data/templates/default/service/client/{_requires.erb → _requires.text.erb} +0 -0
  218. /data/templates/default/service/client/{_resource.erb → _resource.text.erb} +0 -0
  219. /data/templates/default/service/client/{_self_configure.erb → _self_configure.text.erb} +0 -0
  220. /data/templates/default/service/client/method/def/{_request.erb → _request.text.erb} +0 -0
  221. /data/templates/default/service/client/method/def/{_rescue.erb → _rescue.text.erb} +0 -0
  222. /data/templates/default/service/client/method/docs/{_error.erb → _error.text.erb} +0 -0
  223. /data/templates/default/service/client/method/docs/{_request.erb → _request.text.erb} +0 -0
  224. /data/templates/default/service/client/method/docs/{_request_field.erb → _request_field.text.erb} +0 -0
  225. /data/templates/default/service/client/method/docs/{_request_streaming.erb → _request_streaming.text.erb} +0 -0
  226. /data/templates/default/service/client/method/docs/{_response.erb → _response.text.erb} +0 -0
  227. /data/templates/default/service/client/method/docs/{_sample.erb → _sample.text.erb} +0 -0
  228. /data/templates/default/service/client/method/docs/{_sample_response.erb → _sample_response.text.erb} +0 -0
  229. /data/templates/default/service/client/method/docs/{_samples.erb → _samples.text.erb} +0 -0
  230. /data/templates/default/service/client/method/docs/request_field/{_arg.erb → _arg.text.erb} +0 -0
  231. /data/templates/default/service/client/method/docs/request_field/{_hash.erb → _hash.text.erb} +0 -0
  232. /data/templates/default/service/client/method/docs/sample_response/{_comment.erb → _comment.text.erb} +0 -0
  233. /data/templates/default/service/client/method/docs/sample_response/{_define.erb → _define.text.erb} +0 -0
  234. /data/templates/default/service/client/method/docs/sample_response/{_loop.erb → _loop.text.erb} +0 -0
  235. /data/templates/default/service/client/method/docs/sample_response/{_print.erb → _print.text.erb} +0 -0
  236. /data/templates/default/service/client/method/docs/sample_response/{_write_file.erb → _write_file.text.erb} +0 -0
  237. /data/templates/default/service/client/resource/{_doc.erb → _doc.text.erb} +0 -0
  238. /data/templates/default/service/client/resource/{_multi.erb → _multi.text.erb} +0 -0
  239. /data/templates/default/service/client/resource/{_single.erb → _single.text.erb} +0 -0
  240. /data/templates/default/service/{client.erb → client.text.erb} +0 -0
  241. /data/templates/default/service/{credentials.erb → credentials.text.erb} +0 -0
  242. /data/templates/default/service/{operations.erb → operations.text.erb} +0 -0
  243. /data/templates/default/service/{paths.erb → paths.text.erb} +0 -0
  244. /data/templates/default/service/rest/client/method/def/{_rescue.erb → _rescue.text.erb} +0 -0
  245. /data/templates/default/service/rest/client/method/docs/{_error.erb → _error.text.erb} +0 -0
  246. /data/templates/default/service/rest/{client.erb → client.text.erb} +0 -0
  247. /data/templates/default/service/rest/{grpc_transcoding.erb → grpc_transcoding.text.erb} +0 -0
  248. /data/templates/default/service/rest/service_stub/grpc_transcoding_method/def/{_query_string_param.erb → _query_string_param.text.erb} +0 -0
  249. /data/templates/default/service/rest/service_stub/method/def/{_request.erb → _request.text.erb} +0 -0
  250. /data/templates/default/service/rest/{service_stub.erb → service_stub.text.erb} +0 -0
  251. /data/templates/default/service/{rest.erb → rest.text.erb} +0 -0
  252. /data/templates/default/service/test/{client_operations.erb → client_operations.text.erb} +0 -0
  253. /data/templates/default/service/test/{smoke.erb → smoke.text.erb} +0 -0
  254. /data/templates/default/{service.erb → service.text.erb} +0 -0
  255. /data/templates/default/shared/{_header.erb → _header.text.erb} +0 -0
  256. /data/templates/default/shared/{_license.erb → _license.text.erb} +0 -0
  257. /data/templates/default/shared/{_warning.erb → _warning.text.erb} +0 -0
@@ -0,0 +1,221 @@
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 Model
21
+ module Method
22
+ ##
23
+ # The information used in the generation process that
24
+ # can be gathered from the `google.api.http` annotation.
25
+ # `google.api.http` is used in two distinct ways:
26
+ # - REST libs use it as part of the transcoding to set up the REST call
27
+ # - gRPC libs use it as a source of implicit routing headers
28
+ #
29
+ class HttpAnnotation
30
+ ##
31
+ # The Http bindings found in the annotation
32
+ # this includes main binding in the annotation itself,
33
+ # as well as those in the `additional_bindings`.
34
+ #
35
+ # @return [Array<HttpBinding>]
36
+ attr_reader :bindings
37
+
38
+ ##
39
+ # @param proto_http [::Google::Api::HttpRule]
40
+ # The base http annotation
41
+ #
42
+ def initialize proto_http
43
+ @bindings = parse_bindings proto_http
44
+ end
45
+
46
+ ##
47
+ # Whether any implicit routing parameters are present.
48
+ #
49
+ # @return [Boolean]
50
+ def routing_params?
51
+ routing_params.any?
52
+ end
53
+
54
+ ##
55
+ # The implicit routing parameter names.
56
+ #
57
+ # @return [Array<String>]
58
+ def routing_params
59
+ routing_params_with_patterns.map { |param, _| param }
60
+ end
61
+
62
+ ##
63
+ # The implicit routing parameter names and their corresponding paterns,
64
+ # including the `*` pattern implied for the named segments
65
+ # without an explicitly specified pattern.
66
+ #
67
+ # @return [Array<Array<String>>]
68
+ def routing_params_with_patterns
69
+ bindings.first&.routing_params_with_patterns || []
70
+ end
71
+
72
+ ##
73
+ # @param proto_method [::Gapic::Schema::Method]
74
+ # The proto method this annotation model applies to
75
+ # @param service_config [::Google::Api::Service]
76
+ # The service config that might contain an override for the http annotation.
77
+ # This is used for mixins: when generating Operations sublients, and when
78
+ # setting up overrides for other mixin clients in the host services's classes.
79
+ # For non-mixin service generation
80
+ # it is assumed that the service config is merged into protos before generation.
81
+ #
82
+ def self.create_with_override proto_method, service_config = nil
83
+ proto_http = proto_method.http
84
+
85
+ http_override = service_config&.http&.rules&.find { |http_rule| http_rule.selector == proto_method.full_name }
86
+
87
+ http = http_override || proto_http
88
+ HttpAnnotation.new http
89
+ end
90
+
91
+ ##
92
+ # A single Http binding.
93
+ #
94
+ class HttpBinding
95
+ ##
96
+ # @param binding [::Google::Api::HttpRule]
97
+ # The baseline instance of the Http annotation
98
+ def initialize binding
99
+ @binding = binding
100
+ end
101
+
102
+ ##
103
+ # Whether a http verb is present for this method
104
+ #
105
+ # @return [Boolean]
106
+ def verb?
107
+ !verb.nil?
108
+ end
109
+
110
+ ##
111
+ # The http verb for this method
112
+ #
113
+ # @return [Symbol, nil]
114
+ def verb
115
+ verb_path[0] if verb_path
116
+ end
117
+
118
+ ##
119
+ # Whether a method path is present and non-empty
120
+ #
121
+ # @return [Boolean]
122
+ def path?
123
+ !path.empty?
124
+ end
125
+
126
+ ##
127
+ # A method path or an empty string if not present
128
+ #
129
+ # @return [String]
130
+ def path
131
+ return "" unless verb_path
132
+ verb_path[1]
133
+ end
134
+
135
+ ##
136
+ # Whether any routing params are present
137
+ #
138
+ # @return [Boolean]
139
+ def routing_params?
140
+ routing_params.any?
141
+ end
142
+
143
+ ##
144
+ # The segment key names and their corresponding paterns,
145
+ # including the `*` pattern implied for the named segments
146
+ # without pattern explicitly specified.
147
+ #
148
+ # @return [Array<Array<String>>]
149
+ def routing_params_with_patterns
150
+ @routing_params_with_patterns ||= begin
151
+ Gapic::UriTemplate.parse_arguments(path).map do |name, pattern|
152
+ [name, pattern.empty? ? "*" : pattern]
153
+ end
154
+ end
155
+ end
156
+
157
+ ##
158
+ # The segment key names.
159
+ #
160
+ # @return [Array<String>]
161
+ def routing_params
162
+ routing_params_with_patterns.map { |param, _| param }
163
+ end
164
+
165
+ ##
166
+ # Whether method has body specified in proto
167
+ #
168
+ # @return [Boolean]
169
+ def body?
170
+ !body.empty?
171
+ end
172
+
173
+ ##
174
+ # The body specified for the given method in proto
175
+ # or an empty string if not specified
176
+ #
177
+ # @return [String]
178
+ def body
179
+ @binding&.body || ""
180
+ end
181
+
182
+ private
183
+
184
+ ##
185
+ # The combination of verb and path found in the http annotation
186
+ # (or Nil if the annotation is Nil).
187
+ #
188
+ # @return [Array<Symbol, String>, Nil]
189
+ def verb_path
190
+ return nil if @binding.nil?
191
+
192
+ {
193
+ get: @binding.get,
194
+ post: @binding.post,
195
+ put: @binding.put,
196
+ patch: @binding.patch,
197
+ delete: @binding.delete
198
+ }.find { |_, value| !value.empty? }
199
+ end
200
+ end
201
+
202
+ private
203
+
204
+ ##
205
+ # Parses http bindings from the `google.api.http` annotation, preserving order.
206
+ #
207
+ # @param http [::Google::Api::HttpRule]
208
+ # The root instance of the HttpRule to parse.
209
+ #
210
+ # @return Array<HttpBinding>
211
+ # The parsed bindings.
212
+ def parse_bindings http
213
+ return [] if http.nil?
214
+
215
+ raw_binds = [http] + http.additional_bindings.to_a
216
+ raw_binds.map { |raw_bind| HttpBinding.new raw_bind }
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,163 @@
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 "singleton"
18
+
19
+ require "gapic/path_pattern"
20
+
21
+ module Gapic
22
+ module Model
23
+ ##
24
+ # Method-level models
25
+ #
26
+ module Method
27
+ ##
28
+ # Nonstandard (AIP-151 nonconforming) long-running operation method-level model
29
+ #
30
+ # @!attribute [r] service_full_name
31
+ # @return [String] Full grpc name of the provider service for this method's LRO
32
+ # e.g. `google.example.LroProvider`
33
+ #
34
+ # @!attribute [r] operation_request_fields
35
+ # @return [Map<String, String>] Map of the field names of this method's request message
36
+ # that should be saved and later used when constructing the LRO polling request.
37
+ # The values are the names of the fields in the polling request.
38
+ # The semantics are `from -> to`, e.g. `{"foo" => "bar"}` means that
39
+ # when constructing a polling request, the following assignment should be carried out:
40
+ # `lro_polling_request.bar = this_method_request.foo`.
41
+ #
42
+ class NonStandardLro
43
+ # @return [String]
44
+ attr_reader :service_full_name
45
+ # @return [Map<String, String>]
46
+ attr_reader :operation_request_fields
47
+
48
+ ##
49
+ # @param method [Gapic::Schema::Method]
50
+ # @param service_full_name [String] Full grpc name of the provider service for this method's LRO
51
+ def initialize method, service_full_name
52
+ @service_full_name = service_full_name
53
+
54
+ # optionally, there might be things to copy from this method's input object
55
+ # to the LRO service's input object (`operation_request_field` annotation)
56
+ ops_request_fields = method.input.fields.find_all do |f|
57
+ !f.operation_request_field.nil? && !f.operation_request_field.empty?
58
+ end
59
+
60
+ @operation_request_fields = ops_request_fields.to_h do |field|
61
+ [field.name, field.operation_request_field]
62
+ end
63
+ end
64
+
65
+ ##
66
+ # @return [Boolean] Whether this is a model for the nonstandard LRO
67
+ #
68
+ def nonstandard_lro?
69
+ true
70
+ end
71
+
72
+ ##
73
+ # @return [Boolean] Whether this is a model for the AIP-151 LRO
74
+ #
75
+ def aip_lro?
76
+ false
77
+ end
78
+ end
79
+
80
+ ##
81
+ # AIP-151 LRO Model
82
+ #
83
+ class AipLro
84
+ include Singleton
85
+ ##
86
+ # @return [Boolean] Whether this is a model for the nonstandard LRO
87
+ #
88
+ def nonstandard_lro?
89
+ false
90
+ end
91
+
92
+ ##
93
+ # @return [Boolean] Whether this is a model for the AIP-151 LRO
94
+ #
95
+ def aip_lro?
96
+ true
97
+ end
98
+ end
99
+
100
+ ##
101
+ # Method does not represent a long-running operation
102
+ #
103
+ class NoLro
104
+ include Singleton
105
+ ##
106
+ # @return [Boolean] Whether this is a model for the nonstandard LRO
107
+ #
108
+ def nonstandard_lro?
109
+ false
110
+ end
111
+
112
+ ##
113
+ # @return [Boolean] Whether this is a model for the AIP-151 LRO
114
+ #
115
+ def aip_lro?
116
+ false
117
+ end
118
+ end
119
+
120
+ class << self
121
+ ##
122
+ # Inspects the method and returns it's long-running operation model
123
+ #
124
+ # @param method [Gapic::Schema::Method]
125
+ # @param api [Gapic::Schema::Api]
126
+ #
127
+ # @raises [Gapic::Model::ModelError]
128
+ #
129
+ # @returns [Gapic::Model::Method::NonStandardLro, Gapic::Model::Method::AipLro, Gapic::Model::Method::NoLro]
130
+ #
131
+ def parse_lro method, api
132
+ is_aip_lro = method.output.full_name == "google.longrunning.Operation"
133
+ return AipLro.instance if is_aip_lro
134
+
135
+ # If a method is annotated with operation_service, this is a nonstandard LRO consumer method
136
+ is_nonstandard_lro = !method.operation_service.nil? && !method.operation_service.empty?
137
+ if is_nonstandard_lro
138
+ # LRO service name is given plain, so it has to be in the same package as this method's service
139
+ service_full_name = (method.address[0..-3] << method.operation_service).join "."
140
+ ops_service_lro = api.nonstandard_lro_model_for service_full_name
141
+ unless ops_service_lro.nonstandard_lro?
142
+ error_text = "A service #{service_full_name} specified as a nonstandard LRO service for " \
143
+ "the method #{method.full_name} was not found."
144
+ raise ModelError, error_text
145
+ end
146
+
147
+ unless method.output.full_name == ops_service_lro.lro_object_full_name
148
+ error_text = "A service #{service_full_name} specified as a nonstandard LRO service for " \
149
+ "the method #{method.full_name} has a different LRO object " \
150
+ "(#{ops_service_lro.lro_object_full_name}) from the method's return type " \
151
+ "(#{method.output.full_name})."
152
+ raise ModelError, error_text
153
+ end
154
+
155
+ return NonStandardLro.new method, service_full_name
156
+ end
157
+
158
+ NoLro.instance
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,248 @@
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/path_pattern"
18
+
19
+ module Gapic
20
+ module Model
21
+ module Method
22
+ ##
23
+ # Routing headers info determined from the proto method
24
+ #
25
+ # @!attribute [r] routing
26
+ # @return [::Google::Api::RoutingRule] Explicit routing annotation for the Api
27
+ class Routing
28
+ attr_reader :routing
29
+
30
+ ##
31
+ # @param routing [::Google::Api::RoutingRule] Explict routing annotation for the Api
32
+ # @param http [Gapic::Model::Method::HttpAnnotation] Model for the Http annotation
33
+ #
34
+ def initialize routing, http
35
+ @routing = routing
36
+ @http = http
37
+ end
38
+
39
+ ##
40
+ # Whether routing parameters are specified
41
+ #
42
+ # @return [Boolean]
43
+ def routing_params?
44
+ explicit_params? || implicit_params?
45
+ end
46
+
47
+ ##
48
+ # Whether an explicit routing annotation (`google.api.routing`) is present
49
+ #
50
+ # @return [Boolean]
51
+ def explicit_annotation?
52
+ !@routing.nil?
53
+ end
54
+
55
+ ##
56
+ # Whether an annotation that might contain implicit routing (`google.api.http`) is present
57
+ #
58
+ # @return [Boolean]
59
+ def implicit_annotation?
60
+ !@http.nil?
61
+ end
62
+
63
+ ##
64
+ # Whether explicit routing parameters are present
65
+ #
66
+ # @return [Boolean]
67
+ def explicit_params?
68
+ return false unless explicit_annotation?
69
+
70
+ explicit_params.any?
71
+ end
72
+
73
+ ##
74
+ # Explicit routing parameters, if present.
75
+ # Grouped by the routing key, in order, with the extraction and matching information.
76
+ #
77
+ # @return [Hash<String, Array>]
78
+ def explicit_params
79
+ all_explicit_params.group_by(&:key).transform_values do |params|
80
+ params.sort_by(&:order).to_a
81
+ end
82
+ end
83
+
84
+ ##
85
+ # Whether implict routing parameters from `google.api.http` annotation are present
86
+ #
87
+ # @return [Boolean]
88
+ def implicit_params?
89
+ @http.routing_params?
90
+ end
91
+
92
+ ##
93
+ # Implicit routing parameters.
94
+ # These strings are both field and routing header key names.
95
+ #
96
+ # @return [Array<String>]
97
+ def implicit_params
98
+ return {} unless implicit_params?
99
+ @http.routing_params
100
+ end
101
+
102
+ ##
103
+ # Full routing parameter information, including parsing order
104
+ # and matching/extraction patterns and regexes.
105
+ #
106
+ # @!attribute [r] order
107
+ # @return [Integer] Order of the parameter in the annotation
108
+ #
109
+ # @!attribute [r] field
110
+ # @return [String] Field to extract the routing header from
111
+ #
112
+ # @!attribute [r] raw_template
113
+ # @return [String, nil] Raw template as given in the annotation
114
+ #
115
+ # @!attribute [r] path_template
116
+ # @return [String] 'Processed' template, handling such cases as
117
+ # empty or nameless template
118
+ #
119
+ # @!attribute [r] key
120
+ # @return [String] Name of the key to add to the routing header
121
+ #
122
+ # @!attribute [r] value_pattern
123
+ # @return [String] The pattern of the value to be extracted
124
+ #
125
+ # @!attribute [r] field_pattern
126
+ # @return [String] The pattern of the full field (simplified)
127
+ # The field as a whole should match this pattern
128
+ # This pattern is simplified, stipped of the names of the
129
+ # resource id segments.
130
+ # (e.g. `collections/{resource_id=foo/*}` => `collections/foo/*`)
131
+ #
132
+ # @!attribute [r] field_regex_str
133
+ # @return [String] The regex matching the `field_pattern`
134
+ # (the regex form of the simplified pattern)
135
+ #
136
+ # @!attribute [r] field_full_regex_str
137
+ # @return [String] The regex matching the full unsimplified field pattern
138
+ # (it will contain the named capture corresponding to the
139
+ # resource id segment name)
140
+ #
141
+ class RoutingParameter
142
+ attr_reader :order
143
+ attr_reader :field
144
+ attr_reader :raw_template
145
+ attr_reader :path_template
146
+ attr_reader :key
147
+ attr_reader :value_pattern
148
+ attr_reader :field_pattern
149
+ attr_reader :field_regex_str
150
+ attr_reader :field_full_regex_str
151
+
152
+ ##
153
+ # @param routing_parameter [::Google::Api::RoutingParameter]
154
+ # Routing parameter annotation
155
+ #
156
+ # @param order [Integer]
157
+ # Order of this annotation among its peers
158
+ def initialize routing_parameter, order
159
+ @order = order
160
+ @field = routing_parameter.field
161
+ @raw_template = routing_parameter.path_template
162
+ @path_template = infer_template @raw_template, @field
163
+ @path_pattern = Gapic::PathPattern.parse @path_template
164
+
165
+ resource_segment = @path_pattern.segments.find(&:resource_id_segment?)
166
+
167
+ # Only one segment providing an argument and only one argument in the segment
168
+ # (no `{foo}~{bar}` segments)
169
+ valid = @path_pattern.segments.count(&:resource_id_segment?) == 1 &&
170
+ resource_segment.arguments.count == 1
171
+
172
+ unless valid
173
+ error_text = create_invalid_error_text @path_pattern, @raw_template
174
+ raise ModelError, error_text
175
+ end
176
+
177
+ @field_pattern = @path_pattern.simplified_pattern
178
+ @field_full_regex_str = @path_pattern.to_field_regex_str
179
+ @field_regex_str = Gapic::PathPattern.parse(@field_pattern).to_field_regex_str
180
+
181
+ @key = resource_segment.arguments[0]
182
+ @value_pattern = resource_segment.resource_patterns[0]
183
+ end
184
+
185
+ ##
186
+ # Whether pattern matching is not needed
187
+ # since the patterns allow all strings
188
+ # @return [Boolean]
189
+ def pattern_matching_not_needed?
190
+ field_pattern == "**" && value_pattern == "**"
191
+ end
192
+
193
+ ##
194
+ # Whether the value to be added to the routing header
195
+ # is the value of the whole field
196
+ # @return [Boolean]
197
+ def value_is_full_field?
198
+ @path_pattern.segments.count == 1
199
+ end
200
+
201
+ private
202
+
203
+ # Converts path template simplified forms into canonical
204
+ # ResourceId representations by adding a field as a Resource Id
205
+ # @param template [String]
206
+ # @param field [String]
207
+ # @return [String]
208
+ def infer_template template, field
209
+ if template.nil? || template.empty?
210
+ return "{#{field}=**}"
211
+ end
212
+
213
+ if template.strip == "**"
214
+ return "{#{field}=**}"
215
+ end
216
+
217
+ if template.strip == "*"
218
+ return "{#{field}=*}"
219
+ end
220
+
221
+ template
222
+ end
223
+
224
+ def create_invalid_error_text path_pattern, raw_template
225
+ reason = if path_pattern.segments.count(&:resource_id_segment?).zero?
226
+ "it contains no ResourceId (e.g. `{foo=*}`) segments"
227
+ elsif path_pattern.segments.count(&:resource_id_segment?) > 1
228
+ "it contains more than one ResourceId (e.g. `{foo=*}`) segments "
229
+ else
230
+ "it contains a multivariate ResourceId segment (e.g. `{foo}~{bar}`)"
231
+ end
232
+
233
+ "A routing header parameter with the path_template #{raw_template}\n is invalid: #{reason}"
234
+ end
235
+ end
236
+
237
+ private
238
+
239
+ # All explicit routing parameters in an array.
240
+ # @return [Array<RoutingParameter>]
241
+ def all_explicit_params
242
+ return [] unless explicit_annotation?
243
+ @routing.routing_parameters.each_with_index.map { |param, index| RoutingParameter.new param, index }.to_a
244
+ end
245
+ end
246
+ end
247
+ end
248
+ end