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
@@ -14,12 +14,15 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
- require "google/api/annotations.pb"
18
- require "google/api/client.pb"
19
- require "google/api/field_behavior.pb"
20
- require "google/api/resource.pb"
21
- require "google/longrunning/operations.pb"
22
- require "google/protobuf/descriptor.pb"
17
+ require "google/api/annotations_pb"
18
+ require "google/api/client_pb"
19
+ require "google/api/field_behavior_pb"
20
+ require "google/api/resource_pb"
21
+ require "google/api/routing_pb"
22
+ require "google/cloud/extended_operations_pb"
23
+ require "google/longrunning/operations_pb"
24
+ require "google/protobuf/descriptor_pb"
25
+ require "gapic/schema/proto_tools"
23
26
  require "gapic/schema/wrappers"
24
27
 
25
28
  module Gapic
@@ -32,12 +35,21 @@ module Gapic
32
35
  @prior_enums = []
33
36
  end
34
37
 
38
+ FILE_EXTENSION_NAMES = {
39
+ "google.api.resource_definition" => [1053, ::Google::Api::ResourceDescriptor, :repeated]
40
+ }.freeze
41
+
42
+ MESSAGE_EXTENSION_NAMES = {
43
+ "google.api.resource" => [1053, ::Google::Api::ResourceDescriptor]
44
+ }.freeze
45
+
35
46
  # Loads a file.
36
47
  #
37
48
  # @param file_descriptor [Google::Protobuf::FileDescriptorProto] the
38
49
  # descriptor of the proto file.
39
- # @oaram file_to_generate [Boolean] Whether this file is to be
50
+ # @param file_to_generate [Boolean] Whether this file is to be
40
51
  # generated.
52
+ # @return [Gapic::Schema::File]
41
53
  def load_file file_descriptor, file_to_generate
42
54
  # Setup.
43
55
  address = file_descriptor.package.split "."
@@ -45,27 +57,28 @@ module Gapic
45
57
  registry = {}
46
58
 
47
59
  # Load the docs.
48
- location = file_descriptor.source_code_info.location
49
- docs = location.each_with_object({}) { |l, ans| ans[l.path] = l }
60
+ location = file_descriptor.source_code_info.location || []
61
+ docs = location.each_with_object({}) { |l, ans| ans[l.path.to_a] = l }
50
62
 
51
63
  # Load top-level enums.
52
- enums = file_descriptor.enum_type.each_with_index.map do |e, i|
64
+ enums = (file_descriptor.enum_type || []).each_with_index.map do |e, i|
53
65
  load_enum registry, e, address, docs, [5, i]
54
66
  end
55
67
 
56
68
  # Load top-level messages.
57
- messages = file_descriptor.message_type.each_with_index.map do |m, i|
69
+ messages = (file_descriptor.message_type || []).each_with_index.map do |m, i|
58
70
  load_message registry, m, address, docs, [4, i]
59
71
  end
60
72
  messages.each(&method(:update_fields!))
61
73
 
62
74
  # Load services.
63
- services = file_descriptor.service.each_with_index.map do |s, i|
75
+ services = (file_descriptor.service || []).each_with_index.map do |s, i|
64
76
  load_service registry, s, address, docs, [6, i]
65
77
  end
66
78
 
67
79
  # Load top-level resources
68
- resource_descriptors = file_descriptor.options[:".google.api.resource_definition"] if file_descriptor.options
80
+ option_extensions = ProtoTools.parse_options_extensions file_descriptor.options, FILE_EXTENSION_NAMES
81
+ resource_descriptors = option_extensions["google.api.resource_definition"]
69
82
  resources = Array(resource_descriptors).map { |descriptor| Resource.new descriptor }
70
83
 
71
84
  # Construct and return the file.
@@ -73,6 +86,25 @@ module Gapic
73
86
  services, resources, file_to_generate, registry
74
87
  end
75
88
 
