protobuffy 3.1.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 +7 -0
- data/.gitignore +21 -0
- data/.travis.yml +12 -0
- data/.yardopts +5 -0
- data/CHANGES.md +261 -0
- data/CONTRIBUTING.md +16 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +14 -0
- data/README.md +58 -0
- data/Rakefile +61 -0
- data/bin/protoc-gen-ruby +17 -0
- data/bin/rpc_server +4 -0
- data/examples/bin/reverse-client-http +4 -0
- data/examples/bin/reverse-client-socket +4 -0
- data/examples/bin/reverse-client-zmq +4 -0
- data/examples/config.ru +6 -0
- data/examples/definitions/example/reverse.proto +12 -0
- data/examples/lib/example/reverse-client.rb +23 -0
- data/examples/lib/example/reverse-service.rb +9 -0
- data/examples/lib/example/reverse.pb.rb +36 -0
- data/lib/protobuf.rb +106 -0
- data/lib/protobuf/cli.rb +249 -0
- data/lib/protobuf/code_generator.rb +41 -0
- data/lib/protobuf/decoder.rb +74 -0
- data/lib/protobuf/deprecator.rb +42 -0
- data/lib/protobuf/descriptors.rb +3 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +52 -0
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +249 -0
- data/lib/protobuf/encoder.rb +62 -0
- data/lib/protobuf/enum.rb +319 -0
- data/lib/protobuf/exceptions.rb +9 -0
- data/lib/protobuf/field.rb +74 -0
- data/lib/protobuf/field/base_field.rb +280 -0
- data/lib/protobuf/field/bool_field.rb +53 -0
- data/lib/protobuf/field/bytes_field.rb +81 -0
- data/lib/protobuf/field/double_field.rb +26 -0
- data/lib/protobuf/field/enum_field.rb +57 -0
- data/lib/protobuf/field/field_array.rb +86 -0
- data/lib/protobuf/field/fixed32_field.rb +25 -0
- data/lib/protobuf/field/fixed64_field.rb +29 -0
- data/lib/protobuf/field/float_field.rb +38 -0
- data/lib/protobuf/field/int32_field.rb +22 -0
- data/lib/protobuf/field/int64_field.rb +22 -0
- data/lib/protobuf/field/integer_field.rb +24 -0
- data/lib/protobuf/field/message_field.rb +66 -0
- data/lib/protobuf/field/sfixed32_field.rb +28 -0
- data/lib/protobuf/field/sfixed64_field.rb +29 -0
- data/lib/protobuf/field/signed_integer_field.rb +30 -0
- data/lib/protobuf/field/sint32_field.rb +22 -0
- data/lib/protobuf/field/sint64_field.rb +22 -0
- data/lib/protobuf/field/string_field.rb +35 -0
- data/lib/protobuf/field/uint32_field.rb +22 -0
- data/lib/protobuf/field/uint64_field.rb +22 -0
- data/lib/protobuf/field/varint_field.rb +68 -0
- data/lib/protobuf/generators/base.rb +71 -0
- data/lib/protobuf/generators/enum_generator.rb +42 -0
- data/lib/protobuf/generators/extension_generator.rb +28 -0
- data/lib/protobuf/generators/field_generator.rb +132 -0
- data/lib/protobuf/generators/file_generator.rb +140 -0
- data/lib/protobuf/generators/group_generator.rb +113 -0
- data/lib/protobuf/generators/message_generator.rb +99 -0
- data/lib/protobuf/generators/printable.rb +161 -0
- data/lib/protobuf/generators/service_generator.rb +27 -0
- data/lib/protobuf/http.rb +20 -0
- data/lib/protobuf/lifecycle.rb +46 -0
- data/lib/protobuf/logger.rb +86 -0
- data/lib/protobuf/message.rb +182 -0
- data/lib/protobuf/message/fields.rb +122 -0
- data/lib/protobuf/message/serialization.rb +84 -0
- data/lib/protobuf/optionable.rb +23 -0
- data/lib/protobuf/rpc/buffer.rb +79 -0
- data/lib/protobuf/rpc/client.rb +168 -0
- data/lib/protobuf/rpc/connector.rb +21 -0
- data/lib/protobuf/rpc/connectors/base.rb +54 -0
- data/lib/protobuf/rpc/connectors/common.rb +172 -0
- data/lib/protobuf/rpc/connectors/http.rb +90 -0
- data/lib/protobuf/rpc/connectors/socket.rb +73 -0
- data/lib/protobuf/rpc/connectors/zmq.rb +205 -0
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +47 -0
- data/lib/protobuf/rpc/env.rb +58 -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 +36 -0
- data/lib/protobuf/rpc/middleware/logger.rb +91 -0
- data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
- data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
- data/lib/protobuf/rpc/middleware/runner.rb +18 -0
- data/lib/protobuf/rpc/rpc.pb.rb +53 -0
- data/lib/protobuf/rpc/server.rb +39 -0
- data/lib/protobuf/rpc/servers/http/server.rb +101 -0
- data/lib/protobuf/rpc/servers/http_runner.rb +34 -0
- data/lib/protobuf/rpc/servers/socket/server.rb +113 -0
- data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
- data/lib/protobuf/rpc/servers/socket_runner.rb +34 -0
- data/lib/protobuf/rpc/servers/zmq/broker.rb +155 -0
- data/lib/protobuf/rpc/servers/zmq/server.rb +313 -0
- data/lib/protobuf/rpc/servers/zmq/util.rb +47 -0
- data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
- data/lib/protobuf/rpc/servers/zmq_runner.rb +51 -0
- data/lib/protobuf/rpc/service.rb +179 -0
- data/lib/protobuf/rpc/service_directory.rb +245 -0
- data/lib/protobuf/rpc/service_dispatcher.rb +46 -0
- data/lib/protobuf/rpc/service_filters.rb +273 -0
- data/lib/protobuf/rpc/stat.rb +148 -0
- data/lib/protobuf/socket.rb +22 -0
- data/lib/protobuf/tasks.rb +1 -0
- data/lib/protobuf/tasks/compile.rake +61 -0
- data/lib/protobuf/version.rb +3 -0
- data/lib/protobuf/wire_type.rb +10 -0
- data/lib/protobuf/zmq.rb +21 -0
- data/proto/dynamic_discovery.proto +44 -0
- data/proto/google/protobuf/compiler/plugin.proto +147 -0
- data/proto/google/protobuf/descriptor.proto +620 -0
- data/proto/rpc.proto +62 -0
- data/protobuffy.gemspec +37 -0
- data/spec/benchmark/tasks.rb +113 -0
- data/spec/bin/protoc-gen-ruby_spec.rb +18 -0
- data/spec/data/data.bin +3 -0
- data/spec/data/types.bin +0 -0
- data/spec/encoding/all_types_spec.rb +91 -0
- data/spec/encoding/extreme_values_spec.rb +0 -0
- data/spec/functional/socket_server_spec.rb +59 -0
- data/spec/functional/zmq_server_spec.rb +103 -0
- data/spec/lib/protobuf/cli_spec.rb +267 -0
- data/spec/lib/protobuf/code_generator_spec.rb +60 -0
- data/spec/lib/protobuf/enum_spec.rb +239 -0
- data/spec/lib/protobuf/field/int32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/string_field_spec.rb +46 -0
- data/spec/lib/protobuf/field_spec.rb +194 -0
- data/spec/lib/protobuf/generators/base_spec.rb +87 -0
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +68 -0
- data/spec/lib/protobuf/generators/extension_generator_spec.rb +43 -0
- data/spec/lib/protobuf/generators/field_generator_spec.rb +99 -0
- data/spec/lib/protobuf/generators/file_generator_spec.rb +29 -0
- data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
- data/spec/lib/protobuf/generators/service_generator_spec.rb +43 -0
- data/spec/lib/protobuf/lifecycle_spec.rb +89 -0
- data/spec/lib/protobuf/logger_spec.rb +136 -0
- data/spec/lib/protobuf/message_spec.rb +368 -0
- data/spec/lib/protobuf/optionable_spec.rb +46 -0
- data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
- data/spec/lib/protobuf/rpc/connector_spec.rb +26 -0
- data/spec/lib/protobuf/rpc/connectors/base_spec.rb +50 -0
- data/spec/lib/protobuf/rpc/connectors/common_spec.rb +170 -0
- data/spec/lib/protobuf/rpc/connectors/connector_spec.rb +13 -0
- data/spec/lib/protobuf/rpc/connectors/http_spec.rb +61 -0
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +24 -0
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +129 -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 +75 -0
- data/spec/lib/protobuf/rpc/servers/http/server_spec.rb +104 -0
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
- data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +41 -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 +295 -0
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +52 -0
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +484 -0
- data/spec/lib/protobuf/rpc/service_spec.rb +161 -0
- data/spec/lib/protobuf/rpc/stat_spec.rb +151 -0
- data/spec/lib/protobuf_spec.rb +78 -0
- data/spec/spec_helper.rb +57 -0
- data/spec/support/all.rb +7 -0
- data/spec/support/packed_field.rb +22 -0
- data/spec/support/server.rb +94 -0
- data/spec/support/test/all_types.data.bin +0 -0
- data/spec/support/test/all_types.data.txt +119 -0
- data/spec/support/test/defaults.pb.rb +25 -0
- data/spec/support/test/defaults.proto +9 -0
- data/spec/support/test/enum.pb.rb +59 -0
- data/spec/support/test/enum.proto +34 -0
- data/spec/support/test/extended.pb.rb +22 -0
- data/spec/support/test/extended.proto +10 -0
- data/spec/support/test/extreme_values.data.bin +0 -0
- data/spec/support/test/google_unittest.pb.rb +543 -0
- data/spec/support/test/google_unittest.proto +713 -0
- data/spec/support/test/google_unittest_import.pb.rb +37 -0
- data/spec/support/test/google_unittest_import.proto +64 -0
- data/spec/support/test/google_unittest_import_public.pb.rb +8 -0
- data/spec/support/test/google_unittest_import_public.proto +38 -0
- data/spec/support/test/multi_field_extensions.pb.rb +56 -0
- data/spec/support/test/multi_field_extensions.proto +33 -0
- data/spec/support/test/resource.pb.rb +117 -0
- data/spec/support/test/resource.proto +94 -0
- data/spec/support/test/resource_service.rb +26 -0
- data/spec/support/test_app_file.rb +2 -0
- data/spec/support/tolerance_matcher.rb +40 -0
- metadata +367 -0
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
class Logger < ::Logger
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_accessor :file, :level
|
8
|
+
|
9
|
+
# Stub out the log methods for Protobuf::Logger as singleton methods
|
10
|
+
[:debug, :info, :warn, :error, :fatal, :any, :add, :log].each do |m|
|
11
|
+
define_method(m) do |*params, &block|
|
12
|
+
instance && instance.__send__(m, *params, &block)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# One-line file/level configuration
|
18
|
+
def self.configure(options)
|
19
|
+
self.file = options.fetch(:file, false)
|
20
|
+
self.level = options.fetch(:level, false)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Use to reset the instance
|
24
|
+
def self.reset_device!
|
25
|
+
self.file = self.level = @__instance = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
# Singleton instance
|
29
|
+
def self.instance
|
30
|
+
@__instance ||= begin
|
31
|
+
log = nil
|
32
|
+
|
33
|
+
if @file && @level
|
34
|
+
log = new(self.file)
|
35
|
+
log.level = self.level
|
36
|
+
end
|
37
|
+
|
38
|
+
log
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# LogMethods module for log method including, e.g.:
|
44
|
+
#
|
45
|
+
# class MyClass
|
46
|
+
# include Protobuf::Logger::LogMethods
|
47
|
+
# ...
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# Produce a module to allow "include" in other classes to avoid
|
51
|
+
# cluttering the namespace of the including class with the other methods defined above
|
52
|
+
#
|
53
|
+
module LogMethods
|
54
|
+
[:debug, :info, :warn, :error, :fatal, :any, :add, :log].each do |m|
|
55
|
+
define_method("log_#{m}") do |*params, &block|
|
56
|
+
params.map! { |message| sign_message(message) }
|
57
|
+
::Protobuf::Logger.__send__(m, *params, &block)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# When included, also extend the LogMethods module for class access.
|
62
|
+
def self.included(base)
|
63
|
+
base.extend(LogMethods)
|
64
|
+
end
|
65
|
+
|
66
|
+
# We often want to log an exception, so let's make that a core
|
67
|
+
# concern of the logger.
|
68
|
+
#
|
69
|
+
def log_exception(ex)
|
70
|
+
log_error { ex.message }
|
71
|
+
log_error { ex.backtrace[0..5].join("\n") }
|
72
|
+
log_debug { ex.backtrace.join("\n") }
|
73
|
+
end
|
74
|
+
|
75
|
+
def log_signature
|
76
|
+
@_log_signature ||= "[#{self.class == Class ? self.name : self.class.name}]"
|
77
|
+
end
|
78
|
+
|
79
|
+
def sign_message(message)
|
80
|
+
"#{log_signature} #{message}"
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'protobuf/field'
|
2
|
+
require 'protobuf/enum'
|
3
|
+
require 'protobuf/exceptions'
|
4
|
+
require 'protobuf/message/fields'
|
5
|
+
require 'protobuf/message/serialization'
|
6
|
+
|
7
|
+
module Protobuf
|
8
|
+
class Message
|
9
|
+
|
10
|
+
##
|
11
|
+
# Includes & Extends
|
12
|
+
#
|
13
|
+
|
14
|
+
extend ::Protobuf::Message::Fields
|
15
|
+
include ::Protobuf::Message::Serialization
|
16
|
+
|
17
|
+
##
|
18
|
+
# Class Methods
|
19
|
+
#
|
20
|
+
|
21
|
+
def self.to_json
|
22
|
+
name
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Constructor
|
27
|
+
#
|
28
|
+
|
29
|
+
def initialize(fields = {})
|
30
|
+
@values = {}
|
31
|
+
|
32
|
+
fields.to_hash.each_pair do |name, value|
|
33
|
+
self[name] = value unless value.nil?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Public Instance Methods
|
39
|
+
#
|
40
|
+
|
41
|
+
def clear!
|
42
|
+
@values.delete_if do |_, value|
|
43
|
+
if value.is_a?(::Protobuf::Field::FieldArray)
|
44
|
+
value.clear
|
45
|
+
false
|
46
|
+
else
|
47
|
+
true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def clone
|
54
|
+
copy_to(super, :clone)
|
55
|
+
end
|
56
|
+
|
57
|
+
def dup
|
58
|
+
copy_to(super, :dup)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Iterate over every field, invoking the given block
|
62
|
+
#
|
63
|
+
def each_field
|
64
|
+
self.class.all_fields.each do |field|
|
65
|
+
value = __send__(field.name)
|
66
|
+
yield(field, value)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def each_field_for_serialization
|
71
|
+
self.class.all_fields.each do |field|
|
72
|
+
next unless field_must_be_serialized?(field)
|
73
|
+
|
74
|
+
value = @values[field.name]
|
75
|
+
|
76
|
+
if value.nil?
|
77
|
+
raise ::Protobuf::SerializationError, "Required field #{self.class.name}##{field.name} does not have a value."
|
78
|
+
else
|
79
|
+
yield(field, value)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def has_field?(name)
|
85
|
+
@values.has_key?(name)
|
86
|
+
end
|
87
|
+
|
88
|
+
def inspect
|
89
|
+
to_hash.inspect
|
90
|
+
end
|
91
|
+
|
92
|
+
def respond_to_has?(key)
|
93
|
+
respond_to?(key) && has_field?(key)
|
94
|
+
end
|
95
|
+
|
96
|
+
def respond_to_has_and_present?(key)
|
97
|
+
respond_to_has?(key) &&
|
98
|
+
(__send__(key).present? || [true, false].include?(__send__(key)))
|
99
|
+
end
|
100
|
+
|
101
|
+
# Return a hash-representation of the given fields for this message type.
|
102
|
+
def to_hash
|
103
|
+
result = Hash.new
|
104
|
+
|
105
|
+
@values.keys.each do |field_name|
|
106
|
+
value = __send__(field_name)
|
107
|
+
hashed_value = value.respond_to?(:to_hash_value) ? value.to_hash_value : value
|
108
|
+
result.merge!(field_name => hashed_value)
|
109
|
+
end
|
110
|
+
|
111
|
+
return result
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_json(options = {})
|
115
|
+
to_hash.to_json(options)
|
116
|
+
end
|
117
|
+
|
118
|
+
def to_proto
|
119
|
+
self
|
120
|
+
end
|
121
|
+
|
122
|
+
def ==(obj)
|
123
|
+
return false unless obj.is_a?(self.class)
|
124
|
+
each_field do |field, value|
|
125
|
+
return false unless value == obj.__send__(field.name)
|
126
|
+
end
|
127
|
+
true
|
128
|
+
end
|
129
|
+
|
130
|
+
def [](name)
|
131
|
+
if field = self.class.get_field(name, true)
|
132
|
+
__send__(field.name)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def []=(name, value)
|
137
|
+
if field = self.class.get_field(name, true)
|
138
|
+
__send__(field.setter_method_name, value)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
##
|
143
|
+
# Instance Aliases
|
144
|
+
#
|
145
|
+
alias_method :to_hash_value, :to_hash
|
146
|
+
alias_method :to_proto_hash, :to_hash
|
147
|
+
alias_method :responds_to_has?, :respond_to_has?
|
148
|
+
alias_method :respond_to_and_has?, :respond_to_has?
|
149
|
+
alias_method :responds_to_and_has?, :respond_to_has?
|
150
|
+
alias_method :respond_to_has_present?, :respond_to_has_and_present?
|
151
|
+
alias_method :respond_to_and_has_present?, :respond_to_has_and_present?
|
152
|
+
alias_method :respond_to_and_has_and_present?, :respond_to_has_and_present?
|
153
|
+
alias_method :responds_to_has_present?, :respond_to_has_and_present?
|
154
|
+
alias_method :responds_to_and_has_present?, :respond_to_has_and_present?
|
155
|
+
alias_method :responds_to_and_has_and_present?, :respond_to_has_and_present?
|
156
|
+
|
157
|
+
##
|
158
|
+
# Private Instance Methods
|
159
|
+
#
|
160
|
+
private
|
161
|
+
|
162
|
+
def copy_to(object, method)
|
163
|
+
duplicate = proc { |obj|
|
164
|
+
case obj
|
165
|
+
when Message, String then obj.__send__(method)
|
166
|
+
else obj
|
167
|
+
end
|
168
|
+
}
|
169
|
+
|
170
|
+
object.__send__(:initialize)
|
171
|
+
@values.each do |name, value|
|
172
|
+
if value.is_a?(::Protobuf::Field::FieldArray)
|
173
|
+
object.__send__(name).replace(value.map {|v| duplicate.call(v)})
|
174
|
+
else
|
175
|
+
object.__send__("#{name}=", duplicate.call(value))
|
176
|
+
end
|
177
|
+
end
|
178
|
+
object
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'protobuf/deprecator'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
class Message
|
5
|
+
module Fields
|
6
|
+
|
7
|
+
def self.extended(other)
|
8
|
+
other.extend(::Protobuf::Deprecator)
|
9
|
+
other.deprecate_class_method(:get_ext_field_by_name, :get_extension_field)
|
10
|
+
other.deprecate_class_method(:get_ext_field_by_tag, :get_extension_field)
|
11
|
+
other.deprecate_class_method(:get_field_by_name, :get_field)
|
12
|
+
other.deprecate_class_method(:get_field_by_tag, :get_field)
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Field Definition Methods
|
17
|
+
#
|
18
|
+
|
19
|
+
# Define an optional field.
|
20
|
+
#
|
21
|
+
def optional(type_class, name, tag, options = {})
|
22
|
+
define_field(:optional, type_class, name, tag, options)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Define a repeated field.
|
26
|
+
#
|
27
|
+
def repeated(type_class, name, tag, options = {})
|
28
|
+
define_field(:repeated, type_class, name, tag, options)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Define a required field.
|
32
|
+
#
|
33
|
+
def required(type_class, name, tag, options = {})
|
34
|
+
define_field(:required, type_class, name, tag, options)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Define an extension range.
|
38
|
+
#
|
39
|
+
def extensions(range)
|
40
|
+
extension_ranges << range
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Field Access Methods
|
45
|
+
#
|
46
|
+
|
47
|
+
def all_fields
|
48
|
+
@all_fields ||= field_store.values.uniq
|
49
|
+
end
|
50
|
+
|
51
|
+
def extension_fields
|
52
|
+
@extension_fields ||= all_fields.select(&:extension?)
|
53
|
+
end
|
54
|
+
|
55
|
+
def extension_ranges
|
56
|
+
@extension_ranges ||= []
|
57
|
+
end
|
58
|
+
|
59
|
+
def extension_tag?(tag)
|
60
|
+
tag.respond_to?(:to_i) && get_extension_field(tag).present?
|
61
|
+
end
|
62
|
+
|
63
|
+
def field_store
|
64
|
+
@field_store ||= {}
|
65
|
+
end
|
66
|
+
|
67
|
+
def fields
|
68
|
+
@fields ||= all_fields.reject(&:extension?)
|
69
|
+
end
|
70
|
+
|
71
|
+
def field_tag?(tag, allow_extension = false)
|
72
|
+
tag.respond_to?(:to_i) && get_field(tag, allow_extension).present?
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_extension_field(name_or_tag)
|
76
|
+
name_or_tag = name_or_tag.to_sym if name_or_tag.respond_to?(:to_sym)
|
77
|
+
field = field_store[name_or_tag]
|
78
|
+
field if field.try(:extension?) { false }
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_field(name_or_tag, allow_extension = false)
|
82
|
+
name_or_tag = name_or_tag.to_sym if name_or_tag.respond_to?(:to_sym)
|
83
|
+
field = field_store[name_or_tag]
|
84
|
+
|
85
|
+
if field && (allow_extension || ! field.extension?)
|
86
|
+
field
|
87
|
+
else
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def define_field(rule, type_class, field_name, tag, options)
|
93
|
+
raise_if_tag_collision(tag, field_name)
|
94
|
+
raise_if_name_collision(field_name)
|
95
|
+
|
96
|
+
field = ::Protobuf::Field.build(self, rule, type_class, field_name, tag, options)
|
97
|
+
field_store[field_name] = field
|
98
|
+
field_store[tag] = field
|
99
|
+
|
100
|
+
class_eval(<<-RAW_GETTER, __FILE__, __LINE__ + 1)
|
101
|
+
define_method("#{field_name}!") do
|
102
|
+
@values[:#{field_name}]
|
103
|
+
end
|
104
|
+
RAW_GETTER
|
105
|
+
end
|
106
|
+
|
107
|
+
def raise_if_tag_collision(tag, field_name)
|
108
|
+
if get_field(tag, true)
|
109
|
+
raise TagCollisionError, %!Field number #{tag} has already been used in "#{name}" by field "#{field_name}".!
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def raise_if_name_collision(field_name)
|
114
|
+
if get_field(field_name, true)
|
115
|
+
raise DuplicateFieldNameError, %!Field name #{field_name} has already been used in "#{name}".!
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'protobuf/decoder'
|
3
|
+
require 'protobuf/encoder'
|
4
|
+
|
5
|
+
module Protobuf
|
6
|
+
class Message
|
7
|
+
module Serialization
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def decode(bytes)
|
11
|
+
self.new.decode(bytes)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Create a new object with the given values and return the encoded bytes.
|
15
|
+
def encode(fields = {})
|
16
|
+
self.new(fields).encode
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.included(other)
|
21
|
+
other.extend(ClassMethods)
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Instance Methods
|
26
|
+
#
|
27
|
+
|
28
|
+
# Decode the given non-stream bytes into this message.
|
29
|
+
#
|
30
|
+
def decode(bytes)
|
31
|
+
decode_from(::StringIO.new(bytes))
|
32
|
+
end
|
33
|
+
|
34
|
+
# Decode the given stream into this message.
|
35
|
+
#
|
36
|
+
def decode_from(stream)
|
37
|
+
::Protobuf::Decoder.decode_each_field(stream) do |tag, bytes|
|
38
|
+
set_field_bytes(tag, bytes)
|
39
|
+
end
|
40
|
+
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
# Encode this message
|
45
|
+
#
|
46
|
+
def encode
|
47
|
+
stream = ::StringIO.new.set_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
|
48
|
+
encode_to(stream).string
|
49
|
+
end
|
50
|
+
|
51
|
+
# Encode this message to the given stream.
|
52
|
+
#
|
53
|
+
def encode_to(stream)
|
54
|
+
::Protobuf::Encoder.encode(self, stream)
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Instance Aliases
|
59
|
+
#
|
60
|
+
alias_method :parse_from_string, :decode
|
61
|
+
alias_method :deserialize, :decode
|
62
|
+
alias_method :parse_from, :decode_from
|
63
|
+
alias_method :deserialize_from, :decode_from
|
64
|
+
alias_method :to_s, :encode
|
65
|
+
alias_method :bytes, :encode
|
66
|
+
alias_method :serialize, :encode
|
67
|
+
alias_method :serialize_to_string, :encode
|
68
|
+
alias_method :serialize_to, :encode_to
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def field_must_be_serialized?(field)
|
73
|
+
field.required? || ! @values[field.name].nil?
|
74
|
+
end
|
75
|
+
|
76
|
+
def set_field_bytes(tag, bytes)
|
77
|
+
field = self.class.get_field(tag, true)
|
78
|
+
field.set(self, bytes) if field
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|