gapic-generator 0.7.1 → 0.9.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -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 +4 -0
  7. data/lib/gapic/presenters/field_presenter.rb +44 -0
  8. data/lib/gapic/presenters/gem_presenter.rb +55 -10
  9. data/lib/gapic/presenters/method_presenter.rb +40 -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_config_presenter.rb +48 -0
  13. data/lib/gapic/presenters/service_presenter.rb +60 -4
  14. data/lib/gapic/presenters/service_rest_presenter.rb +139 -0
  15. data/lib/gapic/presenters/snippet_presenter.rb +103 -0
  16. data/lib/gapic/runner.rb +2 -1
  17. data/lib/gapic/schema/api.rb +58 -16
  18. data/lib/gapic/schema/request_param_parser.rb +46 -12
  19. data/lib/google/protobuf/any.pb.rb +1 -1
  20. data/lib/google/protobuf/compiler/plugin.pb.rb +9 -6
  21. data/lib/google/protobuf/descriptor.pb.rb +2 -2
  22. data/lib/google/protobuf/empty.pb.rb +1 -1
  23. data/templates/default/gem/readme.erb +3 -3
  24. data/templates/default/lib/_package.erb +11 -1
  25. data/templates/default/lib/_service.erb +31 -1
  26. data/templates/default/lib/rest/_rest.erb +11 -0
  27. data/templates/default/service/client/_client.erb +1 -1
  28. data/templates/default/service/client/_credentials.erb +2 -0
  29. data/templates/default/service/client/_operations.erb +1 -1
  30. data/templates/default/service/client/_self_configure_defaults.erb +2 -2
  31. data/templates/default/service/rest.erb +6 -0
  32. data/templates/default/service/rest/client.erb +6 -0
  33. data/templates/default/service/rest/client/_client.erb +115 -0
  34. data/templates/default/service/rest/client/_config.erb +74 -0
  35. data/templates/default/service/rest/client/_requires.erb +1 -0
  36. data/templates/default/service/rest/client/method/_def.erb +18 -0
  37. data/templates/default/service/rest/client/method/def/_options_defaults.erb +15 -0
  38. data/templates/default/service/rest/client/method/def/_rescue.erb +3 -0
  39. data/templates/default/service/rest/client/method/def/_response_normal.erb +17 -0
  40. data/templates/default/service/rest/client/method/docs/_error.erb +2 -0
  41. data/templates/default/service/rest/client/method/docs/_request.erb +27 -0
  42. data/templates/default/service/rest/client/method/docs/_result.erb +6 -0
  43. data/templates/default/service/rest/grpc_transcoding.erb +6 -0
  44. data/templates/default/service/rest/grpc_transcoding/_grpc_transcoding.erb +9 -0
  45. data/templates/default/service/rest/grpc_transcoding/method/_def.erb +21 -0
  46. data/templates/default/service/rest/grpc_transcoding/method/def/_query_string_param.erb +8 -0
  47. data/templates/default/service/rest/test/client.erb +18 -0
  48. data/templates/default/service/rest/test/method/_assert_response.erb +2 -0
  49. data/templates/default/service/rest/test/method/_configure.erb +19 -0
  50. data/templates/default/service/rest/test/method/_normal.erb +71 -0
  51. data/templates/default/service/rest/test/method/_setup.erb +38 -0
  52. data/templates/default/snippets/gemfile.erb +17 -0
  53. data/templates/default/snippets/snippet/_structure.erb +71 -0
  54. data/templates/default/snippets/standalone.erb +6 -0
  55. metadata +32 -4
  56. data/templates/default/service/client/_self_configure_retry_policy.erb +0 -15
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require "active_support/inflector"
18
+
19
+ module Gapic
20
+ module Presenters
21
+ ##
22
+ # A presenter for snippets.
23
+ #
24
+ class SnippetPresenter
25
+ def initialize method_presenter, api
26
+ @method_presenter = method_presenter
27
+ @api = api
28
+ end
29
+
30
+ def client_streaming?
31
+ @method_presenter.client_streaming?
32
+ end
33
+
34
+ def bidi_streaming?
35
+ @method_presenter.client_streaming? && @method_presenter.server_streaming?
36
+ end
37
+
38
+ def response_kind
39
+ if @method_presenter.server_streaming?
40
+ :streaming
41
+ elsif @method_presenter.paged?
42
+ :paged
43
+ elsif @method_presenter.lro?
44
+ :lro
45
+ else
46
+ :simple
47
+ end
48
+ end
49
+
50
+ def snippet_file_path
51
+ "#{@method_presenter.service.service_require.split('/').last}/#{@method_presenter.name}.rb"
52
+ end
53
+
54
+ def require_path
55
+ @method_presenter.service.service_require
56
+ end
57
+
58
+ def client_type
59
+ @method_presenter.service.client_name_full.sub(/^::/, "")
60
+ end
61
+
62
+ def request_type
63
+ @method_presenter.request_type.sub(/^::/, "")
64
+ end
65
+
66
+ def return_type
67
+ base_type = @method_presenter.return_type.sub(/^::/, "")
68
+ @method_presenter.server_streaming? ? "Enumerable<#{base_type}>" : base_type
69
+ end
70
+
71
+ def paged_response_type
72
+ @method_presenter.paged_response_type
73
+ end
74
+
75
+ def base_response_type
76
+ @method_presenter.return_type
77
+ end
78
+
79
+ # TODO: Determine type of LRO response
80
+
81
+ def method_name
82
+ @method_presenter.name
83
+ end
84
+
85
+ def region_tag
86
+ gem_presenter = @method_presenter.service.gem
87
+ api_id = gem_presenter.api_shortname || gem_presenter.api_id&.split(".")&.first
88
+ names = gem_presenter.name.split "-"
89
+ final_name = names.pop
90
+ if final_name =~ /^v\d/
91
+ api_version = final_name
92
+ api_id ||= names.last
93
+ else
94
+ api_id ||= final_name
95
+ api_version = "v0"
96
+ end
97
+ service_name = @method_presenter.service.module_name
98
+ method_name = @method_presenter.method.name
99
+ "#{api_id}_#{api_version}_generated_#{service_name}_#{method_name}_sync"
100
+ end
101
+ end
102
+ end
103
+ end
data/lib/gapic/runner.rb CHANGED
@@ -65,7 +65,8 @@ module Gapic
65
65
 
