protobuf 2.8.13 → 3.0.0.rc1
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/CHANGES.md +84 -5
- data/CONTRIBUTING.md +3 -3
- data/Rakefile +46 -7
- data/lib/protobuf/cli.rb +2 -20
- data/lib/protobuf/decoder.rb +74 -0
- data/lib/protobuf/deprecator.rb +42 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +17 -16
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +86 -85
- data/lib/protobuf/encoder.rb +62 -0
- data/lib/protobuf/enum.rb +298 -37
- data/lib/protobuf/field/base_field.rb +41 -27
- data/lib/protobuf/field/bool_field.rb +22 -4
- data/lib/protobuf/field/bytes_field.rb +36 -15
- data/lib/protobuf/field/double_field.rb +10 -3
- data/lib/protobuf/field/enum_field.rb +21 -18
- data/lib/protobuf/field/field_array.rb +26 -16
- data/lib/protobuf/field/fixed32_field.rb +10 -4
- data/lib/protobuf/field/fixed64_field.rb +10 -3
- data/lib/protobuf/field/float_field.rb +18 -5
- data/lib/protobuf/field/int32_field.rb +14 -4
- data/lib/protobuf/field/int64_field.rb +14 -4
- data/lib/protobuf/field/integer_field.rb +9 -4
- data/lib/protobuf/field/message_field.rb +16 -7
- data/lib/protobuf/field/sfixed32_field.rb +10 -3
- data/lib/protobuf/field/sfixed64_field.rb +12 -7
- data/lib/protobuf/field/signed_integer_field.rb +7 -0
- data/lib/protobuf/field/sint32_field.rb +14 -4
- data/lib/protobuf/field/sint64_field.rb +14 -4
- data/lib/protobuf/field/string_field.rb +11 -1
- data/lib/protobuf/field/uint32_field.rb +14 -4
- data/lib/protobuf/field/uint64_field.rb +14 -4
- data/lib/protobuf/field/varint_field.rb +11 -9
- data/lib/protobuf/field.rb +42 -25
- data/lib/protobuf/generators/enum_generator.rb +12 -1
- data/lib/protobuf/generators/field_generator.rb +1 -1
- data/lib/protobuf/lifecycle.rb +3 -4
- data/lib/protobuf/message/fields.rb +122 -0
- data/lib/protobuf/message/serialization.rb +84 -0
- data/lib/protobuf/message.rb +21 -221
- data/lib/protobuf/optionable.rb +23 -0
- data/lib/protobuf/rpc/client.rb +2 -4
- data/lib/protobuf/rpc/connector.rb +0 -2
- data/lib/protobuf/rpc/connectors/common.rb +2 -2
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +14 -16
- data/lib/protobuf/rpc/env.rb +58 -0
- data/lib/protobuf/rpc/error.rb +8 -5
- 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/middleware.rb +25 -0
- data/lib/protobuf/rpc/rpc.pb.rb +15 -16
- data/lib/protobuf/rpc/server.rb +14 -64
- data/lib/protobuf/rpc/servers/socket/server.rb +0 -2
- data/lib/protobuf/rpc/servers/socket/worker.rb +11 -15
- data/lib/protobuf/rpc/servers/zmq/util.rb +4 -1
- data/lib/protobuf/rpc/servers/zmq/worker.rb +5 -13
- data/lib/protobuf/rpc/servers/zmq_runner.rb +1 -1
- data/lib/protobuf/rpc/service.rb +38 -72
- data/lib/protobuf/rpc/service_dispatcher.rb +20 -108
- data/lib/protobuf/version.rb +1 -2
- data/lib/protobuf.rb +5 -13
- data/protobuf.gemspec +5 -5
- data/spec/benchmark/tasks.rb +2 -77
- data/spec/functional/zmq_server_spec.rb +13 -21
- data/spec/lib/protobuf/cli_spec.rb +5 -43
- data/spec/lib/protobuf/enum_spec.rb +194 -61
- data/spec/lib/protobuf/field_spec.rb +194 -0
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +24 -1
- data/spec/lib/protobuf/generators/field_generator_spec.rb +6 -6
- data/spec/lib/protobuf/message_spec.rb +52 -70
- data/spec/lib/protobuf/optionable_spec.rb +46 -0
- data/spec/lib/protobuf/rpc/client_spec.rb +1 -93
- data/spec/lib/protobuf/rpc/connector_spec.rb +1 -7
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +8 -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/socket_server_spec.rb +0 -6
- data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +10 -0
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +30 -105
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +4 -4
- data/spec/lib/protobuf/rpc/service_spec.rb +20 -24
- data/spec/lib/protobuf_spec.rb +3 -3
- data/spec/spec_helper.rb +5 -4
- data/spec/support/packed_field.rb +15 -14
- data/spec/support/server.rb +4 -21
- data/spec/support/test/defaults.pb.rb +4 -4
- data/spec/support/test/enum.pb.rb +13 -1
- data/spec/support/test/enum.proto +15 -0
- data/spec/support/test/extended.pb.rb +1 -1
- data/spec/support/test/google_unittest.pb.rb +239 -241
- data/spec/support/test/google_unittest_import.pb.rb +2 -2
- data/spec/support/test/multi_field_extensions.pb.rb +2 -2
- data/spec/support/test/resource.pb.rb +19 -18
- data/spec/support/test/resource.proto +1 -0
- data/spec/support/test/resource_service.rb +5 -0
- metadata +78 -57
- data/bin/rprotoc +0 -8
- data/lib/protobuf/enum_value.rb +0 -85
- data/lib/protobuf/evented.rb +0 -37
- data/lib/protobuf/ext/eventmachine.rb +0 -14
- data/lib/protobuf/field/extension_fields.rb +0 -32
- data/lib/protobuf/message/decoder.rb +0 -72
- data/lib/protobuf/message/message.rb +0 -1
- data/lib/protobuf/rpc/connectors/em_client.rb +0 -84
- data/lib/protobuf/rpc/connectors/eventmachine.rb +0 -87
- data/lib/protobuf/rpc/servers/evented/server.rb +0 -36
- data/lib/protobuf/rpc/servers/evented_runner.rb +0 -31
- data/spec/functional/embedded_service_spec.rb +0 -7
- data/spec/functional/evented_server_spec.rb +0 -64
- data/spec/lib/protobuf/enum_value_spec.rb +0 -29
- data/spec/lib/protobuf/rpc/servers/evented_server_spec.rb +0 -19
data/lib/protobuf/field.rb
CHANGED
@@ -19,38 +19,55 @@ require 'protobuf/field/sfixed32_field'
|
|
19
19
|
require 'protobuf/field/sfixed64_field'
|
20
20
|
require 'protobuf/field/fixed32_field'
|
21
21
|
require 'protobuf/field/fixed64_field'
|
22
|
-
require 'protobuf/field/extension_fields'
|
23
22
|
|
24
23
|
module Protobuf
|
25
24
|
module Field
|
26
|
-
|
27
|
-
|
28
|
-
::Protobuf::Field::
|
29
|
-
::Protobuf::Field::
|
30
|
-
::Protobuf::Field::
|
31
|
-
::Protobuf::Field::
|
32
|
-
::Protobuf::Field::
|
33
|
-
::Protobuf::Field::
|
34
|
-
::Protobuf::Field::
|
35
|
-
::Protobuf::Field::
|
36
|
-
::Protobuf::Field::
|
37
|
-
::Protobuf::Field::
|
38
|
-
::Protobuf::Field::
|
39
|
-
::Protobuf::Field::
|
40
|
-
::Protobuf::Field::
|
41
|
-
::Protobuf::Field::
|
42
|
-
|
25
|
+
|
26
|
+
PRIMITIVE_FIELD_MAP = {
|
27
|
+
:double => ::Protobuf::Field::DoubleField,
|
28
|
+
:float => ::Protobuf::Field::FloatField,
|
29
|
+
:int32 => ::Protobuf::Field::Int32Field,
|
30
|
+
:int64 => ::Protobuf::Field::Int64Field,
|
31
|
+
:uint32 => ::Protobuf::Field::Uint32Field,
|
32
|
+
:uint64 => ::Protobuf::Field::Uint64Field,
|
33
|
+
:sint32 => ::Protobuf::Field::Sint32Field,
|
34
|
+
:sint64 => ::Protobuf::Field::Sint64Field,
|
35
|
+
:fixed32 => ::Protobuf::Field::Fixed32Field,
|
36
|
+
:fixed64 => ::Protobuf::Field::Fixed64Field,
|
37
|
+
:sfixed32 => ::Protobuf::Field::Sfixed32Field,
|
38
|
+
:sfixed64 => ::Protobuf::Field::Sfixed64Field,
|
39
|
+
:string => ::Protobuf::Field::StringField,
|
40
|
+
:bytes => ::Protobuf::Field::BytesField,
|
41
|
+
:bool => ::Protobuf::Field::BoolField
|
42
|
+
}.freeze
|
43
43
|
|
44
44
|
def self.build(message_class, rule, type, name, tag, options = {})
|
45
|
-
field_class
|
46
|
-
|
45
|
+
field_class(type).new(message_class, rule, field_type(type), name, tag, options)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the field class for primitives,
|
49
|
+
# EnumField for types that inherit from Protobuf::Enum,
|
50
|
+
# and MessageField for types that inherit from Protobuf::Message.
|
51
|
+
#
|
52
|
+
def self.field_class(type)
|
53
|
+
if PRIMITIVE_FIELD_MAP.key?(type)
|
54
|
+
PRIMITIVE_FIELD_MAP[type]
|
55
|
+
elsif type < ::Protobuf::Enum
|
56
|
+
EnumField
|
57
|
+
elsif type < ::Protobuf::Message
|
58
|
+
MessageField
|
59
|
+
elsif type < ::Protobuf::Field::BaseField
|
60
|
+
type
|
61
|
+
else
|
62
|
+
raise ArgumentError, "Invalid field type #{type}"
|
63
|
+
end
|
47
64
|
end
|
48
65
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
66
|
+
# Returns the mapped type for primitives,
|
67
|
+
# otherwise the given type is returned.
|
68
|
+
#
|
69
|
+
def self.field_type(type)
|
70
|
+
PRIMITIVE_FIELD_MAP.fetch(type) { type }
|
54
71
|
end
|
55
72
|
|
56
73
|
end
|
@@ -4,18 +4,29 @@ module Protobuf
|
|
4
4
|
module Generators
|
5
5
|
class EnumGenerator < Base
|
6
6
|
|
7
|
+
def allow_alias?
|
8
|
+
descriptor.options.try(:allow_alias!) { false }
|
9
|
+
end
|
10
|
+
|
7
11
|
def compile
|
8
12
|
run_once(:compile) do
|
9
13
|
tags = []
|
10
14
|
|
11
15
|
print_class(descriptor.name, :enum) do
|
16
|
+
if allow_alias?
|
17
|
+
puts "set_option :allow_alias"
|
18
|
+
puts
|
19
|
+
end
|
20
|
+
|
12
21
|
descriptor.value.each do |enum_value_descriptor|
|
13
22
|
tags << enum_value_descriptor.number
|
14
23
|
puts build_value(enum_value_descriptor)
|
15
24
|
end
|
16
25
|
end
|
17
26
|
|
18
|
-
|
27
|
+
unless allow_alias?
|
28
|
+
self.class.validate_tags(fully_qualified_type_namespace, tags)
|
29
|
+
end
|
19
30
|
end
|
20
31
|
end
|
21
32
|
|
data/lib/protobuf/lifecycle.rb
CHANGED
@@ -2,10 +2,9 @@ module Protobuf
|
|
2
2
|
class Lifecycle
|
3
3
|
include ::Protobuf::Logger::LogMethods
|
4
4
|
|
5
|
-
def self.register(
|
5
|
+
def self.register(event_name, &blk)
|
6
6
|
raise "Lifecycle register must have a block" unless block_given?
|
7
|
-
|
8
|
-
event_name = normalized_event_name( event_name )
|
7
|
+
event_name = normalized_event_name(event_name)
|
9
8
|
|
10
9
|
if ::Protobuf.print_deprecation_warnings?
|
11
10
|
$stderr.puts <<-ERROR
|
@@ -32,7 +31,7 @@ module Protobuf
|
|
32
31
|
::ActiveSupport::Notifications.instrument(event_name, args)
|
33
32
|
end
|
34
33
|
|
35
|
-
def self.normalized_event_name(
|
34
|
+
def self.normalized_event_name(event_name)
|
36
35
|
return "#{event_name}".downcase
|
37
36
|
end
|
38
37
|
|
@@ -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
|
+
|
data/lib/protobuf/message.rb
CHANGED
@@ -1,147 +1,33 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
require 'set'
|
3
1
|
require 'protobuf/field'
|
4
2
|
require 'protobuf/enum'
|
5
3
|
require 'protobuf/exceptions'
|
6
|
-
require 'protobuf/message/
|
4
|
+
require 'protobuf/message/fields'
|
5
|
+
require 'protobuf/message/serialization'
|
7
6
|
|
8
7
|
module Protobuf
|
9
8
|
class Message
|
10
9
|
|
11
10
|
##
|
12
|
-
#
|
11
|
+
# Includes & Extends
|
13
12
|
#
|
14
|
-
def self.all_fields
|
15
|
-
@all_fields ||= begin
|
16
|
-
all_fields_array = []
|
17
|
-
max_fields = fields.size > extension_fields.size ? fields.size : extension_fields.size
|
18
|
-
max_fields.times do |field_number|
|
19
|
-
all_fields_array << (fields[field_number] || extension_fields[field_number])
|
20
|
-
end
|
21
|
-
all_fields_array.compact!
|
22
|
-
all_fields_array
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.decode(bytes)
|
27
|
-
self.new.decode(bytes)
|
28
|
-
end
|
29
|
-
|
30
|
-
# Define a field. Don't use this method directly.
|
31
|
-
def self.define_field(rule, type, fname, tag, options)
|
32
|
-
field_array = options[:extension] ? extension_fields : fields
|
33
|
-
field_name_hash = options[:extension] ? extension_field_name_to_tag : field_name_to_tag
|
34
|
-
|
35
|
-
previous_tag_field = get_field_by_tag(tag) || get_ext_field_by_tag(tag)
|
36
|
-
if previous_tag_field
|
37
|
-
raise TagCollisionError, %!Field number #{tag} has already been used in "#{self.name}" by field "#{fname}".!
|
38
|
-
end
|
39
|
-
|
40
|
-
previous_name_field = get_field_by_name(fname) || get_ext_field_by_name(fname)
|
41
|
-
if previous_name_field
|
42
|
-
raise DuplicateFieldNameError, %!Field name #{fname} has already been used in "#{self.name}".!
|
43
|
-
end
|
44
|
-
|
45
|
-
field_definition = ::Protobuf::Field.build(self, rule, type, fname, tag, options)
|
46
|
-
field_name_hash[fname] = tag
|
47
|
-
field_array[tag] = field_definition
|
48
|
-
|
49
|
-
define_method("#{fname}!") do
|
50
|
-
@values[fname]
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Create a new object with the given values and return the encoded bytes.
|
55
|
-
def self.encode(values = {})
|
56
|
-
self.new(values).encode
|
57
|
-
end
|
58
|
-
|
59
|
-
# Reserve field numbers for extensions. Don't use this method directly.
|
60
|
-
def self.extensions(range)
|
61
|
-
extension_fields.add_range(range)
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.extension_field_name_to_tag
|
65
|
-
@extension_fields_by_name ||= {}
|
66
|
-
end
|
67
|
-
|
68
|
-
# An extension field object.
|
69
|
-
def self.extension_fields
|
70
|
-
@extension_fields ||= ::Protobuf::Field::ExtensionFields.new
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.extension_tag?(tag)
|
74
|
-
extension_fields.include_tag?(tag)
|
75
|
-
end
|
76
|
-
|
77
|
-
# A collection of field object.
|
78
|
-
def self.fields
|
79
|
-
@fields ||= []
|
80
|
-
end
|
81
|
-
|
82
|
-
def self.field_name_to_tag
|
83
|
-
@field_name_to_tag ||= {}
|
84
|
-
end
|
85
|
-
|
86
|
-
def self.get_ext_field_by_name(name)
|
87
|
-
tag = extension_field_name_to_tag[name.to_sym]
|
88
|
-
extension_fields[tag] unless tag.nil?
|
89
|
-
end
|
90
|
-
|
91
|
-
def self.get_ext_field_by_tag(tag)
|
92
|
-
extension_fields[tag]
|
93
|
-
end
|
94
|
-
|
95
|
-
# Find a field object by +name+.
|
96
|
-
def self.get_field_by_name(name)
|
97
|
-
name = name.to_sym if name.respond_to?(:to_sym)
|
98
|
-
tag = field_name_to_tag[name]
|
99
|
-
fields[tag] unless tag.nil?
|
100
|
-
end
|
101
|
-
|
102
|
-
# Find a field object by +tag+ number.
|
103
|
-
def self.get_field_by_tag(tag)
|
104
|
-
fields[tag]
|
105
|
-
rescue TypeError
|
106
|
-
tag = tag.nil? ? 'nil' : tag.to_s
|
107
|
-
raise FieldNotDefinedError.new("Tag '#{tag}' does not reference a message field for '#{self.name}'")
|
108
|
-
end
|
109
|
-
|
110
|
-
# Define a optional field. Don't use this method directly.
|
111
|
-
def self.optional(type, name, tag, options = {})
|
112
|
-
define_field(:optional, type, name, tag, options)
|
113
|
-
end
|
114
|
-
|
115
|
-
# Define a repeated field. Don't use this method directly.
|
116
|
-
def self.repeated(type, name, tag, options = {})
|
117
|
-
define_field(:repeated, type, name, tag, options)
|
118
|
-
end
|
119
13
|
|
120
|
-
|
121
|
-
|
122
|
-
define_field(:required, type, name, tag, options)
|
123
|
-
end
|
124
|
-
|
125
|
-
# Backported fix to prevent recursive to_json issues.
|
126
|
-
def self.to_json
|
127
|
-
name
|
128
|
-
end
|
14
|
+
extend ::Protobuf::Message::Fields
|
15
|
+
include ::Protobuf::Message::Serialization
|
129
16
|
|
130
17
|
##
|
131
18
|
# Constructor
|
132
19
|
#
|
133
|
-
def initialize(
|
20
|
+
def initialize(fields = {})
|
134
21
|
@values = {}
|
135
|
-
|
136
|
-
|
22
|
+
|
23
|
+
fields.to_hash.each_pair do |name, value|
|
24
|
+
self[name] = value unless value.nil?
|
25
|
+
end
|
137
26
|
end
|
138
27
|
|
139
28
|
##
|
140
29
|
# Public Instance Methods
|
141
30
|
#
|
142
|
-
def all_fields
|
143
|
-
self.class.all_fields
|
144
|
-
end
|
145
31
|
|
146
32
|
def clear!
|
147
33
|
@values.delete_if do |_, value|
|
@@ -159,95 +45,33 @@ module Protobuf
|
|
159
45
|
copy_to(super, :clone)
|
160
46
|
end
|
161
47
|
|
162
|
-
# Decode the given string bytes into this object.
|
163
|
-
def decode(string)
|
164
|
-
decode_from(::StringIO.new(string))
|
165
|
-
end
|
166
|
-
|
167
|
-
# Decode the given stream into this object.
|
168
|
-
def decode_from(stream)
|
169
|
-
Decoder.decode(stream, self)
|
170
|
-
end
|
171
|
-
|
172
48
|
def dup
|
173
49
|
copy_to(super, :dup)
|
174
50
|
end
|
175
51
|
|
176
|
-
# Iterate over
|
177
|
-
#
|
178
|
-
# # do something
|
179
|
-
# end
|
52
|
+
# Iterate over every field, invoking the given block
|
53
|
+
#
|
180
54
|
def each_field
|
181
|
-
all_fields.each do |field|
|
55
|
+
self.class.all_fields.each do |field|
|
182
56
|
value = __send__(field.name)
|
183
57
|
yield(field, value)
|
184
58
|
end
|
185
59
|
end
|
186
60
|
|
187
61
|
def each_field_for_serialization
|
188
|
-
all_fields.each do |field|
|
189
|
-
next unless
|
62
|
+
self.class.all_fields.each do |field|
|
63
|
+
next unless field_must_be_serialized?(field)
|
190
64
|
|
191
65
|
value = @values[field.name]
|
192
66
|
|
193
67
|
if value.nil?
|
194
|
-
|
195
|
-
raise ::Protobuf::SerializationError, "#{field.name} is required on #{field.message_class}"
|
68
|
+
raise ::Protobuf::SerializationError, "Required field #{self.name}##{field.name} does not have a value."
|
196
69
|
else
|
197
70
|
yield(field, value)
|
198
71
|
end
|
199
72
|
end
|
200
73
|
end
|
201
74
|
|
202
|
-
def encode
|
203
|
-
stream = ""
|
204
|
-
|
205
|
-
each_field_for_serialization do |field, value|
|
206
|
-
if field.repeated?
|
207
|
-
if field.packed?
|
208
|
-
key = (field.tag << 3) | ::Protobuf::WireType::LENGTH_DELIMITED
|
209
|
-
packed_value = value.map { |val| field.encode(val) }.join
|
210
|
-
stream << ::Protobuf::Field::VarintField.encode(key)
|
211
|
-
stream << ::Protobuf::Field::VarintField.encode(packed_value.size)
|
212
|
-
stream << packed_value
|
213
|
-
else
|
214
|
-
value.each { |val| write_pair(stream, field, val) }
|
215
|
-
end
|
216
|
-
else
|
217
|
-
write_pair(stream, field, value)
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
return stream
|
222
|
-
end
|
223
|
-
|
224
|
-
# Returns extension fields. See Message#fields method.
|
225
|
-
def extension_fields
|
226
|
-
self.class.extension_fields
|
227
|
-
end
|
228
|
-
|
229
|
-
def fields
|
230
|
-
self.class.fields
|
231
|
-
end
|
232
|
-
|
233
|
-
def get_ext_field_by_name(name) # :nodoc:
|
234
|
-
self.class.get_ext_field_by_name(name)
|
235
|
-
end
|
236
|
-
|
237
|
-
def get_ext_field_by_tag(tag) # :nodoc:
|
238
|
-
self.class.get_ext_field_by_tag(tag)
|
239
|
-
end
|
240
|
-
|
241
|
-
# Returns field object or +nil+.
|
242
|
-
def get_field_by_name(name)
|
243
|
-
self.class.get_field_by_name(name)
|
244
|
-
end
|
245
|
-
|
246
|
-
# Returns field object or +nil+.
|
247
|
-
def get_field_by_tag(tag)
|
248
|
-
self.class.get_field_by_tag(tag)
|
249
|
-
end
|
250
|
-
|
251
75
|
def has_field?(name)
|
252
76
|
@values.has_key?(name)
|
253
77
|
end
|
@@ -257,17 +81,12 @@ module Protobuf
|
|
257
81
|
end
|
258
82
|
|
259
83
|
def respond_to_has?(key)
|
260
|
-
|
84
|
+
respond_to?(key) && has_field?(key)
|
261
85
|
end
|
262
86
|
|
263
87
|
def respond_to_has_and_present?(key)
|
264
|
-
|
265
|
-
(
|
266
|
-
end
|
267
|
-
|
268
|
-
def set_field(tag, bytes)
|
269
|
-
field = (get_field_by_tag(tag) || get_ext_field_by_tag(tag))
|
270
|
-
field.set(self, bytes) if field
|
88
|
+
respond_to_has?(key) &&
|
89
|
+
(__send__(key).present? || [true, false].include?(__send__(key)))
|
271
90
|
end
|
272
91
|
|
273
92
|
# Return a hash-representation of the given fields for this message type.
|
@@ -300,13 +119,13 @@ module Protobuf
|
|
300
119
|
end
|
301
120
|
|
302
121
|
def [](name)
|
303
|
-
if field =
|
122
|
+
if field = self.class.get_field(name, true)
|
304
123
|
__send__(field.name)
|
305
124
|
end
|
306
125
|
end
|
307
126
|
|
308
127
|
def []=(name, value)
|
309
|
-
if field =
|
128
|
+
if field = self.class.get_field(name, true)
|
310
129
|
__send__(field.setter_method_name, value)
|
311
130
|
end
|
312
131
|
end
|
@@ -314,14 +133,6 @@ module Protobuf
|
|
314
133
|
##
|
315
134
|
# Instance Aliases
|
316
135
|
#
|
317
|
-
alias_method :parse_from_string, :decode
|
318
|
-
alias_method :deserialize, :decode
|
319
|
-
alias_method :parse_from, :decode_from
|
320
|
-
alias_method :deserialize_from, :decode_from
|
321
|
-
alias_method :to_s, :encode
|
322
|
-
alias_method :bytes, :encode
|
323
|
-
alias_method :serialize, :encode
|
324
|
-
alias_method :serialize_to_string, :encode
|
325
136
|
alias_method :to_hash_value, :to_hash
|
326
137
|
alias_method :to_proto_hash, :to_hash
|
327
138
|
alias_method :responds_to_has?, :respond_to_has?
|
@@ -358,16 +169,5 @@ module Protobuf
|
|
358
169
|
object
|
359
170
|
end
|
360
171
|
|
361
|
-
def __field_must_be_serialized__?(field)
|
362
|
-
field.required? || !@values[field.name].nil?
|
363
|
-
end
|
364
|
-
|
365
|
-
# Encode key and value, and write to +stream+.
|
366
|
-
def write_pair(stream, field, value)
|
367
|
-
key = (field.tag << 3) | field.wire_type
|
368
|
-
stream << ::Protobuf::Field::VarintField.encode(key)
|
369
|
-
stream << field.encode(value)
|
370
|
-
end
|
371
|
-
|
372
172
|
end
|
373
173
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Optionable
|
5
|
+
extend ::ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def get_option(name)
|
9
|
+
@_optionable_options.try(:[], name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def set_option(name, value = true)
|
13
|
+
@_optionable_options ||= {}
|
14
|
+
@_optionable_options[name] = value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_option(name)
|
19
|
+
self.class.get_option(name)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|