protobuf 2.0.0.rc2 → 2.0.0.rc3
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.
- data/.gitignore +1 -0
- data/ext/ruby_generator/Makefile +10 -0
- data/ext/ruby_generator/RubyGenerator.cpp +85 -70
- data/ext/ruby_generator/RubyGenerator.h +23 -4
- data/lib/protobuf.rb +33 -26
- data/lib/protobuf/cli.rb +18 -13
- data/lib/protobuf/enum.rb +39 -34
- data/lib/protobuf/enum_value.rb +29 -0
- data/lib/protobuf/field/base_field.rb +34 -5
- data/lib/protobuf/field/enum_field.rb +6 -14
- data/lib/protobuf/field/extension_fields.rb +13 -5
- data/lib/protobuf/field/field_array.rb +17 -7
- data/lib/protobuf/field/varint_field.rb +4 -6
- data/lib/protobuf/message.rb +44 -148
- data/lib/protobuf/rpc/server.rb +2 -2
- data/lib/protobuf/version.rb +1 -1
- data/spec/benchmark/tasks.rb +7 -8
- data/spec/functional/evented_server_spec.rb +9 -9
- data/spec/functional/socket_server_spec.rb +8 -8
- data/spec/functional/zmq_server_spec.rb +8 -8
- data/spec/lib/protobuf/cli_spec.rb +30 -11
- data/spec/lib/protobuf/enum_spec.rb +90 -0
- data/spec/lib/protobuf/enum_value_spec.rb +13 -0
- data/spec/lib/protobuf/message/encoder_spec.rb +1 -1
- data/spec/lib/protobuf/message_spec.rb +50 -0
- data/spec/lib/protobuf/rpc/client_spec.rb +23 -23
- data/spec/lib/protobuf/rpc/servers/evented_server_spec.rb +1 -1
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +1 -1
- data/spec/lib/protobuf/rpc/service_spec.rb +18 -18
- data/spec/lib/protobuf_spec.rb +62 -0
- data/spec/spec_helper.rb +12 -1
- data/spec/support/all.rb +0 -1
- data/spec/support/server.rb +1 -1
- data/spec/support/test/enum.pb.rb +32 -0
- data/spec/support/test/enum.proto +12 -0
- data/spec/support/test/resource.pb.rb +52 -0
- data/spec/{proto/test.proto → support/test/resource.proto} +2 -2
- data/spec/support/test/resource_service.rb +14 -0
- metadata +51 -48
- data/ext/Makefile +0 -11
- data/spec/lib/protobuf/message/enum_spec.rb +0 -13
- data/spec/lib/protobuf/message/message_spec.rb +0 -67
- data/spec/proto/test.pb.rb +0 -54
- data/spec/proto/test_service.rb +0 -30
- data/spec/proto/test_service_impl.rb +0 -18
- data/spec/support/silent_constants.rb +0 -44
data/lib/protobuf/enum.rb
CHANGED
@@ -1,52 +1,57 @@
|
|
1
|
-
require '
|
1
|
+
require 'protobuf/enum_value'
|
2
2
|
|
3
3
|
module Protobuf
|
4
4
|
class Enum
|
5
|
-
class << self
|
6
|
-
attr_reader :values
|
7
|
-
|
8
|
-
def name_by_value(value)
|
9
|
-
if not defined?(@values)
|
10
|
-
constants.find {|c| const_get(c) == value} # for compatibility
|
11
|
-
else
|
12
|
-
@values_index ||= @values.inject({}) {|hash, (n, v)| hash[v.value] = n; hash }
|
13
|
-
@values_index[value]
|
14
|
-
end
|
15
|
-
end
|
16
5
|
|
17
|
-
|
6
|
+
def self.define(name, value)
|
7
|
+
enum_value = ::Protobuf::EnumValue.new(self, name, value)
|
8
|
+
const_set(name, enum_value)
|
9
|
+
@values ||= {}
|
10
|
+
@names ||= []
|
11
|
+
@values[name] = enum_value
|
12
|
+
@names[value] = name
|
13
|
+
end
|
18
14
|
|
19
|
-
|
20
|
-
|
15
|
+
# Fetch the given enum by a variety of type-checking
|
16
|
+
# mechanisms. This is useful for the enum field setters
|
17
|
+
# as well as repeated enum field construction.
|
18
|
+
def self.fetch(value)
|
19
|
+
if value.is_a?(::Protobuf::EnumValue)
|
20
|
+
value
|
21
|
+
elsif value.respond_to?(:to_sym)
|
22
|
+
value_by_name(value.to_sym) rescue nil
|
23
|
+
elsif value.respond_to?(:to_i)
|
24
|
+
enum_by_value(value.to_i) rescue nil
|
25
|
+
else
|
26
|
+
nil
|
21
27
|
end
|
28
|
+
end
|
22
29
|
|
23
|
-
|
24
|
-
|
25
|
-
const_set(name, enum_value)
|
26
|
-
@values ||= {}
|
27
|
-
@values[name] = enum_value
|
28
|
-
end
|
30
|
+
def self.enum_by_value(value)
|
31
|
+
value_by_name(name_by_value(value))
|
29
32
|
end
|
30
|
-
end
|
31
33
|
|
32
|
-
|
34
|
+
def self.name_by_value(value)
|
35
|
+
@names[value]
|
36
|
+
end
|
33
37
|
|
34
|
-
|
38
|
+
def self.valid_tag?(tag)
|
39
|
+
!! name_by_value(tag)
|
40
|
+
end
|
35
41
|
|
36
|
-
def
|
37
|
-
@
|
38
|
-
@name = name
|
39
|
-
@value = value
|
40
|
-
super(@value)
|
42
|
+
def self.value_by_name(name)
|
43
|
+
@values[name]
|
41
44
|
end
|
42
45
|
|
43
|
-
def
|
44
|
-
@
|
46
|
+
def self.values
|
47
|
+
@values
|
45
48
|
end
|
46
49
|
|
47
|
-
|
48
|
-
|
50
|
+
##
|
51
|
+
# Class Aliases
|
52
|
+
#
|
53
|
+
class << self
|
54
|
+
alias_method :get_name_by_tag, :name_by_value
|
49
55
|
end
|
50
56
|
end
|
51
|
-
|
52
57
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'protobuf/enum'
|
3
|
+
|
4
|
+
module Protobuf
|
5
|
+
class EnumValue < SimpleDelegator
|
6
|
+
|
7
|
+
attr_reader :parent_class, :name, :value
|
8
|
+
|
9
|
+
def initialize(parent_class, name, value)
|
10
|
+
@parent_class = parent_class
|
11
|
+
@name = name
|
12
|
+
@value = value
|
13
|
+
super(@value)
|
14
|
+
end
|
15
|
+
|
16
|
+
def inspect
|
17
|
+
"\#<#{self.class} #{@parent_class}::#{@name}=#{@value}>"
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_hash_value
|
21
|
+
self.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
@name.to_s
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -8,7 +8,7 @@ module Protobuf
|
|
8
8
|
# Attributes
|
9
9
|
#
|
10
10
|
attr_reader :message_class, :rule, :type, :name, :tag, :default, :default_value, :setter_method_name, :getter_method_name
|
11
|
-
|
11
|
+
|
12
12
|
##
|
13
13
|
# Class Methods
|
14
14
|
#
|
@@ -28,6 +28,7 @@ module Protobuf
|
|
28
28
|
@default = options.delete(:default)
|
29
29
|
@extension = options.delete(:extension)
|
30
30
|
@packed = repeated? && options.delete(:packed)
|
31
|
+
@deprecated = options.delete(:deprecated)
|
31
32
|
unless options.empty?
|
32
33
|
warn "WARNING: Invalid options: #{options.inspect} (in #{@message_class.name.split('::').last}.#{@name})"
|
33
34
|
end
|
@@ -134,9 +135,14 @@ module Protobuf
|
|
134
135
|
@_optional = (@rule == :optional)
|
135
136
|
end
|
136
137
|
|
138
|
+
# Is this a deprecated field?
|
139
|
+
def deprecated?
|
140
|
+
!! @deprecated
|
141
|
+
end
|
142
|
+
|
137
143
|
# Is this a packed repeated field?
|
138
144
|
def packed?
|
139
|
-
|
145
|
+
!! @packed
|
140
146
|
end
|
141
147
|
|
142
148
|
# Upper limit for this field.
|
@@ -153,24 +159,42 @@ module Protobuf
|
|
153
159
|
"#{@rule} #{@type} #{@name} = #{@tag} #{@default ? "[default=#{@default.inspect}]" : ''}"
|
154
160
|
end
|
155
161
|
|
162
|
+
def warn_if_deprecated
|
163
|
+
if ::Protobuf.print_deprecation_warnings? && deprecated?
|
164
|
+
$stderr.puts("[WARNING] #{@message_class.name}##{@name} field usage is deprecated.")
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
156
168
|
private
|
157
169
|
|
158
|
-
##
|
170
|
+
##
|
159
171
|
# Private Instance Methods
|
160
172
|
#
|
161
173
|
def define_accessor
|
162
|
-
define_getter
|
163
174
|
if repeated?
|
175
|
+
define_array_getter
|
164
176
|
define_array_setter
|
165
177
|
else
|
178
|
+
define_getter
|
166
179
|
define_setter
|
167
180
|
end
|
168
181
|
end
|
169
182
|
|
183
|
+
def define_array_getter
|
184
|
+
field = self
|
185
|
+
@message_class.class_eval do
|
186
|
+
define_method(field.getter_method_name) do
|
187
|
+
@values[field.name] ||= ::Protobuf::Field::FieldArray.new(field)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
170
192
|
def define_array_setter
|
171
193
|
field = self
|
172
194
|
@message_class.class_eval do
|
173
195
|
define_method(field.setter_method_name) do |val|
|
196
|
+
field.warn_if_deprecated
|
197
|
+
@values[field.name] ||= ::Protobuf::Field::FieldArray.new(field)
|
174
198
|
@values[field.name].replace(val)
|
175
199
|
end
|
176
200
|
end
|
@@ -180,6 +204,7 @@ module Protobuf
|
|
180
204
|
field = self
|
181
205
|
@message_class.class_eval do
|
182
206
|
define_method(field.getter_method_name) do
|
207
|
+
field.warn_if_deprecated
|
183
208
|
@values.fetch(field.name, field.default_value)
|
184
209
|
end
|
185
210
|
end
|
@@ -189,10 +214,13 @@ module Protobuf
|
|
189
214
|
field = self
|
190
215
|
@message_class.class_eval do
|
191
216
|
define_method(field.setter_method_name) do |val|
|
217
|
+
field.warn_if_deprecated
|
192
218
|
if val.nil?
|
193
219
|
@values.delete(field.name)
|
194
220
|
elsif field.acceptable?(val)
|
195
221
|
@values[field.name] = val
|
222
|
+
else
|
223
|
+
raise TypeError, "unacceptable value #{val} for type #{field.type}"
|
196
224
|
end
|
197
225
|
end
|
198
226
|
end
|
@@ -205,6 +233,7 @@ module Protobuf
|
|
205
233
|
@default
|
206
234
|
end
|
207
235
|
end
|
208
|
-
|
236
|
+
|
237
|
+
end
|
209
238
|
end
|
210
239
|
end
|
@@ -32,23 +32,15 @@ module Protobuf
|
|
32
32
|
def define_setter
|
33
33
|
field = self
|
34
34
|
@message_class.class_eval do
|
35
|
-
define_method("#{field.name}=") do |
|
36
|
-
|
35
|
+
define_method("#{field.name}=") do |value|
|
36
|
+
orig_value = value
|
37
|
+
if value.nil?
|
37
38
|
@values.delete(field.name)
|
38
39
|
else
|
39
|
-
|
40
|
-
|
41
|
-
when Symbol then
|
42
|
-
field.type.const_get(val) rescue nil
|
43
|
-
when Integer then
|
44
|
-
field.type.const_get(field.type.name_by_value(val)) rescue nil
|
45
|
-
when EnumValue then
|
46
|
-
raise TypeError, "Invalid value: #{val.inspect} for #{field.name}" if val.parent_class != field.type
|
47
|
-
val
|
48
|
-
end
|
49
|
-
raise TypeError, "Invalid value: #{val.inspect} for #{field.name}" unless val
|
40
|
+
value = field.type.fetch(value)
|
41
|
+
raise TypeError, "Invalid ENUM value: #{orig_value.inspect} for #{field.name}" unless value
|
50
42
|
|
51
|
-
@values[field.name] =
|
43
|
+
@values[field.name] = value
|
52
44
|
end
|
53
45
|
end
|
54
46
|
end
|
@@ -1,23 +1,31 @@
|
|
1
1
|
module Protobuf
|
2
2
|
module Field
|
3
|
-
class ExtensionFields <
|
3
|
+
class ExtensionFields < Array
|
4
4
|
##
|
5
5
|
# Constructor
|
6
6
|
#
|
7
|
-
def initialize
|
8
|
-
@
|
7
|
+
def initialize
|
8
|
+
@ranges = []
|
9
9
|
end
|
10
10
|
|
11
11
|
##
|
12
12
|
# Public Instance Methods
|
13
13
|
#
|
14
|
+
|
15
|
+
# Append a range to the list of ranges.
|
16
|
+
def add_range(range = (0..-1))
|
17
|
+
@ranges << range
|
18
|
+
end
|
19
|
+
|
20
|
+
# Set value at tag location, if tag is in a valid range.
|
14
21
|
def []=(key, value)
|
15
|
-
raise RangeError, "#{key} is not in #{@
|
22
|
+
raise RangeError, "#{key} is not in #{@ranges.join(', ')}" unless include_tag?(key)
|
16
23
|
super
|
17
24
|
end
|
18
25
|
|
26
|
+
# Check if the given tag exists in any of the defined ranges.
|
19
27
|
def include_tag?(tag)
|
20
|
-
@
|
28
|
+
@ranges.any? { |range| range.include?(tag) }
|
21
29
|
end
|
22
30
|
end
|
23
31
|
end
|
@@ -8,7 +8,7 @@ module Protobuf
|
|
8
8
|
@field = field
|
9
9
|
end
|
10
10
|
|
11
|
-
##
|
11
|
+
##
|
12
12
|
# Public Instance Methods
|
13
13
|
#
|
14
14
|
def []=(nth, val)
|
@@ -33,21 +33,31 @@ module Protobuf
|
|
33
33
|
super(val)
|
34
34
|
end
|
35
35
|
|
36
|
+
# Return a hash-representation of the given values for this field type.
|
37
|
+
# The value in this case would be an array.
|
38
|
+
def to_hash_value
|
39
|
+
self.map do |value|
|
40
|
+
value.respond_to?(:to_hash_value) ? value.to_hash_value : value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
36
44
|
def to_s
|
37
45
|
"[#{@field.name}]"
|
38
46
|
end
|
39
|
-
|
47
|
+
|
40
48
|
private
|
41
49
|
|
42
50
|
##
|
43
51
|
# Private Instance Methods
|
44
52
|
#
|
45
|
-
def normalize(
|
46
|
-
raise TypeError unless @field.acceptable?(
|
47
|
-
if @field.is_a?(::Protobuf::Field::
|
48
|
-
@field.type.
|
53
|
+
def normalize(value)
|
54
|
+
raise TypeError unless @field.acceptable?(value)
|
55
|
+
if @field.is_a?(::Protobuf::Field::EnumField)
|
56
|
+
@field.type.fetch(value)
|
57
|
+
elsif @field.is_a?(::Protobuf::Field::MessageField) && value.is_a?(Hash)
|
58
|
+
@field.type.new(value)
|
49
59
|
else
|
50
|
-
|
60
|
+
value
|
51
61
|
end
|
52
62
|
end
|
53
63
|
end
|
@@ -4,8 +4,8 @@ module Protobuf
|
|
4
4
|
module Field
|
5
5
|
class VarintField < BaseField
|
6
6
|
INT32_MAX = 2**31 - 1
|
7
|
-
INT32_MIN = -2**31
|
8
|
-
INT64_MAX = 2**63 - 1
|
7
|
+
INT32_MIN = -2**31
|
8
|
+
INT64_MAX = 2**63 - 1
|
9
9
|
INT64_MIN = -2**63
|
10
10
|
UINT32_MAX = 2**32 - 1
|
11
11
|
UINT64_MAX = 2**64 - 1
|
@@ -26,8 +26,8 @@ module Protobuf
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.encode(value)
|
29
|
-
raise RangeError, "#{value} is negative" if value < 0
|
30
29
|
return [value].pack('C') if value < 128
|
30
|
+
|
31
31
|
bytes = []
|
32
32
|
until value == 0
|
33
33
|
bytes << (0x80 | (value & 0x7f))
|
@@ -41,9 +41,7 @@ module Protobuf
|
|
41
41
|
# Public Instance Methods
|
42
42
|
#
|
43
43
|
def acceptable?(val)
|
44
|
-
|
45
|
-
raise RangeError if val < min || max < val
|
46
|
-
true
|
44
|
+
(val > min || val < max) rescue false
|
47
45
|
end
|
48
46
|
|
49
47
|
def decode(value)
|
data/lib/protobuf/message.rb
CHANGED
@@ -8,22 +8,21 @@ module Protobuf
|
|
8
8
|
class Message
|
9
9
|
STRING_ENCODING = "ASCII-8BIT".freeze
|
10
10
|
|
11
|
-
def self.inherited(klass)
|
12
|
-
@_children ||= Set.new
|
13
|
-
@_children << klass
|
14
|
-
end
|
15
|
-
|
16
11
|
def self.all_fields
|
17
12
|
@all_fields ||= begin
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
all_fields_array = []
|
14
|
+
max_fields = fields.size > extension_fields.size ? fields.size : extension_fields.size
|
15
|
+
max_fields.times do |field_number|
|
16
|
+
all_fields_array << (fields[field_number] || extension_fields[field_number])
|
17
|
+
end
|
18
|
+
all_fields_array.compact!
|
19
|
+
all_fields_array
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
24
23
|
# Reserve field numbers for extensions. Don't use this method directly.
|
25
24
|
def self.extensions(range)
|
26
|
-
|
25
|
+
extension_fields.add_range(range)
|
27
26
|
end
|
28
27
|
|
29
28
|
# Define a required field. Don't use this method directly.
|
@@ -43,18 +42,16 @@ module Protobuf
|
|
43
42
|
|
44
43
|
# Define a field. Don't use this method directly.
|
45
44
|
def self.define_field(rule, type, fname, tag, options)
|
46
|
-
|
47
|
-
field_name_hash = options[:extension] ?
|
48
|
-
repeated_collection = options[:extension] ? repeated_extension_fields : repeated_fields
|
45
|
+
field_array = options[:extension] ? extension_fields : fields
|
46
|
+
field_name_hash = options[:extension] ? extension_field_name_to_tag : field_name_to_tag
|
49
47
|
|
50
|
-
if
|
48
|
+
if field_array[tag]
|
51
49
|
raise TagCollisionError, %!{Field number #{tag} has already been used in "#{self.name}" by field "#{fname}".!
|
52
50
|
end
|
53
51
|
|
54
52
|
field_definition = Field.build(self, rule, type, fname, tag, options)
|
55
|
-
field_name_hash[fname
|
56
|
-
|
57
|
-
field_hash[tag] = field_definition
|
53
|
+
field_name_hash[fname] = tag
|
54
|
+
field_array[tag] = field_definition
|
58
55
|
end
|
59
56
|
|
60
57
|
def self.extension_tag?(tag)
|
@@ -66,31 +63,23 @@ module Protobuf
|
|
66
63
|
@extension_fields ||= ::Protobuf::Field::ExtensionFields.new
|
67
64
|
end
|
68
65
|
|
69
|
-
def self.
|
66
|
+
def self.extension_field_name_to_tag
|
70
67
|
@extension_fields_by_name ||= {}
|
71
68
|
end
|
72
69
|
|
73
70
|
# A collection of field object.
|
74
71
|
def self.fields
|
75
|
-
@fields ||=
|
72
|
+
@fields ||= []
|
76
73
|
end
|
77
74
|
|
78
|
-
def self.
|
79
|
-
@
|
80
|
-
end
|
81
|
-
|
82
|
-
def self.repeated_fields
|
83
|
-
@repeated_fields ||= []
|
84
|
-
end
|
85
|
-
|
86
|
-
def self.repeated_extension_fields
|
87
|
-
@repeated_extension_fields ||= []
|
75
|
+
def self.field_name_to_tag
|
76
|
+
@field_name_to_tag ||= {}
|
88
77
|
end
|
89
78
|
|
90
79
|
# Find a field object by +name+.
|
91
80
|
def self.get_field_by_name(name)
|
92
81
|
# Check if the name has been used before, if not then set it to the sym value
|
93
|
-
|
82
|
+
fields[field_name_to_tag[name]]
|
94
83
|
end
|
95
84
|
|
96
85
|
# Find a field object by +tag+ number.
|
@@ -98,62 +87,30 @@ module Protobuf
|
|
98
87
|
fields[tag]
|
99
88
|
end
|
100
89
|
|
101
|
-
def self.field_cache
|
102
|
-
@field_cache ||= {}
|
103
|
-
end
|
104
|
-
|
105
|
-
# Find a field object by +tag_or_name+.
|
106
|
-
def self.get_field(tag_or_name)
|
107
|
-
field_cache[tag_or_name] ||= case tag_or_name
|
108
|
-
when Integer then get_field_by_tag(tag_or_name)
|
109
|
-
when String, Symbol then get_field_by_name(tag_or_name)
|
110
|
-
else raise TypeError, tag_or_name.class
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
90
|
def self.get_ext_field_by_name(name)
|
115
91
|
# Check if the name has been used before, if not then set it to the sym value
|
116
|
-
|
92
|
+
extension_fields[extension_field_name_to_tag[name]]
|
117
93
|
end
|
118
94
|
|
119
95
|
def self.get_ext_field_by_tag(tag)
|
120
96
|
extension_fields[tag]
|
121
97
|
end
|
122
98
|
|
123
|
-
def self.get_ext_field(tag_or_name)
|
124
|
-
case tag_or_name
|
125
|
-
when Integer then get_ext_field_by_tag(tag_or_name)
|
126
|
-
when String, Symbol then get_ext_field_by_name(tag_or_name)
|
127
|
-
else raise TypeError, tag_or_name.class
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
99
|
##
|
132
100
|
# Constructor
|
133
101
|
#
|
134
102
|
def initialize(values={})
|
135
103
|
@values = {}
|
136
104
|
|
137
|
-
|
138
|
-
@values[field.name] = Field::FieldArray.new(field)
|
139
|
-
end
|
140
|
-
|
141
|
-
self.class.repeated_extension_fields.each do |field|
|
142
|
-
@values[field.name] = Field::FieldArray.new(field)
|
143
|
-
end
|
144
|
-
|
145
|
-
values.each { |tag, val| self[tag] = val}
|
105
|
+
values.each { |name, val| self[name] = val}
|
146
106
|
end
|
147
107
|
|
148
108
|
def initialized?
|
149
|
-
|
150
|
-
extension_fields.all? {|tag, field| field.initialized?(self) }
|
109
|
+
all_fields.all? { |field| field.initialized?(self) }
|
151
110
|
end
|
152
111
|
|
153
|
-
def has_field?(
|
154
|
-
|
155
|
-
raise ArgumentError, "unknown field: #{tag_or_name.inspect}" unless field
|
156
|
-
@values.has_key?(field.name)
|
112
|
+
def has_field?(name)
|
113
|
+
@values.has_key?(name)
|
157
114
|
end
|
158
115
|
|
159
116
|
def ==(obj)
|
@@ -204,42 +161,8 @@ module Protobuf
|
|
204
161
|
end
|
205
162
|
private :copy_to
|
206
163
|
|
207
|
-
def inspect
|
208
|
-
|
209
|
-
i = ' ' * indent
|
210
|
-
field_value_to_string = lambda { |field, value|
|
211
|
-
result << \
|
212
|
-
if field.optional? && ! has_field?(field.name)
|
213
|
-
''
|
214
|
-
else
|
215
|
-
case field
|
216
|
-
when Field::MessageField then
|
217
|
-
if value.nil?
|
218
|
-
"#{i}#{field.name} {}\n"
|
219
|
-
else
|
220
|
-
"#{i}#{field.name} {\n#{value.inspect(indent + 1)}#{i}}\n"
|
221
|
-
end
|
222
|
-
when Field::EnumField then
|
223
|
-
if value.is_a?(EnumValue)
|
224
|
-
"#{i}#{field.name}: #{value.name}\n"
|
225
|
-
else
|
226
|
-
"#{i}#{field.name}: #{field.type.name_by_value(value)}\n"
|
227
|
-
end
|
228
|
-
else
|
229
|
-
"#{i}#{field.name}: #{value.inspect}\n"
|
230
|
-
end
|
231
|
-
end
|
232
|
-
}
|
233
|
-
each_field do |field, value|
|
234
|
-
if field.repeated?
|
235
|
-
value.each do |v|
|
236
|
-
field_value_to_string.call(field, v)
|
237
|
-
end
|
238
|
-
else
|
239
|
-
field_value_to_string.call(field, value)
|
240
|
-
end
|
241
|
-
end
|
242
|
-
result.join
|
164
|
+
def inspect
|
165
|
+
to_hash.inspect
|
243
166
|
end
|
244
167
|
|
245
168
|
def parse_from_string(string)
|
@@ -268,30 +191,29 @@ module Protobuf
|
|
268
191
|
field.set(self, bytes) if field
|
269
192
|
end
|
270
193
|
|
271
|
-
def [](
|
272
|
-
if field =
|
194
|
+
def [](name)
|
195
|
+
if field = get_field_by_name(name) || get_ext_field_by_name(name)
|
273
196
|
__send__(field.name)
|
274
197
|
else
|
275
|
-
raise NoMethodError, "No such field: #{
|
198
|
+
raise NoMethodError, "No such field: #{name.inspect}"
|
276
199
|
end
|
277
200
|
end
|
278
201
|
|
279
|
-
def []=(
|
280
|
-
if field =
|
281
|
-
# __send__("#{field.name}=", value)
|
202
|
+
def []=(name, value)
|
203
|
+
if field = get_field_by_name(name) || get_ext_field_by_name(name)
|
282
204
|
__send__(field.setter_method_name, value)
|
283
205
|
else
|
284
|
-
raise NoMethodError, "No such field: #{
|
206
|
+
raise NoMethodError, "No such field: #{name.inspect}"
|
285
207
|
end
|
286
208
|
end
|
287
209
|
|
288
210
|
# Returns a hash; which key is a tag number, and value is a field object.
|
289
211
|
def all_fields
|
290
|
-
|
212
|
+
self.class.all_fields
|
291
213
|
end
|
292
214
|
|
293
215
|
def fields
|
294
|
-
|
216
|
+
self.class.fields
|
295
217
|
end
|
296
218
|
|
297
219
|
# Returns field object or +nil+.
|
@@ -304,11 +226,6 @@ module Protobuf
|
|
304
226
|
self.class.get_field_by_tag(tag)
|
305
227
|
end
|
306
228
|
|
307
|
-
# Returns field object or +nil+.
|
308
|
-
def get_field(tag_or_name)
|
309
|
-
self.class.get_field(tag_or_name)
|
310
|
-
end
|
311
|
-
|
312
229
|
# Returns extension fields. See Message#fields method.
|
313
230
|
def extension_fields
|
314
231
|
self.class.extension_fields
|
@@ -322,10 +239,6 @@ module Protobuf
|
|
322
239
|
self.class.get_ext_field_by_tag(tag)
|
323
240
|
end
|
324
241
|
|
325
|
-
def get_ext_field(tag_or_name) # :nodoc:
|
326
|
-
self.class.get_ext_field(tag_or_name)
|
327
|
-
end
|
328
|
-
|
329
242
|
# Iterate over a field collection.
|
330
243
|
# message.each_field do |field_object, value|
|
331
244
|
# # do something
|
@@ -337,40 +250,23 @@ module Protobuf
|
|
337
250
|
end
|
338
251
|
end
|
339
252
|
|
253
|
+
# Return a hash-representation of the given fields for this message type.
|
340
254
|
def to_hash
|
341
|
-
result =
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
when Field::EnumField then
|
348
|
-
if value.is_a?(EnumValue)
|
349
|
-
value.to_i
|
350
|
-
elsif value.is_a?(Symbol)
|
351
|
-
field.type[value].to_i
|
352
|
-
else
|
353
|
-
value
|
354
|
-
end
|
355
|
-
else
|
356
|
-
value
|
357
|
-
end
|
358
|
-
end
|
359
|
-
}
|
360
|
-
each_field do |field, value|
|
361
|
-
if field.repeated?
|
362
|
-
result[field.name] = value.map do |v|
|
363
|
-
build_value.call(field, v)
|
364
|
-
end
|
365
|
-
else
|
366
|
-
result[field.name] = build_value.call(field, value)
|
367
|
-
end
|
255
|
+
result = Hash.new
|
256
|
+
|
257
|
+
@values.keys.each do |field_name|
|
258
|
+
value = __send__(field_name)
|
259
|
+
hashed_value = value.respond_to?(:to_hash_value) ? value.to_hash_value : value
|
260
|
+
result.merge!(field_name => hashed_value)
|
368
261
|
end
|
369
|
-
|
262
|
+
|
263
|
+
return result
|
370
264
|
end
|
265
|
+
alias_method :to_hash_value, :to_hash
|
371
266
|
|
372
267
|
def to_json
|
373
268
|
to_hash.to_json
|
374
269
|
end
|
270
|
+
|
375
271
|
end
|
376
272
|
end
|