89
+ ##
90
+ # Loads snippet configs from the given directory
91
+ #
92
+ # @param path [String] Directory to search for snippet config files
93
+ # @return [Array<
94
+ # Google::Cloud::Tools::SnippetGen::ConfigLanguage::V1::SnippetConfig>]
95
+ #
96
+ def load_snippet_configs path
97
+ return [] unless path
98
+ Dir.chdir path do
99
+ Dir.glob("**/*.json").map do |file_path|
100
+ json = JSON.load_file file_path
101
+ proto = Google::Cloud::Tools::SnippetGen::ConfigLanguage::V1::SnippetConfig.new underscore_keys json
102
+ proto.json_representation = json
103
+ proto
104
+ end
105
+ end
106
+ end
107
+
76
108
  # Updates the fields of a message and it's nested messages.
77
109
  #
78
110
  # @param message [Message] the message whose fields and nested messages
@@ -102,7 +134,7 @@ module Gapic
102
134
  address = address.clone << descriptor.name
103
135
 
104
136
  # Load Enum Values
105
- values = descriptor.value.each_with_index.map do |value, i|
137
+ values = (descriptor.value || []).each_with_index.map do |value, i|
106
138
  load_enum_value registry, value, address, docs, path + [2, i]
107
139
  end
108
140
 
@@ -149,20 +181,22 @@ module Gapic
149
181
  address = address.clone << descriptor.name
150
182
 
151
183
  # Load Children
152
- nested_messages = descriptor.nested_type.each_with_index.map do |m, i|
184
+ nested_messages = (descriptor.nested_type || []).each_with_index.map do |m, i|
153
185
  load_message registry, m, address, docs, path + [3, i]
154
186
  end
155
- nested_enums = descriptor.enum_type.each_with_index.map do |e, i|
187
+ nested_enums = (descriptor.enum_type || []).each_with_index.map do |e, i|
156
188
  load_enum registry, e, address, docs, path + [4, i]
157
189
  end
158
- fields = descriptor.field.each_with_index.map do |f, i|
190
+ fields = (descriptor.field || []).each_with_index.map do |f, i|
159
191
  load_field registry, f, address, docs, path + [2, i]
160
192
  end
161
- extensions = descriptor.extension.each_with_index.map do |e, i|
193
+ fields.each { |field| field.populate_oneof_siblings! fields }
194
+ extensions = (descriptor.extension || []).each_with_index.map do |e, i|
162
195
  load_field registry, e, address, docs, path + [6, i]
163
196
  end
164
197
 
165
- resource_descriptor = descriptor.options[:".google.api.resource"] if descriptor.options
198
+ option_extensions = ProtoTools.parse_options_extensions descriptor.options, MESSAGE_EXTENSION_NAMES
199
+ resource_descriptor = option_extensions["google.api.resource"]
166
200
  resource = resource_descriptor ? Resource.new(resource_descriptor) : nil
167
201
 
168
202
  # Construct, cache, and return.
@@ -209,7 +243,7 @@ module Gapic
209
243
  address = address.clone << descriptor.name
210
244
 
211
245
  # Load children
212
- methods = descriptor.method.each_with_index.map do |m, i|
246
+ methods = (descriptor["method"] || descriptor.method || []).each_with_index.map do |m, i|
213
247
  load_method registry, m, address, docs, path + [2, i]
214
248
  end
215
249
 
@@ -259,6 +293,20 @@ module Gapic
259
293
 
260
294
  private
261
295
 
296
+ ##
297
+ # Transforms all keys in the given hash to snake case.
298
+ #
299
+ def underscore_keys input
300
+ case input
301
+ when Hash
302
+ input.to_h { |key, value| [ActiveSupport::Inflector.underscore(key), underscore_keys(value)] }
303
+ when Array
304
+ input.map { |elem| underscore_keys elem }
305
+ else
306
+ input
307
+ end
308
+ end
309
+
262
310
  def add_to_registry registry, address, obj
263
311
  registry[address.join(".")] = obj
264
312
  obj
@@ -266,7 +314,7 @@ module Gapic
266
314
 
267
315
  def cached_obj collection, type_name
268
316
  # Remove leading dot.
269
- type_name = type_name[1..-1] if type_name && type_name[0] == "."
317
+ type_name = type_name[1..] if type_name && type_name[0] == "."
270
318
 
271
319
  # Create an address from the type & check cache.
272
320
  collection.find { |m| m.address == type_name.split(".") }
