protobuf-cucumber 3.10.4
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 +7 -0
- data/.gitignore +21 -0
- data/.rubocop.yml +70 -0
- data/.rubocop_todo.yml +145 -0
- data/.travis.yml +40 -0
- data/.yardopts +5 -0
- data/CHANGES.md +344 -0
- data/CONTRIBUTING.md +16 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +64 -0
- data/bin/protoc-gen-ruby +22 -0
- data/bin/rpc_server +5 -0
- data/install-protobuf.sh +28 -0
- data/lib/protobuf.rb +129 -0
- data/lib/protobuf/cli.rb +257 -0
- data/lib/protobuf/code_generator.rb +120 -0
- data/lib/protobuf/decoder.rb +28 -0
- data/lib/protobuf/deprecation.rb +117 -0
- data/lib/protobuf/descriptors.rb +3 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +62 -0
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +301 -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.rb +74 -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 +78 -0
- data/lib/protobuf/field/double_field.rb +25 -0
- data/lib/protobuf/field/enum_field.rb +61 -0
- data/lib/protobuf/field/field_array.rb +104 -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/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.rb +260 -0
- data/lib/protobuf/message/fields.rb +233 -0
- data/lib/protobuf/message/serialization.rb +85 -0
- data/lib/protobuf/optionable.rb +70 -0
- data/lib/protobuf/rpc/buffer.rb +78 -0
- data/lib/protobuf/rpc/client.rb +140 -0
- data/lib/protobuf/rpc/connectors/base.rb +221 -0
- data/lib/protobuf/rpc/connectors/ping.rb +89 -0
- data/lib/protobuf/rpc/connectors/socket.rb +78 -0
- data/lib/protobuf/rpc/connectors/zmq.rb +319 -0
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +50 -0
- data/lib/protobuf/rpc/env.rb +60 -0
- data/lib/protobuf/rpc/error.rb +28 -0
- data/lib/protobuf/rpc/error/client_error.rb +31 -0
- data/lib/protobuf/rpc/error/server_error.rb +43 -0
- data/lib/protobuf/rpc/middleware.rb +25 -0
- data/lib/protobuf/rpc/middleware/exception_handler.rb +40 -0
- data/lib/protobuf/rpc/middleware/logger.rb +95 -0
- data/lib/protobuf/rpc/middleware/request_decoder.rb +79 -0
- data/lib/protobuf/rpc/middleware/response_encoder.rb +83 -0
- data/lib/protobuf/rpc/middleware/runner.rb +18 -0
- data/lib/protobuf/rpc/rpc.pb.rb +64 -0
- data/lib/protobuf/rpc/rpc_method.rb +16 -0
- data/lib/protobuf/rpc/server.rb +39 -0
- data/lib/protobuf/rpc/servers/socket/server.rb +121 -0
- data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
- data/lib/protobuf/rpc/servers/socket_runner.rb +46 -0
- data/lib/protobuf/rpc/servers/zmq/broker.rb +194 -0
- data/lib/protobuf/rpc/servers/zmq/server.rb +321 -0
- data/lib/protobuf/rpc/servers/zmq/util.rb +48 -0
- data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
- data/lib/protobuf/rpc/servers/zmq_runner.rb +70 -0
- data/lib/protobuf/rpc/service.rb +172 -0
- data/lib/protobuf/rpc/service_directory.rb +261 -0
- data/lib/protobuf/rpc/service_dispatcher.rb +45 -0
- data/lib/protobuf/rpc/service_filters.rb +250 -0
- data/lib/protobuf/rpc/stat.rb +119 -0
- data/lib/protobuf/socket.rb +21 -0
- data/lib/protobuf/tasks.rb +1 -0
- data/lib/protobuf/tasks/compile.rake +80 -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/zmq.rb +21 -0
- data/profile.html +5103 -0
- data/proto/dynamic_discovery.proto +44 -0
- data/proto/google/protobuf/compiler/plugin.proto +147 -0
- data/proto/google/protobuf/descriptor.proto +779 -0
- data/proto/rpc.proto +69 -0
- data/protobuf-cucumber.gemspec +57 -0
- data/spec/benchmark/tasks.rb +143 -0
- data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
- data/spec/encoding/all_types_spec.rb +103 -0
- data/spec/encoding/extreme_values_spec.rb +0 -0
- data/spec/functional/class_inheritance_spec.rb +52 -0
- data/spec/functional/code_generator_spec.rb +58 -0
- data/spec/functional/socket_server_spec.rb +59 -0
- data/spec/functional/zmq_server_spec.rb +105 -0
- data/spec/lib/protobuf/cli_spec.rb +317 -0
- data/spec/lib/protobuf/code_generator_spec.rb +87 -0
- data/spec/lib/protobuf/enum_spec.rb +307 -0
- data/spec/lib/protobuf/field/bool_field_spec.rb +91 -0
- data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/enum_field_spec.rb +44 -0
- data/spec/lib/protobuf/field/field_array_spec.rb +105 -0
- data/spec/lib/protobuf/field/field_hash_spec.rb +168 -0
- data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/float_field_spec.rb +90 -0
- data/spec/lib/protobuf/field/int32_field_spec.rb +120 -0
- data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/message_field_spec.rb +132 -0
- data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/string_field_spec.rb +79 -0
- data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field_spec.rb +192 -0
- data/spec/lib/protobuf/generators/base_spec.rb +154 -0
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +82 -0
- data/spec/lib/protobuf/generators/extension_generator_spec.rb +42 -0
- data/spec/lib/protobuf/generators/field_generator_spec.rb +197 -0
- data/spec/lib/protobuf/generators/file_generator_spec.rb +119 -0
- data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
- data/spec/lib/protobuf/generators/service_generator_spec.rb +99 -0
- data/spec/lib/protobuf/lifecycle_spec.rb +94 -0
- data/spec/lib/protobuf/message_spec.rb +944 -0
- data/spec/lib/protobuf/optionable_spec.rb +265 -0
- data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
- data/spec/lib/protobuf/rpc/connectors/base_spec.rb +226 -0
- data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +69 -0
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +34 -0
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +110 -0
- data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
- data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
- data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
- data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +91 -0
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
- data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +43 -0
- data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
- data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
- data/spec/lib/protobuf/rpc/service_directory_spec.rb +293 -0
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +35 -0
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +517 -0
- data/spec/lib/protobuf/rpc/service_spec.rb +162 -0
- data/spec/lib/protobuf/rpc/stat_spec.rb +101 -0
- data/spec/lib/protobuf/varint_spec.rb +29 -0
- data/spec/lib/protobuf_spec.rb +105 -0
- data/spec/spec_helper.rb +42 -0
- data/spec/support/all.rb +6 -0
- data/spec/support/packed_field.rb +23 -0
- data/spec/support/protos/all_types.data.bin +0 -0
- data/spec/support/protos/all_types.data.txt +119 -0
- data/spec/support/protos/enum.pb.rb +63 -0
- data/spec/support/protos/enum.proto +37 -0
- data/spec/support/protos/extreme_values.data.bin +0 -0
- data/spec/support/protos/google_unittest.bin +0 -0
- data/spec/support/protos/google_unittest.pb.rb +798 -0
- data/spec/support/protos/google_unittest.proto +884 -0
- data/spec/support/protos/google_unittest_custom_options.bin +0 -0
- data/spec/support/protos/google_unittest_custom_options.pb.rb +361 -0
- data/spec/support/protos/google_unittest_custom_options.proto +424 -0
- data/spec/support/protos/google_unittest_import.pb.rb +55 -0
- data/spec/support/protos/google_unittest_import.proto +73 -0
- data/spec/support/protos/google_unittest_import_public.pb.rb +31 -0
- data/spec/support/protos/google_unittest_import_public.proto +41 -0
- data/spec/support/protos/map-test.bin +157 -0
- data/spec/support/protos/map-test.pb.rb +85 -0
- data/spec/support/protos/map-test.proto +68 -0
- data/spec/support/protos/multi_field_extensions.pb.rb +59 -0
- data/spec/support/protos/multi_field_extensions.proto +35 -0
- data/spec/support/protos/resource.pb.rb +172 -0
- data/spec/support/protos/resource.proto +137 -0
- data/spec/support/resource_service.rb +23 -0
- data/spec/support/server.rb +65 -0
- data/spec/support/test_app_file.rb +2 -0
- data/varint_prof.rb +82 -0
- metadata +579 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
module Protobuf
|
2
|
+
class Lifecycle
|
3
|
+
class << self
|
4
|
+
def register(event_name)
|
5
|
+
fail "Lifecycle register must have a block" unless block_given?
|
6
|
+
event_name = normalized_event_name(event_name)
|
7
|
+
|
8
|
+
::ActiveSupport::Notifications.subscribe(event_name) do |_name, _start, _finish, _id, args|
|
9
|
+
yield(*args)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
alias :on register
|
13
|
+
|
14
|
+
def trigger(event_name, *args)
|
15
|
+
event_name = normalized_event_name(event_name)
|
16
|
+
|
17
|
+
::ActiveSupport::Notifications.instrument(event_name, args)
|
18
|
+
end
|
19
|
+
|
20
|
+
replacement = ::ActiveSupport::Notifications
|
21
|
+
|
22
|
+
::Protobuf.deprecator.deprecate_methods(
|
23
|
+
self,
|
24
|
+
:register => "#{replacement}.#{replacement.method(:subscribe).name}".to_sym,
|
25
|
+
:trigger => "#{replacement}.#{replacement.method(:instrument).name}".to_sym,
|
26
|
+
)
|
27
|
+
|
28
|
+
def normalized_event_name(event_name)
|
29
|
+
event_name.to_s.downcase
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Logging
|
5
|
+
def self.initialize_logger(log_target = $stdout, log_level = ::Logger::INFO)
|
6
|
+
@logger = Logger.new(log_target)
|
7
|
+
@logger.level = log_level
|
8
|
+
@logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.logger
|
12
|
+
defined?(@logger) ? @logger : initialize_logger
|
13
|
+
end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
attr_writer :logger
|
17
|
+
end
|
18
|
+
|
19
|
+
def logger
|
20
|
+
::Protobuf::Logging.logger
|
21
|
+
end
|
22
|
+
|
23
|
+
def log_exception(ex)
|
24
|
+
logger.error { ex.message }
|
25
|
+
logger.error { ex.backtrace[0..5].join("\n") }
|
26
|
+
logger.debug { ex.backtrace.join("\n") }
|
27
|
+
end
|
28
|
+
|
29
|
+
def log_signature
|
30
|
+
@_log_signature ||= "[#{self.class == Class ? name : self.class.name}]"
|
31
|
+
end
|
32
|
+
|
33
|
+
def sign_message(message)
|
34
|
+
"#{log_signature} #{message}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Inspired by [mperham](https://github.com/mperham/sidekiq)
|
@@ -0,0 +1,260 @@
|
|
1
|
+
require 'protobuf/message/fields'
|
2
|
+
require 'protobuf/message/serialization'
|
3
|
+
require 'protobuf/varint'
|
4
|
+
|
5
|
+
module Protobuf
|
6
|
+
class Message
|
7
|
+
|
8
|
+
##
|
9
|
+
# Includes & Extends
|
10
|
+
#
|
11
|
+
|
12
|
+
extend ::Protobuf::Message::Fields
|
13
|
+
include ::Protobuf::Message::Serialization
|
14
|
+
::Protobuf::Optionable.inject(self) { ::Google::Protobuf::MessageOptions }
|
15
|
+
|
16
|
+
##
|
17
|
+
# Class Methods
|
18
|
+
#
|
19
|
+
|
20
|
+
def self.to_json
|
21
|
+
name
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.from_json(json)
|
25
|
+
fields = normalize_json(JSON.parse(json))
|
26
|
+
new(fields)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.normalize_json(ob)
|
30
|
+
case ob
|
31
|
+
when Array
|
32
|
+
ob.map { |value| normalize_json(value) }
|
33
|
+
when Hash
|
34
|
+
Hash[*ob.flat_map { |key, value| [key.underscore, normalize_json(value)] }]
|
35
|
+
else
|
36
|
+
ob
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Constructor
|
42
|
+
#
|
43
|
+
|
44
|
+
def initialize(fields = {})
|
45
|
+
@values = {}
|
46
|
+
fields.to_hash.each do |name, value|
|
47
|
+
set_field(name, value, true)
|
48
|
+
end
|
49
|
+
|
50
|
+
yield self if block_given?
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Public Instance Methods
|
55
|
+
#
|
56
|
+
|
57
|
+
def clear!
|
58
|
+
@values.delete_if do |_, value|
|
59
|
+
if value.is_a?(::Protobuf::Field::FieldArray) || value.is_a?(::Protobuf::Field::FieldHash)
|
60
|
+
value.clear
|
61
|
+
false
|
62
|
+
else
|
63
|
+
true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
def clone
|
70
|
+
copy_to(super, :clone)
|
71
|
+
end
|
72
|
+
|
73
|
+
def dup
|
74
|
+
copy_to(super, :dup)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Iterate over every field, invoking the given block
|
78
|
+
#
|
79
|
+
def each_field
|
80
|
+
return to_enum(:each_field) unless block_given?
|
81
|
+
|
82
|
+
self.class.all_fields.each do |field|
|
83
|
+
value = self[field.name]
|
84
|
+
yield(field, value)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def each_field_for_serialization
|
89
|
+
_protobuf_message_unset_required_field_tags.each do |tag|
|
90
|
+
fail ::Protobuf::SerializationError, "Required field #{self.class.name}##{_protobuf_message_field[tag].name} does not have a value."
|
91
|
+
end
|
92
|
+
|
93
|
+
@values.each_key do |fully_qualified_name|
|
94
|
+
field = _protobuf_message_field[fully_qualified_name]
|
95
|
+
yield(field, field.value_from_values_for_serialization(@values))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def field?(name)
|
100
|
+
field = _protobuf_message_field[name]
|
101
|
+
|
102
|
+
if field
|
103
|
+
field.field?(@values)
|
104
|
+
else
|
105
|
+
false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
alias :respond_to_has? field?
|
109
|
+
::Protobuf.deprecator.define_deprecated_methods(self, :has_field? => :field?)
|
110
|
+
|
111
|
+
def inspect
|
112
|
+
attrs = self.class.fields.map do |field|
|
113
|
+
[field.name, self[field.name].inspect].join('=')
|
114
|
+
end.join(' ')
|
115
|
+
|
116
|
+
"#<#{self.class} #{attrs}>"
|
117
|
+
end
|
118
|
+
|
119
|
+
def respond_to_has_and_present?(key)
|
120
|
+
field = _protobuf_message_field[key]
|
121
|
+
|
122
|
+
if field
|
123
|
+
field.field_and_present?(@values)
|
124
|
+
else
|
125
|
+
false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Return a hash-representation of the given fields for this message type.
|
130
|
+
def to_hash
|
131
|
+
result = {}
|
132
|
+
|
133
|
+
@values.each_key do |field_name|
|
134
|
+
field = _protobuf_message_field[field_name]
|
135
|
+
field.to_message_hash(@values, result)
|
136
|
+
end
|
137
|
+
|
138
|
+
result
|
139
|
+
end
|
140
|
+
|
141
|
+
def to_hash_with_string_keys
|
142
|
+
result = {}
|
143
|
+
|
144
|
+
@values.each_key do |field_name|
|
145
|
+
field = _protobuf_message_field[field_name]
|
146
|
+
field.to_message_hash_with_string_key(@values, result)
|
147
|
+
end
|
148
|
+
|
149
|
+
result
|
150
|
+
end
|
151
|
+
|
152
|
+
def to_json(options = {})
|
153
|
+
to_json_hash(options).to_json(options)
|
154
|
+
end
|
155
|
+
|
156
|
+
# Return a hash-representation of the given fields for this message type that
|
157
|
+
# is safe to convert to JSON.
|
158
|
+
def to_json_hash(options = {})
|
159
|
+
result = {}
|
160
|
+
|
161
|
+
lower_camel_case = options[:lower_camel_case]
|
162
|
+
|
163
|
+
@values.each_key do |field_name|
|
164
|
+
value = self[field_name]
|
165
|
+
field = self.class.get_field(field_name, true)
|
166
|
+
|
167
|
+
# NB: to_json_hash_value should come before json_encode so as to handle
|
168
|
+
# repeated fields without extra logic.
|
169
|
+
hashed_value = if value.respond_to?(:to_json_hash_value) && !field.is_a?(::Protobuf::Field::EnumField)
|
170
|
+
value.to_json_hash_value(options)
|
171
|
+
elsif field.respond_to?(:json_encode)
|
172
|
+
field.json_encode(value)
|
173
|
+
else
|
174
|
+
value
|
175
|
+
end
|
176
|
+
|
177
|
+
key = lower_camel_case ? field.name.to_s.camelize(:lower).to_sym : field.name
|
178
|
+
result[key] = hashed_value
|
179
|
+
end
|
180
|
+
|
181
|
+
result
|
182
|
+
end
|
183
|
+
|
184
|
+
def to_proto
|
185
|
+
self
|
186
|
+
end
|
187
|
+
|
188
|
+
def ==(other)
|
189
|
+
return false unless other.is_a?(self.class)
|
190
|
+
each_field do |field, value|
|
191
|
+
return false unless value == other[field.name]
|
192
|
+
end
|
193
|
+
true
|
194
|
+
end
|
195
|
+
|
196
|
+
def [](name)
|
197
|
+
field = _protobuf_message_field[name]
|
198
|
+
field.value_from_values(@values)
|
199
|
+
rescue # not having a field should be the exceptional state
|
200
|
+
raise if field
|
201
|
+
fail ArgumentError, "invalid field name=#{name.inspect}"
|
202
|
+
end
|
203
|
+
|
204
|
+
def []=(name, value)
|
205
|
+
set_field(name, value, true)
|
206
|
+
end
|
207
|
+
|
208
|
+
def set_field(name, value, ignore_nil_for_repeated, field = nil)
|
209
|
+
field ||= _protobuf_message_field[name]
|
210
|
+
|
211
|
+
if field
|
212
|
+
field.set_field(@values, value, ignore_nil_for_repeated, self)
|
213
|
+
else
|
214
|
+
fail(::Protobuf::FieldNotDefinedError, name) unless ::Protobuf.ignore_unknown_fields?
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
##
|
219
|
+
# Instance Aliases
|
220
|
+
#
|
221
|
+
alias :to_hash_value to_hash
|
222
|
+
alias :to_json_hash_value to_json_hash
|
223
|
+
alias :to_proto_hash to_hash
|
224
|
+
alias :responds_to_has? respond_to_has?
|
225
|
+
alias :respond_to_and_has? respond_to_has?
|
226
|
+
alias :responds_to_and_has? respond_to_has?
|
227
|
+
alias :respond_to_has_present? respond_to_has_and_present?
|
228
|
+
alias :respond_to_and_has_present? respond_to_has_and_present?
|
229
|
+
alias :respond_to_and_has_and_present? respond_to_has_and_present?
|
230
|
+
alias :responds_to_has_present? respond_to_has_and_present?
|
231
|
+
alias :responds_to_and_has_present? respond_to_has_and_present?
|
232
|
+
alias :responds_to_and_has_and_present? respond_to_has_and_present?
|
233
|
+
|
234
|
+
##
|
235
|
+
# Private Instance Methods
|
236
|
+
#
|
237
|
+
|
238
|
+
private
|
239
|
+
|
240
|
+
def copy_to(object, method)
|
241
|
+
duplicate = proc do |obj|
|
242
|
+
case obj
|
243
|
+
when Message, String then obj.__send__(method)
|
244
|
+
else obj
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
object.__send__(:initialize)
|
249
|
+
@values.each do |name, value|
|
250
|
+
if value.is_a?(::Protobuf::Field::FieldArray)
|
251
|
+
object[name].replace(value.map { |v| duplicate.call(v) })
|
252
|
+
else
|
253
|
+
object[name] = duplicate.call(value)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
object
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
260
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
require "set"
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
class Message
|
5
|
+
module Fields
|
6
|
+
|
7
|
+
ACCESSOR_SUFFIXES = ["", "=", "!", "?"].freeze
|
8
|
+
|
9
|
+
def self.extended(other)
|
10
|
+
other.extend(ClassMethods)
|
11
|
+
::Protobuf.deprecator.define_deprecated_methods(
|
12
|
+
other.singleton_class,
|
13
|
+
:get_ext_field_by_name => :get_extension_field,
|
14
|
+
:get_ext_field_by_tag => :get_extension_field,
|
15
|
+
:get_field_by_name => :get_field,
|
16
|
+
:get_field_by_tag => :get_field,
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
def inherited(subclass)
|
22
|
+
inherit_fields!(subclass)
|
23
|
+
subclass.const_set("PROTOBUF_MESSAGE_REQUIRED_FIELD_TAGS", subclass.required_field_tags)
|
24
|
+
subclass.const_set("PROTOBUF_MESSAGE_GET_FIELD", subclass.field_store)
|
25
|
+
subclass.class_eval <<-RUBY, __FILE__, __LINE__
|
26
|
+
def _protobuf_message_field
|
27
|
+
PROTOBUF_MESSAGE_GET_FIELD
|
28
|
+
end
|
29
|
+
|
30
|
+
def _protobuf_message_unset_required_field_tags
|
31
|
+
@_protobuf_message_unset_required_field_tags ||= PROTOBUF_MESSAGE_REQUIRED_FIELD_TAGS.dup
|
32
|
+
end
|
33
|
+
RUBY
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Field Definition Methods
|
38
|
+
#
|
39
|
+
|
40
|
+
# Define an optional field.
|
41
|
+
#
|
42
|
+
def optional(type_class, name, tag, options = {})
|
43
|
+
define_field(:optional, type_class, name, tag, options)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Define a repeated field.
|
47
|
+
#
|
48
|
+
def repeated(type_class, name, tag, options = {})
|
49
|
+
define_field(:repeated, type_class, name, tag, options)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Define a required field.
|
53
|
+
#
|
54
|
+
def required(type_class, name, tag, options = {})
|
55
|
+
required_field_tags << tag
|
56
|
+
define_field(:required, type_class, name, tag, options)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Define a map field.
|
60
|
+
#
|
61
|
+
def map(key_type_class, value_type_class, name, tag, options = {})
|
62
|
+
# manufacture a message that represents the map entry, used for
|
63
|
+
# serialization and deserialization
|
64
|
+
entry_type = Class.new(::Protobuf::Message) do
|
65
|
+
set_option :map_entry, true
|
66
|
+
optional key_type_class, :key, 1
|
67
|
+
optional value_type_class, :value, 2
|
68
|
+
end
|
69
|
+
define_field(:repeated, entry_type, name, tag, options)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Define an extension range.
|
73
|
+
#
|
74
|
+
def extensions(range)
|
75
|
+
extension_ranges << range
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Field Access Methods
|
80
|
+
#
|
81
|
+
def all_fields
|
82
|
+
@all_fields ||= field_store.values.uniq.sort_by(&:tag)
|
83
|
+
end
|
84
|
+
|
85
|
+
def extension_fields
|
86
|
+
@extension_fields ||= all_fields.select(&:extension?)
|
87
|
+
end
|
88
|
+
|
89
|
+
def extension_ranges
|
90
|
+
@extension_ranges ||= []
|
91
|
+
end
|
92
|
+
|
93
|
+
def required_field_tags
|
94
|
+
@required_field_tags ||= []
|
95
|
+
end
|
96
|
+
|
97
|
+
def extension_tag?(tag)
|
98
|
+
tag.respond_to?(:to_i) && get_extension_field(tag).present?
|
99
|
+
end
|
100
|
+
|
101
|
+
def field_store
|
102
|
+
@field_store ||= {}
|
103
|
+
end
|
104
|
+
|
105
|
+
def fields
|
106
|
+
@fields ||= all_fields.reject(&:extension?)
|
107
|
+
end
|
108
|
+
|
109
|
+
def field_tag?(tag, allow_extension = false)
|
110
|
+
tag.respond_to?(:to_i) && get_field(tag, allow_extension).present?
|
111
|
+
end
|
112
|
+
|
113
|
+
def get_extension_field(name_or_tag)
|
114
|
+
field = field_store[name_or_tag]
|
115
|
+
field if field.try(:extension?) { false }
|
116
|
+
end
|
117
|
+
|
118
|
+
def get_field(name_or_tag, allow_extension = false)
|
119
|
+
field = field_store[name_or_tag]
|
120
|
+
|
121
|
+
if field && (allow_extension || !field.extension?)
|
122
|
+
field
|
123
|
+
else
|
124
|
+
nil
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def define_field(rule, type_class, fully_qualified_field_name, tag, options)
|
129
|
+
raise_if_tag_collision(tag, fully_qualified_field_name)
|
130
|
+
raise_if_name_collision(fully_qualified_field_name)
|
131
|
+
|
132
|
+
# Determine appropirate accessor for fields depending on name collisions via extensions:
|
133
|
+
|
134
|
+
# Case 1: Base field = "string_field" and no extensions of the same name
|
135
|
+
# Result:
|
136
|
+
# message.string_field #=> @values["string_field"]
|
137
|
+
# message[:string_field] #=> @values["string_field"]
|
138
|
+
# message['string_field'] #=> @values["string_field"]
|
139
|
+
|
140
|
+
# Case 2: Base field = "string_field" and extension 1 = ".my_package.string_field", extension N = ".package_N.string_field"...
|
141
|
+
# Result:
|
142
|
+
# message.string_field #=> @values["string_field"]
|
143
|
+
# message[:string_field] #=> @values["string_field"]
|
144
|
+
# message['string_field'] #=> @values["string_field"]
|
145
|
+
# message[:'.my_package.string_field'] #=> @values[".my_package.string_field"]
|
146
|
+
# message['.my_package.string_field'] #=> @values[".my_package.string_field"]
|
147
|
+
|
148
|
+
# Case 3: No base field, extension 1 = ".my_package.string_field", extension 2 = ".other_package.string_field", extension N...
|
149
|
+
# Result:
|
150
|
+
# message.string_field #=> raise NoMethodError (no simple accessor allowed)
|
151
|
+
# message[:string_field] #=> raise NoMethodError (no simple accessor allowed)
|
152
|
+
# message['string_field'] #=> raise NoMethodError (no simple accessor allowed)
|
153
|
+
# message[:'.my_package.string_field'] #=> @values[".my_package.string_field"]
|
154
|
+
# message['.my_package.string_field'] #=> @values[".my_package.string_field"]
|
155
|
+
# message[:'.other_package.string_field'] #=> @values[".other_package.string_field"]
|
156
|
+
# message['.other_package.string_field'] #=> @values[".other_package.string_field"]
|
157
|
+
|
158
|
+
# Case 4: No base field, extension = ".my_package.string_field", no other extensions
|
159
|
+
# Result:
|
160
|
+
# message.string_field #=> @values[".my_package.string_field"]
|
161
|
+
# message[:string_field] #=> @values[".my_package.string_field"]
|
162
|
+
# message['string_field'] #=> @values[".my_package.string_field"]
|
163
|
+
# message[:'.my_package.string_field'] #=> @values[".my_package.string_field"]
|
164
|
+
# message[:'.my_package.string_field'] #=> @values[".my_package.string_field"]
|
165
|
+
|
166
|
+
simple_name =
|
167
|
+
if options[:extension]
|
168
|
+
base_name = fully_qualified_field_name.to_s.split('.').last.to_sym
|
169
|
+
if field_store[base_name]
|
170
|
+
# Case 3
|
171
|
+
if field_store[base_name].extension?
|
172
|
+
remove_existing_accessors(base_name)
|
173
|
+
end
|
174
|
+
nil
|
175
|
+
# Case 4
|
176
|
+
else
|
177
|
+
base_name
|
178
|
+
end
|
179
|
+
else
|
180
|
+
# Case 1
|
181
|
+
fully_qualified_field_name
|
182
|
+
end
|
183
|
+
|
184
|
+
field = ::Protobuf::Field.build(self, rule, type_class, fully_qualified_field_name,
|
185
|
+
tag, simple_name, options)
|
186
|
+
field_store[tag] = field
|
187
|
+
field_store[fully_qualified_field_name.to_sym] = field
|
188
|
+
field_store[fully_qualified_field_name.to_s] = field
|
189
|
+
if simple_name && simple_name != fully_qualified_field_name
|
190
|
+
field_store[simple_name.to_sym] = field
|
191
|
+
field_store[simple_name.to_s] = field
|
192
|
+
end
|
193
|
+
# defining a new field for the message will cause cached @all_fields, @extension_fields,
|
194
|
+
# and @fields to be incorrect; reset them
|
195
|
+
@all_fields = @extension_fields = @fields = nil
|
196
|
+
end
|
197
|
+
|
198
|
+
def remove_existing_accessors(accessor)
|
199
|
+
field_store.delete(accessor.to_sym).try(:fully_qualified_name_only!)
|
200
|
+
field_store.delete(accessor.to_s)
|
201
|
+
ACCESSOR_SUFFIXES.each do |modifier|
|
202
|
+
begin
|
203
|
+
remove_method("#{accessor}#{modifier}")
|
204
|
+
# rubocop: disable Lint/HandleExceptions
|
205
|
+
rescue NameError
|
206
|
+
# Do not remove the method
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def raise_if_tag_collision(tag, field_name)
|
212
|
+
if get_field(tag, true)
|
213
|
+
fail TagCollisionError, %(Field number #{tag} has already been used in "#{name}" by field "#{field_name}".)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def raise_if_name_collision(field_name)
|
218
|
+
if get_field(field_name, true)
|
219
|
+
fail DuplicateFieldNameError, %(Field name #{field_name} has already been used in "#{name}".)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def inherit_fields!(subclass)
|
224
|
+
instance_variables.each do |iv|
|
225
|
+
subclass.instance_variable_set(iv, instance_variable_get(iv))
|
226
|
+
end
|
227
|
+
end
|
228
|
+
private :inherit_fields!
|
229
|
+
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|