66
66
  # Create and write the response
67
67
  response = Google::Protobuf::Compiler::CodeGeneratorResponse.new file: output_files
68
- response.supported_features = Google::Protobuf::Compiler::CodeGeneratorResponse::FEATURE_PROTO3_OPTIONAL
68
+ feature_set = Google::Protobuf::Compiler::CodeGeneratorResponse::Feature::FEATURE_PROTO3_OPTIONAL.to_i
69
+ response.supported_features = feature_set
69
70
  response
70
71
  end
71
72
 
@@ -89,6 +89,10 @@ module Gapic
89
89
  matching_files.first
90
90
  end
91
91
 
92
+ def overrides_of key
93
+ configuration&.fetch(:overrides, nil)&.fetch(key, nil) || {}
94
+ end
95
+
92
96
  def fix_file_path str
93
97
  str = String str
94
98
  return str if configuration[:overrides].nil?
@@ -144,11 +148,9 @@ module Gapic
144
148
  # @return [Array<Hash>]
145
149
  # An array of the sample file hashes.
146
150
  def samples
147
- @samples ||= begin
148
- protoc_options["samples"].to_s.split(";").flat_map do |sample_path|
149
- YAML.load_file sample_path
150
- end.compact
151
- end
151
+ @samples ||= protoc_options["samples"].to_s.split(";").flat_map do |sample_path|
152
+ YAML.load_file sample_path
153
+ end.compact
152
154
  end
153
155
 
154
156
  # Structured representation of the standalone samples configuration files.
@@ -174,10 +176,10 @@ module Gapic
174
176
  # An array of the standalone sample configuration hashes.
175
177
  def standalone_test_samples
176
178
  @standalone_test_samples ||= begin
177
- samples.select { |sample| sample["type"] == "test/samples" }
178
- .select { |sample| sample["schema_version"] == "1" || sample["schema_version"] == 1 }
179
- .map { |sample| sample["samples"] }
180
- .flatten.compact
179
+ test_samples = samples.select { |sample| sample["type"] == "test/samples" }
180
+ test_samples.select { |sample| sample["schema_version"] == "1" || sample["schema_version"] == 1 }
181
+ .map { |sample| sample["samples"] }
182
+ .flatten.compact
181
183
  end