@@ -43,10 +43,10 @@ module Gapic
43
43
  # @param map_params_list [Array<String>]
44
44
  # @return Gapic::Schema::ParameterSchema
45
45
  def self.create bool_params_list: [], string_params_list: [], array_params_list: [], map_params_list: []
46
- bool_params = bool_params_list.map { |val| [val, val] }.to_h
47
- string_params = string_params_list.map { |val| [val, val] }.to_h
48
- array_params = array_params_list.map { |val| [val, val] }.to_h
49
- map_params = map_params_list.map { |val| [val, val] }.to_h
46
+ bool_params = bool_params_list.to_h { |val| [val, val] }
47
+ string_params = string_params_list.to_h { |val| [val, val] }
48
+ array_params = array_params_list.to_h { |val| [val, val] }
49
+ map_params = map_params_list.to_h { |val| [val, val] }
50
50
 
51
51
  ParameterSchema.new bool_params, string_params, array_params, map_params
52
52
  end
@@ -58,16 +58,16 @@ module Gapic
58
58
  # @param map_aliases [Hash{String => String}]
59
59
  # @return Gapic::Schema::ParameterSchema
60
60
  def extend_with_aliases bool_aliases: {}, string_aliases: {}, array_aliases: {}, map_aliases: {}
61
- bool_params = @bool_params
61
+ bool_params = @bool_params.dup
62
62
  bool_aliases.each { |param_alias, param| bool_params[param_alias] = param if bool_params.key? param }
63
63
 
64
- string_params = @string_params
64
+ string_params = @string_params.dup
65
65
  string_aliases.each { |param_alias, param| string_params[param_alias] = param if string_params.key? param }
66
66
 
67
- array_params = @array_params
67
+ array_params = @array_params.dup
68
68
  array_aliases.each { |param_alias, param| array_params[param_alias] = param if array_params.key? param }
69
69
 
70
- map_params = @map_params
70
+ map_params = @map_params.dup
71
71
  map_aliases.each { |param_alias, param| map_params[param_alias] = param if map_params.key? param }
72
72
 
73
73
  ParameterSchema.new bool_params, string_params, array_params, map_params
