gapic-generator 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +13 -0
- data/CHANGELOG.md +43 -0
- data/CODE_OF_CONDUCT.md +43 -0
- data/CONTRIBUTING.md +28 -0
- data/LICENSE +202 -0
- data/README.md +72 -0
- data/bin/gapic-generator +103 -0
- data/bin/protoc-gen-ruby_gapic +33 -0
- data/default-rubocop.yml +10 -0
- data/gem_templates/binary.erb +20 -0
- data/gem_templates/dockerfile.erb +39 -0
- data/gem_templates/entrypoint.erb +24 -0
- data/gem_templates/gapic_sh.erb +97 -0
- data/gem_templates/gemfile.erb +8 -0
- data/gem_templates/gemspec.erb +36 -0
- data/gem_templates/generator.erb +37 -0
- data/gem_templates/gitignore.erb +10 -0
- data/gem_templates/rakefile.erb +29 -0
- data/gem_templates/readme.erb +69 -0
- data/gem_templates/rubocop.erb +16 -0
- data/gem_templates/shared/_header.erb +4 -0
- data/gem_templates/shared/_license.erb +13 -0
- data/gem_templates/shared/_warning.erb +1 -0
- data/gem_templates/test_generator.erb +13 -0
- data/gem_templates/test_helper.erb +25 -0
- data/gem_templates/version.erb +10 -0
- data/lib/gapic/file_formatter.rb +62 -0
- data/lib/gapic/formatting_utils.rb +109 -0
- data/lib/gapic/gem_builder.rb +98 -0
- data/lib/gapic/generator.rb +30 -0
- data/lib/gapic/generator/version.rb +21 -0
- data/lib/gapic/generators/base_generator.rb +91 -0
- data/lib/gapic/generators/default_generator.rb +101 -0
- data/lib/gapic/grpc_service_config/method_config.rb +49 -0
- data/lib/gapic/grpc_service_config/parser.rb +218 -0
- data/lib/gapic/grpc_service_config/parsing_error.rb +25 -0
- data/lib/gapic/grpc_service_config/retry_policy.rb +51 -0
- data/lib/gapic/grpc_service_config/service_config.rb +42 -0
- data/lib/gapic/path_template.rb +35 -0
- data/lib/gapic/path_template/parser.rb +83 -0
- data/lib/gapic/path_template/segment.rb +67 -0
- data/lib/gapic/resource_lookup.rb +91 -0
- data/lib/gapic/runner.rb +76 -0
- data/lib/gapic/schema.rb +17 -0
- data/lib/gapic/schema/api.rb +264 -0
- data/lib/gapic/schema/loader.rb +269 -0
- data/lib/gapic/schema/wrappers.rb +717 -0
- data/lib/google/api/annotations.pb.rb +39 -0
- data/lib/google/api/client.pb.rb +43 -0
- data/lib/google/api/field_behavior.pb.rb +51 -0
- data/lib/google/api/http.pb.rb +60 -0
- data/lib/google/api/resource.pb.rb +80 -0
- data/lib/google/longrunning/operations.pb.rb +115 -0
- data/lib/google/protobuf/any.pb.rb +40 -0
- data/lib/google/protobuf/compiler/plugin.pb.rb +72 -0
- data/lib/google/protobuf/descriptor.pb.rb +359 -0
- data/lib/google/protobuf/empty.pb.rb +36 -0
- data/lib/google/rpc/status.pb.rb +46 -0
- data/templates/default/gem/_version.erb +2 -0
- data/templates/default/gem/changelog.erb +3 -0
- data/templates/default/gem/gemfile.erb +4 -0
- data/templates/default/gem/gemspec.erb +37 -0
- data/templates/default/gem/gitignore.erb +20 -0
- data/templates/default/gem/license.erb +22 -0
- data/templates/default/gem/rakefile.erb +27 -0
- data/templates/default/gem/readme.erb +24 -0
- data/templates/default/gem/rubocop.erb +59 -0
- data/templates/default/gem/version.erb +6 -0
- data/templates/default/gem/yardopts.erb +12 -0
- data/templates/default/helpers/default_helper.rb +50 -0
- data/templates/default/helpers/filepath_helper.rb +38 -0
- data/templates/default/helpers/namespace_helper.rb +44 -0
- data/templates/default/helpers/presenter_helper.rb +24 -0
- data/templates/default/helpers/presenters/enum_presenter.rb +35 -0
- data/templates/default/helpers/presenters/enum_value_presenter.rb +33 -0
- data/templates/default/helpers/presenters/field_presenter.rb +146 -0
- data/templates/default/helpers/presenters/file_presenter.rb +53 -0
- data/templates/default/helpers/presenters/gem_presenter.rb +140 -0
- data/templates/default/helpers/presenters/message_presenter.rb +66 -0
- data/templates/default/helpers/presenters/method_presenter.rb +293 -0
- data/templates/default/helpers/presenters/package_presenter.rb +65 -0
- data/templates/default/helpers/presenters/resource_presenter.rb +92 -0
- data/templates/default/helpers/presenters/sample_presenter.rb +74 -0
- data/templates/default/helpers/presenters/service_presenter.rb +276 -0
- data/templates/default/layouts/_ruby.erb +20 -0
- data/templates/default/package.erb +6 -0
- data/templates/default/proto_docs/_enum.erb +13 -0
- data/templates/default/proto_docs/_message.erb +23 -0
- data/templates/default/proto_docs/_proto_file.erb +9 -0
- data/templates/default/proto_docs/proto_file.erb +6 -0
- data/templates/default/proto_docs/readme.erb +5 -0
- data/templates/default/service.erb +8 -0
- data/templates/default/service/client.erb +6 -0
- data/templates/default/service/client/_client.erb +137 -0
- data/templates/default/service/client/_config.erb +155 -0
- data/templates/default/service/client/_credentials.erb +21 -0
- data/templates/default/service/client/_helpers.erb +9 -0
- data/templates/default/service/client/_operations.erb +88 -0
- data/templates/default/service/client/_paths.erb +8 -0
- data/templates/default/service/client/_requires.erb +1 -0
- data/templates/default/service/client/_resource.erb +6 -0
- data/templates/default/service/client/_self_configure.erb +9 -0
- data/templates/default/service/client/_self_configure_defaults.erb +22 -0
- data/templates/default/service/client/_self_configure_retry_policy.erb +15 -0
- data/templates/default/service/client/method/_def.erb +21 -0
- data/templates/default/service/client/method/def/_options_defaults.erb +29 -0
- data/templates/default/service/client/method/def/_request.erb +6 -0
- data/templates/default/service/client/method/def/_request_normal.erb +4 -0
- data/templates/default/service/client/method/def/_request_streaming.erb +9 -0
- data/templates/default/service/client/method/def/_rescue.erb +1 -0
- data/templates/default/service/client/method/def/_response.erb +6 -0
- data/templates/default/service/client/method/def/_response_normal.erb +8 -0
- data/templates/default/service/client/method/def/_response_paged.erb +9 -0
- data/templates/default/service/client/method/docs/_error.erb +2 -0
- data/templates/default/service/client/method/docs/_request.erb +6 -0
- data/templates/default/service/client/method/docs/_request_field.erb +7 -0
- data/templates/default/service/client/method/docs/_request_normal.erb +20 -0
- data/templates/default/service/client/method/docs/_request_streaming.erb +5 -0
- data/templates/default/service/client/method/docs/_response.erb +6 -0
- data/templates/default/service/client/method/docs/_sample.erb +20 -0
- data/templates/default/service/client/method/docs/_sample_response.erb +24 -0
- data/templates/default/service/client/method/docs/_samples.erb +6 -0
- data/templates/default/service/client/method/docs/request_field/_arg.erb +10 -0
- data/templates/default/service/client/method/docs/request_field/_hash.erb +19 -0
- data/templates/default/service/client/method/docs/sample_response/_comment.erb +5 -0
- data/templates/default/service/client/method/docs/sample_response/_define.erb +2 -0
- data/templates/default/service/client/method/docs/sample_response/_loop.erb +12 -0
- data/templates/default/service/client/method/docs/sample_response/_print.erb +2 -0
- data/templates/default/service/client/method/docs/sample_response/_write_file.erb +2 -0
- data/templates/default/service/client/resource/_def.erb +6 -0
- data/templates/default/service/client/resource/_doc.erb +8 -0
- data/templates/default/service/client/resource/_multi.erb +28 -0
- data/templates/default/service/client/resource/_single.erb +11 -0
- data/templates/default/service/credentials.erb +6 -0
- data/templates/default/service/operations.erb +6 -0
- data/templates/default/service/paths.erb +6 -0
- data/templates/default/service/test/client.erb +24 -0
- data/templates/default/service/test/client_operations.erb +24 -0
- data/templates/default/service/test/method/_assert_response.erb +11 -0
- data/templates/default/service/test/method/_bidi.erb +100 -0
- data/templates/default/service/test/method/_client.erb +84 -0
- data/templates/default/service/test/method/_normal.erb +69 -0
- data/templates/default/service/test/method/_server.erb +85 -0
- data/templates/default/service/test/method/_setup.erb +21 -0
- data/templates/default/service/test/smoke.erb +12 -0
- data/templates/default/shared/_header.erb +4 -0
- data/templates/default/shared/_license.erb +21 -0
- data/templates/default/shared/_warning.erb +1 -0
- metadata +351 -0
@@ -0,0 +1,146 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2018 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
|
+
class FieldPresenter
|
20
|
+
include NamespaceHelper
|
21
|
+
|
22
|
+
def initialize api, message, field
|
23
|
+
@api = api
|
24
|
+
@message = message
|
25
|
+
@field = field
|
26
|
+
end
|
27
|
+
|
28
|
+
def name
|
29
|
+
@field.name
|
30
|
+
end
|
31
|
+
|
32
|
+
def doc_types
|
33
|
+
field_doc_types @field, false
|
34
|
+
end
|
35
|
+
|
36
|
+
def doc_attribute_type
|
37
|
+
mode = @field.output_only? ? "r" : "rw"
|
38
|
+
"@!attribute [#{mode}] #{@field.name}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def output_doc_types
|
42
|
+
field_doc_types @field, true
|
43
|
+
end
|
44
|
+
|
45
|
+
def doc_description
|
46
|
+
@field.docs_leading_comments
|
47
|
+
end
|
48
|
+
|
49
|
+
def default_value
|
50
|
+
single = default_singular_value
|
51
|
+
return "[#{single}]" if @field.repeated? && !@field.map?
|
52
|
+
single
|
53
|
+
end
|
54
|
+
|
55
|
+
def as_kwarg value: nil
|
56
|
+
"#{name}: #{value || name}"
|
57
|
+
end
|
58
|
+
|
59
|
+
# TODO: remove, only used in tests
|
60
|
+
def type_name
|
61
|
+
@field.type_name
|
62
|
+
end
|
63
|
+
|
64
|
+
def type_name_full
|
65
|
+
return nil if type_name.blank?
|
66
|
+
ruby_namespace @api, type_name
|
67
|
+
end
|
68
|
+
|
69
|
+
def message?
|
70
|
+
@field.message?
|
71
|
+
end
|
72
|
+
|
73
|
+
def enum?
|
74
|
+
@field.enum?
|
75
|
+
end
|
76
|
+
|
77
|
+
def repeated?
|
78
|
+
@field.repeated?
|
79
|
+
end
|
80
|
+
|
81
|
+
def map?
|
82
|
+
@field.map?
|
83
|
+
end
|
84
|
+
|
85
|
+
protected
|
86
|
+
|
87
|
+
def field_doc_types field, output
|
88
|
+
return field_map_type field.message, output if field.map?
|
89
|
+
base_type =
|
90
|
+
if field.message?
|
91
|
+
type = message_ruby_type field.message
|
92
|
+
output ? type : "#{type} | Hash"
|
93
|
+
elsif field.enum?
|
94
|
+
# TODO: handle when arg message is nil and enum is the type
|
95
|
+
message_ruby_type field.enum
|
96
|
+
else
|
97
|
+
case field.type
|
98
|
+
when 1, 2 then "Float"
|
99
|
+
when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "Integer"
|
100
|
+
when 9, 12 then "String"
|
101
|
+
when 8 then "Boolean"
|
102
|
+
else
|
103
|
+
"Object"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
field.repeated? ? "Array<#{base_type}>" : base_type
|
107
|
+
end
|
108
|
+
|
109
|
+
def field_map_type entry_message, output
|
110
|
+
key_field = value_field = nil
|
111
|
+
entry_message.fields.each do |field|
|
112
|
+
key_field = field if field.name == "key"
|
113
|
+
value_field = field if field.name == "value"
|
114
|
+
end
|
115
|
+
class_name = output ? "Google::Protobuf::Map" : "Hash"
|
116
|
+
if key_field && value_field
|
117
|
+
key_type = field_doc_types key_field, output
|
118
|
+
value_type = field_doc_types value_field, output
|
119
|
+
"#{class_name}{#{key_type} => #{value_type}}"
|
120
|
+
else
|
121
|
+
class_name
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def default_singular_value
|
126
|
+
if @field.message?
|
127
|
+
"{}"
|
128
|
+
elsif @field.enum?
|
129
|
+
# TODO: select the first non-0 enum value
|
130
|
+
":#{@field.enum.values.first.name}"
|
131
|
+
else
|
132
|
+
case @field.type
|
133
|
+
when 1, 2 then "3.5"
|
134
|
+
when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "42"
|
135
|
+
when 9, 12 then "\"hello world\""
|
136
|
+
when 8 then "true"
|
137
|
+
else
|
138
|
+
"Object"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def message_ruby_type message
|
144
|
+
ruby_namespace @api, message.address.join(".")
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2018 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_relative "enum_presenter"
|
18
|
+
require_relative "message_presenter"
|
19
|
+
|
20
|
+
class FilePresenter
|
21
|
+
include NamespaceHelper
|
22
|
+
|
23
|
+
# @param file [Gapic::Schema::File] the file to present
|
24
|
+
def initialize api, file
|
25
|
+
@api = api
|
26
|
+
@file = file
|
27
|
+
end
|
28
|
+
|
29
|
+
def name
|
30
|
+
@file.name
|
31
|
+
end
|
32
|
+
|
33
|
+
def address
|
34
|
+
@file.address
|
35
|
+
end
|
36
|
+
|
37
|
+
def namespace
|
38
|
+
return @file.ruby_package if @file.ruby_package.present?
|
39
|
+
ruby_namespace_for_address address
|
40
|
+
end
|
41
|
+
|
42
|
+
def messages
|
43
|
+
@messages ||= @file.messages.map { |m| MessagePresenter.new @api, m }
|
44
|
+
end
|
45
|
+
|
46
|
+
def enums
|
47
|
+
@enums ||= @file.enums.map { |e| EnumPresenter.new e }
|
48
|
+
end
|
49
|
+
|
50
|
+
def docs_file_path
|
51
|
+
@file.name.gsub ".proto", ".rb"
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 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_relative "file_presenter"
|
18
|
+
require_relative "package_presenter"
|
19
|
+
require_relative "service_presenter"
|
20
|
+
|
21
|
+
class GemPresenter
|
22
|
+
include FilepathHelper
|
23
|
+
include NamespaceHelper
|
24
|
+
|
25
|
+
def initialize api
|
26
|
+
@api = api
|
27
|
+
end
|
28
|
+
|
29
|
+
def packages
|
30
|
+
@packages ||= begin
|
31
|
+
packages = @api.generate_files.map(&:package).uniq.sort
|
32
|
+
packages.map { |p| PackagePresenter.new @api, p }.delete_if(&:empty?)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def services
|
37
|
+
@services ||= begin
|
38
|
+
files = @api.generate_files
|
39
|
+
files.map(&:services).flatten.map { |s| ServicePresenter.new @api, s }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def proto_files
|
44
|
+
@proto_files ||= begin
|
45
|
+
files = @api.files
|
46
|
+
files = files.reject { |f| blacklist_protos.include? f.name }
|
47
|
+
files = files.reject { |f| f.messages.empty? && f.enums.empty? }
|
48
|
+
files.map { |f| FilePresenter.new @api, f }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def address
|
53
|
+
name.split("-").map(&:camelize)
|
54
|
+
end
|
55
|
+
|
56
|
+
def name
|
57
|
+
gem_config :name
|
58
|
+
end
|
59
|
+
|
60
|
+
def namespace
|
61
|
+
gem_config(:namespace) ||
|
62
|
+
fix_namespace(@api, name.split("-").map(&:camelize).join("::"))
|
63
|
+
end
|
64
|
+
|
65
|
+
def title
|
66
|
+
gem_config(:title) ||
|
67
|
+
namespace.split("::").join(" ")
|
68
|
+
end
|
69
|
+
|
70
|
+
def version
|
71
|
+
gem_config(:version) ||
|
72
|
+
"0.0.1"
|
73
|
+
end
|
74
|
+
|
75
|
+
def version_require
|
76
|
+
ruby_file_path @api, version_name_full
|
77
|
+
end
|
78
|
+
|
79
|
+
def version_file_path
|
80
|
+
"#{version_require}.rb"
|
81
|
+
end
|
82
|
+
|
83
|
+
def version_name_full
|
84
|
+
"#{namespace}::VERSION"
|
85
|
+
end
|
86
|
+
|
87
|
+
def authors
|
88
|
+
gem_config(:authors) ||
|
89
|
+
["Google LLC"]
|
90
|
+
end
|
91
|
+
|
92
|
+
def email
|
93
|
+
gem_config(:email) ||
|
94
|
+
"googleapis-packages@google.com"
|
95
|
+
end
|
96
|
+
|
97
|
+
def description
|
98
|
+
gem_config(:description) ||
|
99
|
+
"#{name} is the official library for #{title} API."
|
100
|
+
end
|
101
|
+
|
102
|
+
def summary
|
103
|
+
gem_config(:summary) ||
|
104
|
+
"API Client library for #{title} API"
|
105
|
+
end
|
106
|
+
|
107
|
+
def homepage
|
108
|
+
gem_config(:homepage) ||
|
109
|
+
"https://github.com/googleapis/googleapis"
|
110
|
+
end
|
111
|
+
|
112
|
+
def env_prefix
|
113
|
+
(gem_config(:env_prefix) || name.split("-").last).upcase
|
114
|
+
end
|
115
|
+
|
116
|
+
def iam_dependency?
|
117
|
+
@api.files.map(&:name).include? "google/iam/v1/iam_policy.proto"
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def gem_config key
|
123
|
+
return unless @api.configuration[:gem]
|
124
|
+
|
125
|
+
@api.configuration[:gem][key]
|
126
|
+
end
|
127
|
+
|
128
|
+
def blacklist_protos
|
129
|
+
blacklist = gem_config :blacklist
|
130
|
+
|
131
|
+
return default_blacklist_protos if blacklist.nil?
|
132
|
+
return default_blacklist_protos if blacklist[:protos].nil?
|
133
|
+
|
134
|
+
default_blacklist_protos[:protos]
|
135
|
+
end
|
136
|
+
|
137
|
+
def default_blacklist_protos
|
138
|
+
["google/api/http.proto", "google/protobuf/descriptor.proto"]
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2018 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
|
+
require_relative "field_presenter"
|
20
|
+
|
21
|
+
class MessagePresenter
|
22
|
+
include NamespaceHelper
|
23
|
+
|
24
|
+
def initialize api, message
|
25
|
+
@api = api
|
26
|
+
@message = message
|
27
|
+
end
|
28
|
+
|
29
|
+
def name
|
30
|
+
@message.name
|
31
|
+
end
|
32
|
+
|
33
|
+
def doc_types
|
34
|
+
type_name_full
|
35
|
+
end
|
36
|
+
|
37
|
+
def doc_description
|
38
|
+
@message.docs_leading_comments
|
39
|
+
end
|
40
|
+
|
41
|
+
def default_value
|
42
|
+
"{}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def type_name_full
|
46
|
+
message_ruby_type @message
|
47
|
+
end
|
48
|
+
|
49
|
+
def fields
|
50
|
+
@fields = @message.fields.map { |f| FieldPresenter.new @api, @message, f }
|
51
|
+
end
|
52
|
+
|
53
|
+
def nested_enums
|
54
|
+
@nested_enums ||= @message.nested_enums.map { |e| EnumPresenter.new e }
|
55
|
+
end
|
56
|
+
|
57
|
+
def nested_messages
|
58
|
+
@nested_messages ||= @message.nested_messages.map { |m| MessagePresenter.new @api, m }
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
def message_ruby_type message
|
64
|
+
ruby_namespace @api, message.address.join(".")
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,293 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2018 Google LLC
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require "active_support/inflector"
|
18
|
+
require "gapic/path_template"
|
19
|
+
require_relative "service_presenter"
|
20
|
+
require_relative "field_presenter"
|
21
|
+
require_relative "sample_presenter"
|
22
|
+
|
23
|
+
class MethodPresenter
|
24
|
+
include NamespaceHelper
|
25
|
+
|
26
|
+
def initialize api, method
|
27
|
+
@api = api
|
28
|
+
@method = method
|
29
|
+
end
|
30
|
+
|
31
|
+
def service
|
32
|
+
ServicePresenter.new @api, @method.parent
|
33
|
+
end
|
34
|
+
|
35
|
+
def name
|
36
|
+
ActiveSupport::Inflector.underscore @method.name
|
37
|
+
end
|
38
|
+
|
39
|
+
def kind
|
40
|
+
if client_streaming?
|
41
|
+
if server_streaming?
|
42
|
+
:bidi
|
43
|
+
else
|
44
|
+
:client
|
45
|
+
end
|
46
|
+
elsif server_streaming?
|
47
|
+
:server
|
48
|
+
else
|
49
|
+
:normal
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def doc_description
|
54
|
+
@method.docs_leading_comments
|
55
|
+
end
|
56
|
+
|
57
|
+
def doc_response_type
|
58
|
+
ret = return_type
|
59
|
+
ret = "Gapic::Operation" if lro?
|
60
|
+
if server_streaming?
|
61
|
+
ret = "Enumerable<#{ret}>"
|
62
|
+
elsif paged?
|
63
|
+
paged_type = paged_response_type
|
64
|
+
paged_type = "Gapic::Operation" if paged_type == "Google::Longrunning::Operation"
|
65
|
+
ret = "Gapic::PagedEnumerable<#{paged_type}>"
|
66
|
+
end
|
67
|
+
ret
|
68
|
+
end
|
69
|
+
|
70
|
+
def arguments
|
71
|
+
arguments = @method.input.fields.reject(&:output_only?)
|
72
|
+
arguments.map { |arg| FieldPresenter.new @api, @method.input, arg }
|
73
|
+
end
|
74
|
+
|
75
|
+
def fields
|
76
|
+
@method.input.fields.map { |field| FieldPresenter.new @api, @method.input, field }
|
77
|
+
end
|
78
|
+
|
79
|
+
def fields_with_first_oneof
|
80
|
+
return fields if @method.input.oneof_decl.empty?
|
81
|
+
|
82
|
+
selected_fields = []
|
83
|
+
have_oneof = []
|
84
|
+
|
85
|
+
@method.input.fields.each do |field|
|
86
|
+
idx = field.oneof_index
|
87
|
+
selected_fields << field unless have_oneof.include? idx
|
88
|
+
have_oneof << idx
|
89
|
+
end
|
90
|
+
|
91
|
+
selected_fields.map { |field| FieldPresenter.new @api, @method.input, field }
|
92
|
+
end
|
93
|
+
|
94
|
+
def request_type
|
95
|
+
message_ruby_type @method.input
|
96
|
+
end
|
97
|
+
|
98
|
+
def return_type
|
99
|
+
message_ruby_type @method.output
|
100
|
+
end
|
101
|
+
|
102
|
+
def yields?
|
103
|
+
# Server streaming RCP calls are the only one that does not yield
|
104
|
+
!server_streaming?
|
105
|
+
end
|
106
|
+
|
107
|
+
def yield_doc_description
|
108
|
+
return "Register a callback to be run when an operation is done." if lro?
|
109
|
+
|
110
|
+
"Access the result along with the RPC operation"
|
111
|
+
end
|
112
|
+
|
113
|
+
def yield_params
|
114
|
+
if lro?
|
115
|
+
return [
|
116
|
+
OpenStruct.new(
|
117
|
+
name: "operation",
|
118
|
+
doc_types: "Gapic::Operation"
|
119
|
+
)
|
120
|
+
]
|
121
|
+
end
|
122
|
+
[
|
123
|
+
OpenStruct.new(
|
124
|
+
name: "result",
|
125
|
+
doc_types: return_type
|
126
|
+
),
|
127
|
+
OpenStruct.new(
|
128
|
+
name: "operation",
|
129
|
+
doc_types: "GRPC::ActiveCall::Operation"
|
130
|
+
)
|
131
|
+
]
|
132
|
+
end
|
133
|
+
|
134
|
+
# @api.incode samples and sample_configs are yaml configuration files such as
|
135
|
+
# speech_transcribe_sync_gcs.yaml
|
136
|
+
def samples
|
137
|
+
sample_configs = @api.incode_samples.select do |sample_config|
|
138
|
+
sample_config["service"] == @method.address[0...-1].join(".") &&
|
139
|
+
sample_config["rpc"] == @method.name
|
140
|
+
end
|
141
|
+
sample_configs.map { |sample_config| SamplePresenter.new @api, sample_config }
|
142
|
+
end
|
143
|
+
|
144
|
+
def lro?
|
145
|
+
return paged_response_type == "Google::Longrunning::Operation" if paged?
|
146
|
+
|
147
|
+
message_ruby_type(@method.output) == "Google::Longrunning::Operation"
|
148
|
+
end
|
149
|
+
|
150
|
+
def client_streaming?
|
151
|
+
@method.client_streaming
|
152
|
+
end
|
153
|
+
|
154
|
+
def server_streaming?
|
155
|
+
@method.server_streaming
|
156
|
+
end
|
157
|
+
|
158
|
+
def paged?
|
159
|
+
return false if server_streaming? # Cannot page a streaming response
|
160
|
+
paged_request?(@method.input) && paged_response?(@method.output)
|
161
|
+
end
|
162
|
+
|
163
|
+
def paged_response_type
|
164
|
+
return nil unless paged_response? @method.output
|
165
|
+
|
166
|
+
repeated_field = @method.output.fields.find do |f|
|
167
|
+
f.label == Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED &&
|
168
|
+
f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE
|
169
|
+
end
|
170
|
+
message_ruby_type repeated_field.message
|
171
|
+
end
|
172
|
+
|
173
|
+
##
|
174
|
+
#
|
175
|
+
# @return [Array<String>] The segment key names.
|
176
|
+
#
|
177
|
+
def routing_params
|
178
|
+
segments = Gapic::PathTemplate.parse method_path
|
179
|
+
segments.select { |s| s.is_a? Gapic::PathTemplate::Segment }.map(&:name)
|
180
|
+
end
|
181
|
+
|
182
|
+
def routing_params?
|
183
|
+
routing_params.any?
|
184
|
+
end
|
185
|
+
|
186
|
+
def grpc_service_config
|
187
|
+
if @api.grpc_service_config&.service_method_level_configs&.key?(service.grpc_full_name) &&
|
188
|
+
@api.grpc_service_config.service_method_level_configs[service.grpc_full_name]&.key?(grpc_method_name)
|
189
|
+
@api.grpc_service_config.service_method_level_configs[service.grpc_full_name][grpc_method_name]
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def grpc_method_name
|
194
|
+
@method.name
|
195
|
+
end
|
196
|
+
|
197
|
+
protected
|
198
|
+
|
199
|
+
def message_ruby_type message
|
200
|
+
ruby_namespace @api, message.address.join(".")
|
201
|
+
end
|
202
|
+
|
203
|
+
def doc_types_for arg
|
204
|
+
if arg.message?
|
205
|
+
"#{message_ruby_type arg.message} | Hash"
|
206
|
+
elsif arg.enum?
|
207
|
+
# TODO: handle when arg message is nil and enum is the type
|
208
|
+
message_ruby_type arg.enum
|
209
|
+
else
|
210
|
+
case arg.type
|
211
|
+
when 1, 2 then "Float"
|
212
|
+
when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "Integer"
|
213
|
+
when 9, 12 then "String"
|
214
|
+
when 8 then "Boolean"
|
215
|
+
else
|
216
|
+
"Object"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def doc_desc_for arg
|
222
|
+
return nil if arg.docs.leading_comments.empty?
|
223
|
+
|
224
|
+
arg.docs.leading_comments
|
225
|
+
end
|
226
|
+
|
227
|
+
def default_value_for arg
|
228
|
+
if arg.message?
|
229
|
+
"{}"
|
230
|
+
elsif arg.enum?
|
231
|
+
# TODO: select the first non-0 enum value
|
232
|
+
# ":ENUM"
|
233
|
+
arg.enum.values.first
|
234
|
+
else
|
235
|
+
case arg.type
|
236
|
+
when 1, 2 then "3.14"
|
237
|
+
when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "42"
|
238
|
+
when 9, 12 then "\"hello world\""
|
239
|
+
when 8 then "true"
|
240
|
+
else
|
241
|
+
"Object"
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def method_path
|
247
|
+
return "" if @method.http.nil?
|
248
|
+
|
249
|
+
method = [
|
250
|
+
@method.http.get, @method.http.post, @method.http.put,
|
251
|
+
@method.http.patch, @method.http.delete
|
252
|
+
].find { |x| !x.empty? }
|
253
|
+
return method unless method.nil?
|
254
|
+
|
255
|
+
return @method.http.custom.path unless @method.http.custom.nil?
|
256
|
+
end
|
257
|
+
|
258
|
+
def paged_request? request
|
259
|
+
page_token = request.fields.find do |f|
|
260
|
+
f.name == "page_token" && f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
|
261
|
+
end
|
262
|
+
return false if page_token.nil?
|
263
|
+
|
264
|
+
page_size_types = [
|
265
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT32,
|
266
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT64
|
267
|
+
]
|
268
|
+
page_size = request.fields.find do |f|
|
269
|
+
f.name == "page_size" && page_size_types.include?(f.type)
|
270
|
+
end
|
271
|
+
return false if page_size.nil?
|
272
|
+
|
273
|
+
true
|
274
|
+
end
|
275
|
+
|
276
|
+
def paged_response? response
|
277
|
+
next_page_token = response.fields.find do |f|
|
278
|
+
f.name == "next_page_token" && f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
|
279
|
+
end
|
280
|
+
return false if next_page_token.nil?
|
281
|
+
|
282
|
+
repeated_field = response.fields.find do |f|
|
283
|
+
f.label == Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED &&
|
284
|
+
f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE
|
285
|
+
end
|
286
|
+
return false if repeated_field.nil?
|
287
|
+
|
288
|
+
# We want to make sure the first repeated field is also has the lowest field number,
|
289
|
+
# but the google-protobuf gem sorts fields by number, so we lose the original order.
|
290
|
+
|
291
|
+
true
|
292
|
+
end
|
293
|
+
end
|