182
184
  end
183
185
 
@@ -231,6 +233,29 @@ module Gapic
231
233
  configuration[:generate_path_helpers_output] ||= false
232
234
  end
233
235
 
236
+ # Whether to generate REST clients
237
+ def generate_rest_clients?
238
+ return false if configuration[:transports].nil?
239
+ configuration[:transports].include? "rest"
240
+ end
241
+
242
+ # Whether to generate GRPC clients
243
+ def generate_grpc_clients?
244
+ return true if configuration[:transports].nil?
245
+ configuration[:transports].include? "grpc"
246
+ end
247
+
248
+ # Whether to generate standalone snippets
249
+ def generate_standalone_snippets?
250
+ configuration[:generate_standalone_snippets] ||= false
251
+ end
252
+
253
+ # Whether to generate gapic metadata (drift manifest) file
254
+ # @return [Boolean]
255
+ def generate_metadata
256
+ configuration[:generate_metadata] ||= false
257
+ end
258
+
234
259
  # Whether the override_proto_namespaces parameter was given in the configuration
235
260
  def override_proto_namespaces_defined?
236
261
  configuration.key? :override_proto_namespaces
@@ -260,9 +285,7 @@ module Gapic
260
285
 
261
286
  # Parsed grpc service config
262
287
  def grpc_service_config
263
- @grpc_service_config ||= begin
264
- Gapic::GrpcServiceConfig::Parser.parse grpc_service_config_raw
265
- end
288
+ @grpc_service_config ||= Gapic::GrpcServiceConfig::Parser.parse grpc_service_config_raw
266
289
  end
267
290
 
268
291
  # Get a resource given its type string
@@ -272,10 +295,8 @@ module Gapic
272
295
 
273
296
  # Given a service, find all common services that use it as a delegate.
274
297
  def common_services_for delegate
275
- @delegate_to_common ||= begin
276
- (configuration[:common_services] || {}).each_with_object({}) do |(c, d), mapping|
277
- (mapping[d] ||= []) << c
278
- end
298
+ @delegate_to_common ||= (configuration[:common_services] || {}).each_with_object({}) do |(c, d), mapping|
299
+ (mapping[d] ||= []) << c
279
300
  end
280
301
  all_services = services
281
302
  @delegate_to_common.fetch(delegate.address.join("."), []).map do |addr|
@@ -292,6 +313,27 @@ module Gapic
292
313
  services.find { |s| s.address == addr }
293
314
  end
294
315
 
316
+ ##
317
+ # Whether configuration has an override for the wrapper gem name
318
+ # @return [Boolean]
319
+ def wrapper_gem_name_override?
320
+ configuration.key?(:overrides) &&
321
+ configuration[:overrides].key?(:wrapper_gem_name)
322
+ end
323
+
324
+ ##
325
+ # An override for the wrapper gem name in the configuration
326
+ # @return [String, Nil]
327
+ def wrapper_gem_name_override
328
+ return nil unless wrapper_gem_name_override?
329
+ return nil if configuration[:overrides][:wrapper_gem_name].nil?
330
+
331
+ wrapper_name_config = configuration[:overrides][:wrapper_gem_name].strip
332
+ return nil if wrapper_name_config.empty?
333
+
334
+ wrapper_name_config
335
+ end
336
+
295
337
  private
296
338
 
297
339
  # Perform a variety of sanity checks on the data, and prints errors to
@@ -67,16 +67,15 @@ module Gapic
67
67
  param_name_input = unescape param_name_input_esc
68
68
  param_type, param_config_name = param_schema.schema_name_type_for param_name_input
69
69
 
70
- if param_type == :bool && !["true", "false"].include?(unescape(value_str))
71
- error_str = "WARNING: parameter #{param_name_input} (recognised as bool " \
72
- "#{param_config_name}) will be discarded because of " \
73
- "invalid value. Value should be either 'true' or 'false'."
74
- error_output&.puts error_str
75
- end
76
-
77
- param_value = parse_param_value param_type, value_str
70
+ param_value = parse_validate_param_value(
71
+ param_type,
72
+ param_name_input,
73
+ param_config_name,
74
+ value_str,
75
+ error_output
76
+ )
78
77
 