@@ -0,0 +1,193 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2023 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 "stringio"
18
+
19
+ module Gapic
20
+ module Schema
21
+ ##
22
+ # @private
23
+ #
24
+ # A set of logic dealing with parsing raw proto data. This is unfortunately
25
+ # necessary for getting options extension information from proto
26
+ # descriptors, because the google-protobuf library implementation is
27
+ # incomplete. (Specifically, it does not expose Ruby interfaces for Service
28
+ # and Method descriptors, the objects that normally surface extended
29
+ # options; see https://github.com/protocolbuffers/protobuf/issues/14891.)
30
+ #
31
+ # We hope this code will be temporary until the above protobuf features are
32
+ # available. In the meantime, we make it private.
33
+ #
34
+ module ProtoTools
35
+ class << self
36
+ ##
37
+ # Parse through an options object looking for specific fields.
38
+ #
39
+ # The fields should be provided as a hash mapping the option name to
40
+ # an array of the form `[id, type, flags...]` where the ID is the field
41
+ # number, the type is the protobuf message class or one of the symbols
42
+ # `:string`, `:bool`, `:enum`, and currently the only flag supported is
43
+ # `:repeated`.
44
+ #
45
+ # Returns a hash mapping option names found to their values. Repeated
46
+ # values are represented as arrays (not as protobuf repeated values).
47
+ #
48
+ def parse_options_extensions options, extension_config
49
+ return {} unless options
50
+ return options.dup.delete_if { |k, _v| !extension_config.key? k } if options.is_a? Hash
51
+ bytes = options.class.encode options
52
+ return {} if bytes.empty?
53
+ option_data_by_id = build_option_data_by_id extension_config
54
+ results = build_default_results extension_config
55
+ walk_bytes bytes do |id, _wire_type, data|
56
+ option_data = option_data_by_id[id]
57
+ next unless option_data
58
+ name = option_data[0]
59
+ type = option_data[1]
60
+ results[name] =
61
+ if option_data[2].include? :repeated
62
+ decode_repeated data, type, results[name]
63
+ else
64
+ decode_data data, type
65
+ end
66
+ end
67
+ results
68
+ end
69
+
70
+ ##
71
+ # Given a byte string of data, parse through it and yield each record
72
+ # as the field number, wire type number, and data. The data is either
73
+ # an integer (for VARINT) or byte array (for LEN). I64 and I32 records
74
+ # are skipped.
75
+ #
76
+ def walk_bytes bytes
77
+ io = StringIO.new bytes
78
+ until io.eof?
79
+ tag = read_varint io
80
+ id = tag >> 3
81
+ wire_type = tag & 7
82
+ case wire_type
83
+ when 0 # VARINT
84
+ data = read_varint io
85
+ yield id, wire_type, data
86
+ when 1 # I64
87
+ # Skip
88
+ io.read 8
89
+ when 2 # LEN
90
+ len = read_varint io
91
+ data = io.read len
92
+ yield id, wire_type, data
93
+ when 5 # I32
94
+ # Skip
95
+ io.read 4
96
+ else
97
+ raise "Wire type #{wire_type} not supported (id = #{id})"
98
+ end
99
+ end
100
+ end
101
+
102
+ ##
103
+ # Read and return a single VARINT from the byte stream
104
+ #
105
+ def read_varint io
106
+ acc = 0
107
+ shift = 0
108
+ loop do
109
+ byte = io.getbyte
110
+ acc += ((byte & 0x7f) << shift)
111
+ shift += 7
112
+ break if byte < 0x80
113
+ end
114
+ acc
115
+ end
116
+
117
+ ##
118
+ # Given a data and type, return a decoded form of the data.
119
+ # If the type is `:string`, the data must be a bytestring and is
120
+ # returned as is. If the type is `:enum`, the data must be an integer
121
+ # and is returned as is. If the type is `:bool`, the data must be an
122
+ # integer and is converted to a boolean. If the type is a protobuf
123
+ # message class, the data must be a bytestring and is decoded. Any
124
+ # other type is not supported and results in an exception.
125
+ #
126
+ def decode_data data, type
127
+ case type
128
+ when :string, :enum
129
+ data
130
+ when :bool
131
+ !data.zero?
132
+ when ::Class
133
+ type.decode data
134
+ else
135
+ raise "Type #{type} not supported"
136
+ end
137
+ end
138
+
139
+ ##
140
+ # Given a data and a repeated type, return a decoded form of the data
141
+ # as an array. Supports repeated `:string`, `:enum`, and protobuf
142
+ # message class types. Any other type results in an exception.
143
+ #
144
+ def decode_repeated data, type, acc = nil
145
+ acc ||= []
146
+ case type
147
+ when :string
148
+ acc << data
149
+ when :enum
150
+ if data.is_a? ::String
151
+ io = StringIO.new data
152
+ acc << read_varint(io) until io.eof?
153
+ else
154
+ acc << data
155
+ end
156
+ when ::Class
157
+ acc << type.decode(data)
158
+ else
159
+ raise "Type #{type} not supported"
160
+ end
161
+ acc
162
+ end
163
+
164
+ private
165
+
166
+ # @private
167
+ # Internal method to build a hash of default results
168
+ def build_default_results extension_config
169
+ extension_config.to_h do |name, config|
170
+ default =
171
+ if config[2..].include? :repeated
172
+ []
173
+ else
174
+ case config[1]
175
+ when :enum
176
+ 0
177
+ when :string
178
+ ""
179
+ end
180
+ end
181
+ [name, default]
182
+ end
183
+ end
184
+
185
+ # @private
186
+ # Internal method to build a hash keyed by id
187
+ def build_option_data_by_id extension_config
188
+ extension_config.to_h { |name, config| [config[0], [name, config[1], config[2..]]] }
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
@@ -100,9 +100,8 @@ module Gapic
100
100
  # @return [String,Array<String>,Hash{String => String}]
101
101
  def parse_validate_param_value param_type, param_name_input, param_config_name, value_str, error_output
102
102
  if param_type == :bool && !["true", "false"].include?(unescape(value_str))
