contrast-agent 6.3.0 → 6.4.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.
- checksums.yaml +4 -4
- data/.gitignore +0 -3
- data/.simplecov +1 -0
- data/Rakefile +0 -27
- data/lib/contrast/agent/assess/policy/propagation_method.rb +0 -2
- data/lib/contrast/agent/assess/policy/trigger_method.rb +1 -1
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api/dtm.pb.rb +1 -1
- data/lib/contrast/api/settings.pb.rb +1 -1
- data/lib/contrast/utils/patching/policy/patch_utils.rb +5 -22
- data/lib/contrast.rb +34 -0
- data/lib/protobuf/code_generator.rb +129 -0
- data/lib/protobuf/decoder.rb +28 -0
- data/lib/protobuf/deprecation.rb +117 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +79 -0
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +360 -0
- data/lib/protobuf/descriptors.rb +3 -0
- data/lib/protobuf/encoder.rb +11 -0
- data/lib/protobuf/enum.rb +365 -0
- data/lib/protobuf/exceptions.rb +9 -0
- data/lib/protobuf/field/base_field.rb +380 -0
- data/lib/protobuf/field/base_field_object_definitions.rb +504 -0
- data/lib/protobuf/field/bool_field.rb +64 -0
- data/lib/protobuf/field/bytes_field.rb +67 -0
- data/lib/protobuf/field/double_field.rb +25 -0
- data/lib/protobuf/field/enum_field.rb +56 -0
- data/lib/protobuf/field/field_array.rb +102 -0
- data/lib/protobuf/field/field_hash.rb +122 -0
- data/lib/protobuf/field/fixed32_field.rb +25 -0
- data/lib/protobuf/field/fixed64_field.rb +28 -0
- data/lib/protobuf/field/float_field.rb +43 -0
- data/lib/protobuf/field/int32_field.rb +21 -0
- data/lib/protobuf/field/int64_field.rb +34 -0
- data/lib/protobuf/field/integer_field.rb +23 -0
- data/lib/protobuf/field/message_field.rb +51 -0
- data/lib/protobuf/field/sfixed32_field.rb +27 -0
- data/lib/protobuf/field/sfixed64_field.rb +28 -0
- data/lib/protobuf/field/signed_integer_field.rb +29 -0
- data/lib/protobuf/field/sint32_field.rb +21 -0
- data/lib/protobuf/field/sint64_field.rb +21 -0
- data/lib/protobuf/field/string_field.rb +51 -0
- data/lib/protobuf/field/uint32_field.rb +21 -0
- data/lib/protobuf/field/uint64_field.rb +21 -0
- data/lib/protobuf/field/varint_field.rb +77 -0
- data/lib/protobuf/field.rb +74 -0
- data/lib/protobuf/generators/base.rb +85 -0
- data/lib/protobuf/generators/enum_generator.rb +39 -0
- data/lib/protobuf/generators/extension_generator.rb +27 -0
- data/lib/protobuf/generators/field_generator.rb +193 -0
- data/lib/protobuf/generators/file_generator.rb +262 -0
- data/lib/protobuf/generators/group_generator.rb +122 -0
- data/lib/protobuf/generators/message_generator.rb +104 -0
- data/lib/protobuf/generators/option_generator.rb +17 -0
- data/lib/protobuf/generators/printable.rb +160 -0
- data/lib/protobuf/generators/service_generator.rb +50 -0
- data/lib/protobuf/lifecycle.rb +33 -0
- data/lib/protobuf/logging.rb +39 -0
- data/lib/protobuf/message/fields.rb +233 -0
- data/lib/protobuf/message/serialization.rb +85 -0
- data/lib/protobuf/message.rb +241 -0
- data/lib/protobuf/optionable.rb +72 -0
- data/lib/protobuf/tasks/compile.rake +80 -0
- data/lib/protobuf/tasks.rb +1 -0
- data/lib/protobuf/varint.rb +20 -0
- data/lib/protobuf/varint_pure.rb +31 -0
- data/lib/protobuf/version.rb +3 -0
- data/lib/protobuf/wire_type.rb +10 -0
- data/lib/protobuf.rb +91 -0
- data/proto/dynamic_discovery.proto +46 -0
- data/proto/google/protobuf/compiler/plugin.proto +183 -0
- data/proto/google/protobuf/descriptor.proto +911 -0
- data/proto/rpc.proto +71 -0
- data/ruby-agent.gemspec +1 -1
- metadata +71 -10
@@ -0,0 +1,262 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'protobuf/generators/base'
|
3
|
+
require 'protobuf/generators/group_generator'
|
4
|
+
|
5
|
+
module Protobuf
|
6
|
+
module Generators
|
7
|
+
class FileGenerator < Base
|
8
|
+
|
9
|
+
attr_reader :output_file
|
10
|
+
|
11
|
+
def initialize(*args)
|
12
|
+
super
|
13
|
+
@output_file = ::CSGoogle::Protobuf::Compiler::CodeGeneratorResponse::File.new(:name => file_name)
|
14
|
+
@extension_fields = Hash.new { |h, k| h[k] = [] }
|
15
|
+
@known_messages = {}
|
16
|
+
@known_enums = {}
|
17
|
+
@dangling_messages = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def file_name
|
21
|
+
convert_filename(descriptor.name, false)
|
22
|
+
end
|
23
|
+
|
24
|
+
def compile
|
25
|
+
run_once(:compile) do
|
26
|
+
map_extensions(descriptor, [descriptor.package])
|
27
|
+
|
28
|
+
print_file_comment
|
29
|
+
print_generic_requires
|
30
|
+
print_import_requires
|
31
|
+
|
32
|
+
print_package do
|
33
|
+
inject_optionable
|
34
|
+
group = GroupGenerator.new(current_indent)
|
35
|
+
group.add_options(descriptor.options) if descriptor.options
|
36
|
+
group.add_enums(descriptor.enum_type, :namespace => [descriptor.package])
|
37
|
+
group.add_message_declarations(descriptor.message_type)
|
38
|
+
group.add_messages(descriptor.message_type, :extension_fields => @extension_fields, :namespace => [descriptor.package])
|
39
|
+
group.add_extended_messages(unknown_extensions)
|
40
|
+
group.add_services(descriptor.service)
|
41
|
+
|
42
|
+
group.add_header(:enum, 'Enum Classes')
|
43
|
+
group.add_header(:message_declaration, 'Message Classes')
|
44
|
+
group.add_header(:options, 'File Options')
|
45
|
+
group.add_header(:message, 'Message Fields')
|
46
|
+
group.add_header(:extended_message, 'Extended Message Fields')
|
47
|
+
group.add_header(:service, 'Service Classes')
|
48
|
+
print group.to_s
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def unknown_extensions
|
55
|
+
@unknown_extensions ||= @extension_fields.map do |message_name, fields|
|
56
|
+
message_klass = modulize(message_name).safe_constantize
|
57
|
+
if message_klass
|
58
|
+
unknown_fields = fields.reject do |field|
|
59
|
+
@known_messages[message_name] && message_klass.get_field(field.name, true)
|
60
|
+
end
|
61
|
+
[message_name, unknown_fields]
|
62
|
+
else
|
63
|
+
[message_name, fields]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def generate_output_file
|
69
|
+
compile
|
70
|
+
output_file.content = to_s
|
71
|
+
output_file
|
72
|
+
end
|
73
|
+
|
74
|
+
# Recursively map out all extensions known in this file.
|
75
|
+
# The key is the type_name of the message being extended, and
|
76
|
+
# the value is an array of field descriptors.
|
77
|
+
#
|
78
|
+
def map_extensions(descriptor, namespaces)
|
79
|
+
if fully_qualified_token?(descriptor.name)
|
80
|
+
fully_qualified_namespace = descriptor.name
|
81
|
+
elsif !(namespace = namespaces.reject(&:empty?).join(".")).empty?
|
82
|
+
fully_qualified_namespace = ".#{namespace}"
|
83
|
+
end
|
84
|
+
# Record all the message descriptor name's we encounter (should be the whole tree).
|
85
|
+
if descriptor.is_a?(::CSGoogle::Protobuf::DescriptorProto)
|
86
|
+
@known_messages[fully_qualified_namespace || descriptor.name] = descriptor
|
87
|
+
elsif descriptor.is_a?(::CSGoogle::Protobuf::EnumDescriptorProto)
|
88
|
+
@known_enums[fully_qualified_namespace || descriptor.name] = descriptor
|
89
|
+
return
|
90
|
+
end
|
91
|
+
|
92
|
+
descriptor.extension.each do |field_descriptor|
|
93
|
+
unless fully_qualified_token?(field_descriptor.name) && fully_qualified_namespace
|
94
|
+
field_descriptor.name = "#{fully_qualified_namespace}.#{field_descriptor.name}"
|
95
|
+
end
|
96
|
+
@extension_fields[field_descriptor.extendee] << field_descriptor
|
97
|
+
end
|
98
|
+
|
99
|
+
[:message_type, :nested_type, :enum_type].each do |type|
|
100
|
+
next unless descriptor.respond_to_has_and_present?(type)
|
101
|
+
|
102
|
+
descriptor.public_send(type).each do |type_descriptor|
|
103
|
+
map_extensions(type_descriptor, (namespaces + [type_descriptor.name]))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def print_file_comment
|
109
|
+
puts "# encoding: utf-8"
|
110
|
+
puts
|
111
|
+
puts "##"
|
112
|
+
puts "# This file is auto-generated. DO NOT EDIT!"
|
113
|
+
puts "#"
|
114
|
+
end
|
115
|
+
|
116
|
+
def print_generic_requires
|
117
|
+
print_require("protobuf")
|
118
|
+
print_require("protobuf/rpc/service") if descriptor.service.count > 0
|
119
|
+
puts
|
120
|
+
end
|
121
|
+
|
122
|
+
def print_import_requires
|
123
|
+
return if descriptor.dependency.empty?
|
124
|
+
|
125
|
+
header "Imports"
|
126
|
+
|
127
|
+
descriptor.dependency.each do |dependency|
|
128
|
+
print_require(convert_filename(dependency), ENV.key?('PB_REQUIRE_RELATIVE'))
|
129
|
+
end
|
130
|
+
|
131
|
+
puts
|
132
|
+
end
|
133
|
+
|
134
|
+
def print_package(&block)
|
135
|
+
namespaces = descriptor.package.split('.')
|
136
|
+
if namespaces.empty? && ENV.key?('PB_ALLOW_DEFAULT_PACKAGE_NAME')
|
137
|
+
namespaces = [File.basename(descriptor.name).sub('.proto', '')]
|
138
|
+
end
|
139
|
+
namespaces.reverse.reduce(block) do |previous, namespace|
|
140
|
+
-> { print_module(namespace, &previous) }
|
141
|
+
end.call
|
142
|
+
end
|
143
|
+
|
144
|
+
def eval_unknown_extensions!
|
145
|
+
@@evaled_dependencies ||= Set.new # rubocop:disable Style/ClassVars
|
146
|
+
@@all_messages ||= {} # rubocop:disable Style/ClassVars
|
147
|
+
@@all_enums ||= {} # rubocop:disable Style/ClassVars
|
148
|
+
|
149
|
+
map_extensions(descriptor, [descriptor.package])
|
150
|
+
@known_messages.each do |name, descriptor|
|
151
|
+
@@all_messages[name] = descriptor
|
152
|
+
end
|
153
|
+
@known_enums.each do |name, descriptor|
|
154
|
+
@@all_enums[name] = descriptor
|
155
|
+
end
|
156
|
+
|
157
|
+
# create package namespace
|
158
|
+
print_package {}
|
159
|
+
eval_code
|
160
|
+
|
161
|
+
unknown_extensions.each do |extendee, fields|
|
162
|
+
eval_dependencies(extendee)
|
163
|
+
fields.each do |field|
|
164
|
+
eval_dependencies(field.type_name)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
group = GroupGenerator.new(0)
|
168
|
+
group.add_extended_messages(unknown_extensions, false)
|
169
|
+
print group.to_s
|
170
|
+
eval_code
|
171
|
+
rescue => e
|
172
|
+
warn "Error loading unknown extensions #{descriptor.name.inspect} error=#{e}"
|
173
|
+
raise e
|
174
|
+
end
|
175
|
+
|
176
|
+
private
|
177
|
+
|
178
|
+
def convert_filename(filename, for_require = true)
|
179
|
+
filename.sub(/\.proto/, (for_require ? '.pb' : '.pb.rb'))
|
180
|
+
end
|
181
|
+
|
182
|
+
def fully_qualified_token?(token)
|
183
|
+
token[0] == '.'
|
184
|
+
end
|
185
|
+
|
186
|
+
def eval_dependencies(name, namespace = nil)
|
187
|
+
name = "#{namespace}.#{name}" if namespace && !fully_qualified_token?(name)
|
188
|
+
return if name.empty? || @@evaled_dependencies.include?(name) || modulize(name).safe_constantize
|
189
|
+
|
190
|
+
# if name = .foo.bar.Baz look for classes / modules named ::Foo::Bar and ::Foo
|
191
|
+
# module == pure namespace (e.g. the descriptor package name)
|
192
|
+
# class == nested messages
|
193
|
+
create_ruby_namespace_heiarchy(name)
|
194
|
+
|
195
|
+
if (message = @@all_messages[name])
|
196
|
+
# Create the blank namespace in case there are nested types
|
197
|
+
eval_message_code(name)
|
198
|
+
|
199
|
+
message.nested_type.each do |nested_type|
|
200
|
+
eval_dependencies(nested_type.name, name) unless nested_type.name.empty?
|
201
|
+
end
|
202
|
+
message.field.each do |field|
|
203
|
+
eval_dependencies(field.type_name, name) unless field.type_name.empty?
|
204
|
+
end
|
205
|
+
message.enum_type.each do |enum_type|
|
206
|
+
eval_dependencies(enum_type.name, name)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Check @@evaled_dependencies again in case there was a dependency
|
210
|
+
# loop that already loaded this message
|
211
|
+
return if @@evaled_dependencies.include?(name)
|
212
|
+
eval_message_code(name, message.field)
|
213
|
+
@@evaled_dependencies << name
|
214
|
+
|
215
|
+
elsif (enum = @@all_enums[name])
|
216
|
+
# Check @@evaled_dependencies again in case there was a dependency
|
217
|
+
# loop that already loaded this enum
|
218
|
+
return if @@evaled_dependencies.include?(name)
|
219
|
+
namespace = name.split(".")
|
220
|
+
eval_enum_code(enum, namespace[0..-2].join("."))
|
221
|
+
@@evaled_dependencies << name
|
222
|
+
else
|
223
|
+
fail "Error loading unknown dependencies, could not find message or enum #{name.inspect}"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def eval_message_code(fully_qualified_namespace, fields = [])
|
228
|
+
group = GroupGenerator.new(0)
|
229
|
+
group.add_extended_messages({ fully_qualified_namespace => fields }, false)
|
230
|
+
print group.to_s
|
231
|
+
eval_code
|
232
|
+
end
|
233
|
+
|
234
|
+
def eval_enum_code(enum, fully_qualified_namespace)
|
235
|
+
group = GroupGenerator.new(0)
|
236
|
+
group.add_enums([enum], :namespace => [fully_qualified_namespace])
|
237
|
+
print group.to_s
|
238
|
+
eval_code(modulize(fully_qualified_namespace).safe_constantize || Object)
|
239
|
+
end
|
240
|
+
|
241
|
+
def eval_code(context = Object)
|
242
|
+
warn "#{context.inspect}.module_eval #{print_contents.inspect}" if ENV['PB_DEBUG']
|
243
|
+
context.module_eval print_contents.to_s
|
244
|
+
@io.truncate(0)
|
245
|
+
@io.rewind
|
246
|
+
end
|
247
|
+
|
248
|
+
def create_ruby_namespace_heiarchy(namespace)
|
249
|
+
loop do
|
250
|
+
namespace, _match, _tail = namespace.rpartition(".")
|
251
|
+
break if namespace.empty?
|
252
|
+
eval_dependencies(namespace)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def inject_optionable
|
257
|
+
return if descriptor.package.empty? && !ENV.key?('PB_ALLOW_DEFAULT_PACKAGE_NAME')
|
258
|
+
puts "::Protobuf::Optionable.inject(self) { ::CSGoogle::Protobuf::FileOptions }"
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'protobuf/generators/enum_generator'
|
2
|
+
require 'protobuf/generators/extension_generator'
|
3
|
+
require 'protobuf/generators/field_generator'
|
4
|
+
require 'protobuf/generators/message_generator'
|
5
|
+
require 'protobuf/generators/option_generator'
|
6
|
+
require 'protobuf/generators/service_generator'
|
7
|
+
|
8
|
+
module Protobuf
|
9
|
+
module Generators
|
10
|
+
class GroupGenerator
|
11
|
+
include ::Protobuf::Generators::Printable
|
12
|
+
|
13
|
+
attr_reader :groups, :indent_level
|
14
|
+
attr_writer :order
|
15
|
+
|
16
|
+
def initialize(indent_level = 0)
|
17
|
+
@groups = Hash.new { |h, k| h[k] = [] }
|
18
|
+
@headers = {}
|
19
|
+
@comments = {}
|
20
|
+
@handlers = {}
|
21
|
+
@indent_level = indent_level
|
22
|
+
@order = [:enum, :message_declaration, :options, :message, :extended_message, :service]
|
23
|
+
init_printer(indent_level)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_options(option_descriptor)
|
27
|
+
@groups[:options] << OptionGenerator.new(option_descriptor, indent_level)
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_enums(enum_descriptors, options)
|
31
|
+
enum_descriptors.each do |enum_descriptor|
|
32
|
+
@groups[:enum] << EnumGenerator.new(enum_descriptor, indent_level, options)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_comment(type, message)
|
37
|
+
@comments[type] = message
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_extended_messages(extended_messages, skip_empty_fields = true)
|
41
|
+
extended_messages.each do |message_type, field_descriptors|
|
42
|
+
next if skip_empty_fields && field_descriptors.empty?
|
43
|
+
@groups[:extended_message] << ExtensionGenerator.new(message_type, field_descriptors, indent_level)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_extension_fields(field_descriptors)
|
48
|
+
field_descriptors.each do |field_descriptor|
|
49
|
+
@groups[:extension_field] << FieldGenerator.new(field_descriptor, nil, indent_level)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def add_extension_ranges(extension_ranges, &item_handler)
|
54
|
+
@groups[:extension_range] = extension_ranges
|
55
|
+
@handlers[:extension_range] = item_handler
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_header(type, message)
|
59
|
+
@headers[type] = message
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_message_declarations(descriptors)
|
63
|
+
descriptors.each do |descriptor|
|
64
|
+
# elide synthetic map entry messages (we handle map fields differently)
|
65
|
+
next if descriptor.options.try(:map_entry?) { false }
|
66
|
+
@groups[:message_declaration] << MessageGenerator.new(descriptor, indent_level, :declaration => true)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_message_fields(field_descriptors, msg_descriptor)
|
71
|
+
field_descriptors.each do |field_descriptor|
|
72
|
+
@groups[:field] << FieldGenerator.new(field_descriptor, msg_descriptor, indent_level)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def add_messages(descriptors, options = {})
|
77
|
+
descriptors.each do |descriptor|
|
78
|
+
# elide synthetic map entry message (we handle map fields differently)
|
79
|
+
next if descriptor.options.try(:map_entry?) { false }
|
80
|
+
@groups[:message] << MessageGenerator.new(descriptor, indent_level, options)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def add_services(service_descriptors)
|
85
|
+
service_descriptors.each do |service_descriptor|
|
86
|
+
@groups[:service] << ServiceGenerator.new(service_descriptor, indent_level)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def compile
|
91
|
+
@order.each do |type|
|
92
|
+
items = @groups[type]
|
93
|
+
next if items.empty?
|
94
|
+
|
95
|
+
item_handler = @handlers[type]
|
96
|
+
|
97
|
+
item_header = @headers[type]
|
98
|
+
header(item_header) if item_header
|
99
|
+
|
100
|
+
item_comment = @comments[type]
|
101
|
+
comment(item_comment) if item_comment
|
102
|
+
|
103
|
+
items.each do |item|
|
104
|
+
if item_handler
|
105
|
+
puts item_handler.call(item)
|
106
|
+
else
|
107
|
+
print item.to_s
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
puts if type == :message_declaration || type == :options
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def to_s
|
116
|
+
compile
|
117
|
+
print_contents
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'protobuf/generators/base'
|
2
|
+
require 'protobuf/generators/group_generator'
|
3
|
+
|
4
|
+
module Protobuf
|
5
|
+
module Generators
|
6
|
+
class MessageGenerator < Base
|
7
|
+
|
8
|
+
def initialize(descriptor, indent_level, options = {})
|
9
|
+
super
|
10
|
+
@only_declarations = options.fetch(:declaration) { false }
|
11
|
+
@extension_fields = options.fetch(:extension_fields) { {} }
|
12
|
+
end
|
13
|
+
|
14
|
+
def compile
|
15
|
+
run_once(:compile) do
|
16
|
+
if @only_declarations
|
17
|
+
compile_declaration
|
18
|
+
else
|
19
|
+
compile_message
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def compile_declaration
|
25
|
+
run_once(:compile_declaration) do
|
26
|
+
if printable?
|
27
|
+
print_class(descriptor.name, :message) do
|
28
|
+
group = GroupGenerator.new(current_indent)
|
29
|
+
group.add_enums(descriptor.enum_type, :namespace => type_namespace)
|
30
|
+
group.add_message_declarations(descriptor.nested_type)
|
31
|
+
print group.to_s
|
32
|
+
end
|
33
|
+
else
|
34
|
+
print_class(descriptor.name, :message)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def compile_message
|
40
|
+
run_once(:compile_message) do
|
41
|
+
if printable?
|
42
|
+
print_class(descriptor.name, nil) do
|
43
|
+
group = GroupGenerator.new(current_indent)
|
44
|
+
group.add_messages(descriptor.nested_type, :extension_fields => @extension_fields, :namespace => type_namespace)
|
45
|
+
group.add_comment(:options, 'Message Options')
|
46
|
+
group.add_options(descriptor.options) if options?
|
47
|
+
group.add_message_fields(descriptor.field, descriptor)
|
48
|
+
self.class.validate_tags(fully_qualified_type_namespace, descriptor.field.map(&:number))
|
49
|
+
|
50
|
+
group.add_comment(:extension_range, 'Extension Fields')
|
51
|
+
group.add_extension_ranges(descriptor.extension_range) do |extension_range|
|
52
|
+
"extensions #{extension_range.start}...#{extension_range.end}"
|
53
|
+
end
|
54
|
+
|
55
|
+
group.add_extension_fields(message_extension_fields)
|
56
|
+
|
57
|
+
group.order = [:message, :options, :field, :extension_range, :extension_field]
|
58
|
+
print group.to_s
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def extensions?
|
67
|
+
!message_extension_fields.empty?
|
68
|
+
end
|
69
|
+
|
70
|
+
def fields?
|
71
|
+
descriptor.field.count > 0
|
72
|
+
end
|
73
|
+
|
74
|
+
def options?
|
75
|
+
descriptor.options
|
76
|
+
end
|
77
|
+
|
78
|
+
def nested_enums?
|
79
|
+
descriptor.enum_type.count > 0
|
80
|
+
end
|
81
|
+
|
82
|
+
def nested_messages?
|
83
|
+
descriptor.nested_type.count > 0
|
84
|
+
end
|
85
|
+
|
86
|
+
def nested_types?
|
87
|
+
nested_enums? || nested_messages?
|
88
|
+
end
|
89
|
+
|
90
|
+
def printable?
|
91
|
+
if @only_declarations
|
92
|
+
nested_types?
|
93
|
+
else
|
94
|
+
fields? || nested_messages? || extensions? || options?
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def message_extension_fields
|
99
|
+
@extension_fields.fetch(fully_qualified_type_namespace) { [] }
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'protobuf/generators/base'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Generators
|
5
|
+
class OptionGenerator < Base
|
6
|
+
def compile
|
7
|
+
run_once(:compile) do
|
8
|
+
descriptor.each_field.map do |field, value|
|
9
|
+
next unless descriptor.field?(field.name)
|
10
|
+
serialized_value = serialize_value(value)
|
11
|
+
puts "set_option #{field.fully_qualified_name.inspect}, #{serialized_value}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
module Protobuf
|
2
|
+
module Generators
|
3
|
+
module Printable
|
4
|
+
|
5
|
+
PARENT_CLASS_MESSAGE = "::Protobuf::Message".freeze
|
6
|
+
PARENT_CLASS_ENUM = "::Protobuf::Enum".freeze
|
7
|
+
PARENT_CLASS_SERVICE = "::Protobuf::Rpc::Service".freeze
|
8
|
+
|
9
|
+
# Initialize the printer.
|
10
|
+
# Must be called by any class/module that includes the Printable module.
|
11
|
+
#
|
12
|
+
def init_printer(indent_level)
|
13
|
+
@io = ::StringIO.new
|
14
|
+
self.current_indent = indent_level.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
attr_accessor :current_indent
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Print a one-line comment.
|
24
|
+
#
|
25
|
+
def comment(message)
|
26
|
+
puts "# #{message}"
|
27
|
+
end
|
28
|
+
|
29
|
+
# Print a "header" comment.
|
30
|
+
#
|
31
|
+
# header("Lorem ipsum dolor")
|
32
|
+
# ##
|
33
|
+
# # Lorem ipsum dolor
|
34
|
+
# #
|
35
|
+
def header(message)
|
36
|
+
puts
|
37
|
+
puts "##"
|
38
|
+
puts "# #{message}"
|
39
|
+
puts "#"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Increase the indent level. An outdent will only occur if given a block
|
43
|
+
# (after the block is finished).
|
44
|
+
#
|
45
|
+
def indent
|
46
|
+
self.current_indent += 1
|
47
|
+
yield
|
48
|
+
outdent
|
49
|
+
end
|
50
|
+
|
51
|
+
# Take a string and upcase the first character of each namespace.
|
52
|
+
# Due to the nature of varying standards about how class/modules are named
|
53
|
+
# (e.g. CamelCase, Underscore_Case, SCREAMING_SNAKE_CASE), we only want
|
54
|
+
# to capitalize the first character to ensure ruby will treat the value
|
55
|
+
# as a constant. Otherwise we do not attempt to change the
|
56
|
+
# token's definition.
|
57
|
+
#
|
58
|
+
# modulize("foo.bar.Baz") -> "::Foo::Bar::Baz"
|
59
|
+
# modulize("foo.bar.baz") -> "::Foo::Bar::Baz"
|
60
|
+
# modulize("foo.bar.BAZ") -> "::Foo::Bar::BAZ"
|
61
|
+
#
|
62
|
+
def modulize(name)
|
63
|
+
name = name.gsub(/\./, '::')
|
64
|
+
name = name.gsub(/(^(?:::)?[a-z]|::[a-z])/, &:upcase)
|
65
|
+
name
|
66
|
+
end
|
67
|
+
|
68
|
+
# Decrease the indent level. Cannot be negative.
|
69
|
+
#
|
70
|
+
def outdent
|
71
|
+
self.current_indent -= 1 unless current_indent.zero?
|
72
|
+
end
|
73
|
+
|
74
|
+
# Return the parent class for a given type.
|
75
|
+
# Valid types are :message, :enum, and :service, otherwise an error
|
76
|
+
# will be thrown.
|
77
|
+
#
|
78
|
+
def parent_class(type)
|
79
|
+
case type
|
80
|
+
when :message then
|
81
|
+
PARENT_CLASS_MESSAGE
|
82
|
+
when :enum then
|
83
|
+
PARENT_CLASS_ENUM
|
84
|
+
when :service then
|
85
|
+
PARENT_CLASS_SERVICE
|
86
|
+
else
|
87
|
+
fail "Unknown parent class type #{type}: #{caller[0..5].join("\n")}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Print a class or module block, indicated by type.
|
92
|
+
# If a class, can be given a parent class to inherit from.
|
93
|
+
# If a block is given, call the block from within an indent block.
|
94
|
+
# Otherwise, end the block on the same line.
|
95
|
+
#
|
96
|
+
def print_block(name, parent_klass, type)
|
97
|
+
name = modulize(name)
|
98
|
+
block_def = "#{type} #{name}"
|
99
|
+
block_def += " < #{parent_class(parent_klass)}" if parent_klass
|
100
|
+
|
101
|
+
if block_given?
|
102
|
+
puts block_def
|
103
|
+
indent { yield }
|
104
|
+
puts "end"
|
105
|
+
puts
|
106
|
+
else
|
107
|
+
block_def += "; end"
|
108
|
+
puts block_def
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Use print_block to print a class, with optional parent class
|
113
|
+
# to inherit from. Accepts a block for use with print_block.
|
114
|
+
#
|
115
|
+
def print_class(name, parent_klass, &block)
|
116
|
+
print_block(name, parent_klass, :class, &block)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Use print_block to print a module.
|
120
|
+
# Accepts a block for use with print_block.
|
121
|
+
#
|
122
|
+
def print_module(name, &block)
|
123
|
+
print_block(name, nil, :module, &block)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Print a file require.
|
127
|
+
#
|
128
|
+
# print_require('foo/bar/baz') -> "require 'foo/bar/baz'"
|
129
|
+
#
|
130
|
+
def print_require(file, relative = false)
|
131
|
+
puts "require#{'_relative' if relative} '#{file}'"
|
132
|
+
end
|
133
|
+
|
134
|
+
# Puts the given message prefixed by the indent level.
|
135
|
+
# If no message is given print a newline.
|
136
|
+
#
|
137
|
+
def puts(message = nil)
|
138
|
+
if message
|
139
|
+
@io.puts((" " * current_indent) + message)
|
140
|
+
else
|
141
|
+
@io.puts
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Print the given message raw, no indent.
|
146
|
+
#
|
147
|
+
def print(contents)
|
148
|
+
@io.print(contents)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Returns the contents of the underlying StringIO object.
|
152
|
+
#
|
153
|
+
def print_contents
|
154
|
+
@io.rewind
|
155
|
+
@io.read
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|