79
- if param_value
78
+ unless param_value.nil?
80
79
  RequestParameter.new param_val_input_str, param_name_input_esc, value_str, param_config_name, param_value
81
80
  end
82
81
  end.compact # known bool parameters with invalid values will not be added so we have to compact
@@ -92,13 +91,48 @@ module Gapic
92
91
 
93
92
  private
94
93
 
94
+ # Parses and validates param value depending on type and name
95
+ # @param param_type [Symbol] type of the parameter
96
+ # @param param_name_input [String] name of the parameter as given in the config
97
+ # @param param_config_name [String] canonical configuration name of the parameter
98
+ # @param value_str [String] string representation of parameter's value
99
+ # @param error_output [IO] Stream to write outputs to.
100
+ # @return [String,Array<String>,Hash{String => String}]
101
+ def parse_validate_param_value param_type, param_name_input, param_config_name, value_str, error_output
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'."
106
+ error_output&.puts error_str
107
+ end
108
+
109
+ param_value = parse_param_value param_type, value_str
110
+
111
+ if param_config_name == ":transports"
112
+ allowed_transports = ["grpc", "rest"]
113
+ noncompliant_values = param_value.reject { |pv| allowed_transports.include? pv }
114
+ if noncompliant_values.any?
115
+ 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."
120
+ error_output&.puts error_str
121
+ param_value = nil
122
+ end
123
+ end
124
+
125
+ param_value
126
+ end
127
+
95
128
  # Parses param value depending on type
96
- # @param param_type [Symbol]
97
- # @param value_str [String]
129
+ # @param param_type [Symbol] type of the parameter
130
+ # @param value_str [String] string representation of parameter's value
98
131
  # @return [String,Array<String>,Hash{String => String}]
99
132
  def parse_param_value param_type, value_str
100
133
  case param_type
101
134
  when :array
135
+ return [] if value_str.empty?
102
136
  # elements in the arrays are concatenated by `;`
103
137
  # e.g. foo;bar;baz
104
138
  array_value_strings = split_by_unescaped value_str, ";"
@@ -114,7 +148,7 @@ module Gapic
114
148
  when :bool
115
149
  # bools should be either `true` or `false`
116
150
  unesc_val = unescape value_str
117
- unesc_val if ["true", "false"].include? unesc_val
151
+ (unesc_val == "true") if ["true", "false"].include? unesc_val
118
152
  else
119
153
  # if it's an unknown type, just escape it without attempting to parse anything
120
154
  unescape value_str
@@ -21,7 +21,7 @@ module Google
21
21
  set_option :java_package, "com.google.protobuf"
22
22
  set_option :java_outer_classname, "AnyProto"
23
23
  set_option :java_multiple_files, true
24
- set_option :go_package, "github.com/golang/protobuf/ptypes/any"
24
+ set_option :go_package, "google.golang.org/protobuf/types/known/anypb"
25
25
  set_option :objc_class_prefix, "GPB"
26
26
  set_option :csharp_namespace, "Google.Protobuf.WellKnownTypes"
27
27
 
@@ -1,8 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  ##
4
- # This file was auto-generated initially but now is hand-edited to add support
5
- # for response features and proto3_optional
4
+ # This file is auto-generated. DO NOT EDIT!
6
5
  #
7
6
  require 'protobuf'
8
7
 
@@ -23,6 +22,11 @@ module Google
23
22
  class Version < ::Protobuf::Message; end
24
23
  class CodeGeneratorRequest < ::Protobuf::Message; end
25
24
  class CodeGeneratorResponse < ::Protobuf::Message
25
+ class Feature < ::Protobuf::Enum
26
+ define :FEATURE_NONE, 0
27
+ define :FEATURE_PROTO3_OPTIONAL, 1
28
+ end
29
+
26
30
  class File < ::Protobuf::Message; end
27
31
 
28
32
  end
@@ -34,7 +38,7 @@ module Google
34
38
  #
35
39
  set_option :java_package, "com.google.protobuf.compiler"
36
40
  set_option :java_outer_classname, "PluginProtos"
37
- set_option :go_package, "github.com/golang/protobuf/protoc-gen-go/plugin;plugin_go"
41
+ set_option :go_package, "google.golang.org/protobuf/types/pluginpb"
38
42
 
39
43
 
40
44
  ##
@@ -55,16 +59,15 @@ module Google
55
59
  end