103
- error_str = "WARNING: parameter #{param_name_input} (recognised as bool " \
104
- "#{param_config_name}) will be discarded because of " \
105
- "invalid value. Value should be either 'true' or 'false'."
103
+ error_str = "WARNING: parameter #{param_name_input} (recognised as bool #{param_config_name}) will be " \
104
+ "discarded because of invalid value. Value should be either 'true' or 'false'."
106
105
  error_output&.puts error_str
107
106
  end
108
107
 
@@ -113,10 +112,9 @@ module Gapic
113
112
  noncompliant_values = param_value.reject { |pv| allowed_transports.include? pv }
114
113
  if noncompliant_values.any?
115
114
  noncompliant_values_list = noncompliant_values.join ", "
116
- error_str = "WARNING: parameter #{param_name_input} (recognised as string array " \
117
- "#{param_config_name}) will be discarded because "\
118
- "it contains invalid values: #{noncompliant_values_list}. "\
119
- "#{param_config_name} can only contain 'grpc' and/or 'rest' or be empty."
115
+ error_str = "WARNING: parameter #{param_name_input} (recognised as string array #{param_config_name}) " \
116
+ "will be discarded because it contains invalid values: #{noncompliant_values_list}. " \
117
+ "#{param_config_name} can only contain 'grpc' and/or 'rest' or be empty."
120
118
  error_output&.puts error_str
121
119
  param_value = nil
122
120
  end
@@ -0,0 +1,152 @@
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 "yaml"
18
+ require "google/api/service_pb"
19
+
20
+ module Gapic
21
+ module Schema
22
+ # Contains logic for parsing a subset of service.yaml used
23
+ # for the service generation
24
+ module ServiceConfigParser
25
+ class << self
26
+ CONFIG_VERSION_KEY = "config_version"
27
+ NAME_KEY = "name"
28
+ VERSION_KEY = "version"
29
+ ID_KEY = "id"
30
+ TITLE_KEY = "title"
31
+ APIS_KEY = "apis"
32
+ HTTP_KEY = "http"
33
+ HTTP_RULES_KEY = "rules"
34
+ HTTP_RULES_SELECTOR_KEY = "selector"
35
+ HTTP_RULES_VERBS_ALLOWED = ["get", "post", "put", "patch", "delete"].freeze
36
+ HTTP_RULES_BODY_KEY = "body"
37
+ HTTP_RULES_ADDITIONAL_BINDINGS_KEY = "additional_bindings"
38
+ PUBS_KEY = "publishing"
39
+ PUBS_SHORTNAME_KEY = "api_short_name"
40
+ PUBS_ORGANIZATION_KEY = "organization"
41
+ PUBS_DOCURL_KEY = "documentation_uri"
42
+ PUBS_DOCTAG_KEY = "doc_tag_prefix"
43
+ PUBS_METHOD_SETTINGS = "method_settings"
44
+ DOCS_KEY = "documentation"
45
+ DOCS_SUMMARY_KEY = "summary"
46
+ DOCS_OVERVIEW_KEY = "overview"
47
+
48
+ ##
49
+ # Returns the parsed Google::Api::Service object.
50
+ # Only supports a limited subset of fields.
51
+ #
52
+ # @return [::Google::Api::Service]
53
+ #
54
+ def parse_service_yaml service_yaml_text
55
+ return nil unless service_yaml_text && !service_yaml_text.empty?
56
+ service_yaml = YAML.safe_load service_yaml_text
57
+ service = Google::Api::Service.new
58
+
59
+ if service_yaml.key? CONFIG_VERSION_KEY
60
+ config_ver = Google::Protobuf::UInt32Value.new
61
+ config_ver.value = service_yaml[CONFIG_VERSION_KEY]
62
+ service.config_version = config_ver
63
+ end
64
+
65
+ service.name = service_yaml[NAME_KEY] if service_yaml.key? NAME_KEY
66
+ service.id = service_yaml[ID_KEY] if service_yaml.key? ID_KEY
67
+ service.title = service_yaml[TITLE_KEY] if service_yaml.key? TITLE_KEY
68
+
69
+ service.apis += parse_apis service_yaml[APIS_KEY] if service_yaml.key? APIS_KEY
70
+ service.http = parse_http service_yaml[HTTP_KEY] if service_yaml.key? HTTP_KEY
71
+ service
72
+ end
73
+
74
+ ##
75
+ # Populates Gapic::Model::ApiMetadata from a service yaml file.
76
+ #
77
+ # @param service_yaml_text [String] YAML content
78
+ # @param api_metadata [Gapic::Model::ApiMetadata] model to populate
79
+ #
80
+ def parse_api_metadata service_yaml_text, api_metadata = nil
81
+ api_metadata ||= Gapic::Model::ApiMetadata.new
82
+ if service_yaml_text && !service_yaml_text.empty?
83
+ service_yaml = YAML.safe_load service_yaml_text
84
+ pubs_yaml = service_yaml[PUBS_KEY] || {}
85
+ docs_yaml = service_yaml[DOCS_KEY] || {}
86
+ api_metadata.update! name: service_yaml[NAME_KEY],
87
+ short_name: pubs_yaml[PUBS_SHORTNAME_KEY],
88
+ title: service_yaml[TITLE_KEY],
89
+ summary: docs_yaml[DOCS_SUMMARY_KEY],
90
+ description: docs_yaml[DOCS_OVERVIEW_KEY],
91
+ organization: pubs_yaml[PUBS_ORGANIZATION_KEY],
92
+ documentation_url: pubs_yaml[PUBS_DOCURL_KEY],
93
+ doc_tag_prefix: pubs_yaml[PUBS_DOCTAG_KEY],
94
+ method_settings: pubs_yaml[PUBS_METHOD_SETTINGS] || {}
95
+ end
96
+ api_metadata
97
+ end
98
+
99
+ private
100
+
101
+ # Parses the Apis section of the service yaml
102
+ # @return [Enumerable<::Google::Protobuf::Api>]
103
+ def parse_apis apis_yaml
104
+ apis_yaml.map { |api_yaml| parse_api api_yaml }
105
+ end
106
+
107
+ # Parses a single Api from yaml
108
+ # only supports a limited amount of fields
109
+ # @return [::Google::Protobuf::Api]
110
+ def parse_api api_yaml
111
+ api = ::Google::Protobuf::Api.new
112
+ api.name = api_yaml[NAME_KEY] if api_yaml.key? NAME_KEY
113
+ api.version = api_yaml[VERSION_KEY] if api_yaml.key? VERSION_KEY
114
+ api
115
+ end
116
+
117
+ # Parses a http section of the service yaml
118
+ # only supports a limited amount of fields
119
+ # @return [::Google::Api::Http]
120
+ def parse_http http_yaml
121
+ http = Google::Api::Http.new
122
+
123
+ if http_yaml.key? HTTP_RULES_KEY
124
+ http.rules += http_yaml[HTTP_RULES_KEY].map { |rule_yaml| parse_http_rule rule_yaml }
125
+ end
126
+
127
+ http
128
+ end
129
+
130
+ # Parses a single Http rule from yaml
131
+ # only supports a limited amount of fields
132
+ # NB: this method is recursive when parsing additional_bindings field
133
+ # @return [::Google::Api::HttpRule]
134
+ def parse_http_rule rule_yaml
135
+ rule = Google::Api::HttpRule.new
136
+ rule.selector = rule_yaml[HTTP_RULES_SELECTOR_KEY] if rule_yaml.key? HTTP_RULES_SELECTOR_KEY
137
+ verb_path = HTTP_RULES_VERBS_ALLOWED.find { |verb| rule_yaml[verb] }
138
+ rule.send "#{verb_path}=", rule_yaml[verb_path] if verb_path
139
+ rule.body = rule_yaml[HTTP_RULES_BODY_KEY] if rule_yaml.key? HTTP_RULES_BODY_KEY
140
+
141
+ if rule_yaml.key? HTTP_RULES_ADDITIONAL_BINDINGS_KEY
142
+ rule.additional_bindings += rule_yaml[HTTP_RULES_ADDITIONAL_BINDINGS_KEY].map do |binding_yaml|
143
+ parse_http_rule binding_yaml
144
+ end
145
+ end
146
+
147
+ rule
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end