56
60
 
57
61
  class CodeGeneratorResponse
58
- FEATURE_PROTO3_OPTIONAL = 1
59
-
60
62
  class File
61
63
  optional :string, :name, 1
62
64
  optional :string, :insertion_point, 2
63
65
  optional :string, :content, 15
66
+ optional ::Google::Protobuf::GeneratedCodeInfo, :generated_code_info, 16
64
67
  end
65
68
 
66
69
  optional :string, :error, 1
67
- optional :int32, :supported_features, 2
70
+ optional :uint64, :supported_features, 2
68
71
  repeated ::Google::Protobuf::Compiler::CodeGeneratorResponse::File, :file, 15
69
72
  end
70
73
 
@@ -121,7 +121,7 @@ module Google
121
121
  set_option :java_package, "com.google.protobuf"
122
122
  set_option :java_outer_classname, "DescriptorProtos"
123
123
  set_option :optimize_for, ::Google::Protobuf::FileOptions::OptimizeMode::SPEED
124
- set_option :go_package, "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor"
124
+ set_option :go_package, "google.golang.org/protobuf/types/descriptorpb"
125
125
  set_option :cc_enable_arenas, true
126
126
  set_option :objc_class_prefix, "GPB"
127
127
  set_option :csharp_namespace, "Google.Protobuf.Reflection"
@@ -245,7 +245,7 @@ module Google
245
245
  optional :bool, :py_generic_services, 18, :default => false
246
246
  optional :bool, :php_generic_services, 42, :default => false
247
247
  optional :bool, :deprecated, 23, :default => false
248
- optional :bool, :cc_enable_arenas, 31, :default => false
248
+ optional :bool, :cc_enable_arenas, 31, :default => true
249
249
  optional :string, :objc_class_prefix, 36
250
250
  optional :string, :csharp_namespace, 37
251
251
  optional :string, :swift_prefix, 39
@@ -21,7 +21,7 @@ module Google
21
21
  set_option :java_package, "com.google.protobuf"
22
22
  set_option :java_outer_classname, "EmptyProto"
23
23
  set_option :java_multiple_files, true
24
- set_option :go_package, "github.com/golang/protobuf/ptypes/empty"
24
+ set_option :go_package, "google.golang.org/protobuf/types/known/emptypb"
25
25
  set_option :cc_enable_arenas, true
26
26
  set_option :objc_class_prefix, "GPB"
27
27
  set_option :csharp_namespace, "Google.Protobuf.WellKnownTypes"
@@ -16,12 +16,12 @@ $ gem install <%= gem.name %>
16
16
 
17
17
  ```ruby
18
18
  require "<%= gem.entrypoint_require %>"
19
- <%- service = gem.first_non_common_service -%>
20
- <%- method = service&.methods.first -%>
19
+ <%- service = gem.quick_start_service -%>
20
+ <%- method = service&.quick_start_method -%>
21
21
  <%- if service && method -%>
22
22
 
23
23
  client = <%= service.create_client_call %>
24
- request = my_create_request
24
+ request = <%= method.request_type %>.new # (request fields as keyword arguments...)
25
25
  response = client.<%= method.name %> request
26
26
  <%- end -%>
27
27
  ```
@@ -6,13 +6,23 @@ require "<%= service.service_require %>"
6
6
  require "<%= package.gem.version_require %>"
7
7
  <% end %>
8
8
  <%- unless package.empty? -%>
9
+ <%- if package.services.first.generate_grpc_clients? -%>
9
10
  ##
10
- # To load this package, including all its services, and instantiate a client:
11
+ # To load this package, including all its services, and instantiate a <%= package.grpc_client_designation %>:
11
12
  #
12
13
  # require "<%= package.package_require %>"
13
14
  # client = <%= package.services.first.create_client_call %>
14
15
  #
15
16
  <%- end -%>
17
+ <%- if package.services.first.generate_rest_clients? -%>
18
+ ##
19
+ # To load this package, including all its services, and instantiate a REST client:
20
+ #
21
+ # require "<%= package.package_require %>"
22
+ # client = <%= package.services.first.rest.create_client_call %>
23
+ #
24
+ <%- end -%>
25
+ <%- end -%>
16
26
  module <%= package.module_name %>
17
27
  end
18
28
  <% @footer = capture do %>