ruby_protobuf 0.3.3 → 0.4.1

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.
Files changed (78) hide show
  1. data/History.txt +10 -2
  2. data/Manifest.txt +26 -12
  3. data/README.txt +6 -1
  4. data/Rakefile +51 -14
  5. data/TODO +15 -0
  6. data/VERSION +1 -0
  7. data/bin/rprotoc +11 -6
  8. data/lib/protobuf/common/exceptions.rb +11 -0
  9. data/lib/protobuf/common/util.rb +9 -0
  10. data/lib/protobuf/common/wire_type.rb +6 -6
  11. data/lib/protobuf/compiler/compiler.rb +16 -16
  12. data/lib/protobuf/compiler/nodes.rb +67 -65
  13. data/lib/protobuf/compiler/proto.y +31 -38
  14. data/lib/protobuf/compiler/proto_parser.rb +315 -294
  15. data/lib/protobuf/compiler/template/rpc_bin.erb +1 -1
  16. data/lib/protobuf/compiler/template/rpc_client.erb +1 -1
  17. data/lib/protobuf/compiler/template/rpc_service.erb +2 -2
  18. data/lib/protobuf/compiler/visitors.rb +45 -39
  19. data/lib/protobuf/descriptor/descriptor.proto +0 -0
  20. data/lib/protobuf/descriptor/descriptor.rb +11 -10
  21. data/lib/protobuf/descriptor/descriptor_builder.rb +6 -7
  22. data/lib/protobuf/descriptor/descriptor_proto.rb +51 -31
  23. data/lib/protobuf/descriptor/enum_descriptor.rb +5 -5
  24. data/lib/protobuf/descriptor/field_descriptor.rb +8 -9
  25. data/lib/protobuf/descriptor/file_descriptor.rb +0 -1
  26. data/lib/protobuf/message/decoder.rb +33 -35
  27. data/lib/protobuf/message/encoder.rb +23 -19
  28. data/lib/protobuf/message/enum.rb +43 -9
  29. data/lib/protobuf/message/field.rb +281 -193
  30. data/lib/protobuf/message/message.rb +166 -110
  31. data/lib/protobuf/message/protoable.rb +4 -3
  32. data/lib/protobuf/message/service.rb +1 -1
  33. data/lib/protobuf/rpc/client.rb +3 -3
  34. data/lib/protobuf/rpc/handler.rb +1 -1
  35. data/lib/protobuf/rpc/server.rb +8 -8
  36. data/lib/ruby_protobuf.rb +1 -1
  37. data/test/check_unbuild.rb +7 -7
  38. data/test/proto/addressbook.pb.rb +67 -0
  39. data/test/proto/addressbook.proto +2 -0
  40. data/test/proto/addressbook_base.pb.rb +59 -0
  41. data/test/proto/addressbook_base.proto +1 -1
  42. data/test/proto/addressbook_ext.pb.rb +21 -0
  43. data/test/proto/addressbook_ext.proto +2 -2
  44. data/test/{collision.rb → proto/collision.pb.rb} +0 -0
  45. data/test/{ext_collision.rb → proto/ext_collision.pb.rb} +1 -1
  46. data/test/{ext_range.rb → proto/ext_range.pb.rb} +4 -4
  47. data/test/proto/ext_range.proto +2 -2
  48. data/test/proto/float_default.proto +10 -0
  49. data/test/proto/lowercase.pb.rb +31 -0
  50. data/test/proto/lowercase.proto +9 -0
  51. data/test/{merge.rb → proto/merge.pb.rb} +2 -2
  52. data/test/proto/nested.pb.rb +31 -0
  53. data/test/proto/nested.proto +2 -0
  54. data/test/proto/optional_field.pb.rb +36 -0
  55. data/test/proto/optional_field.proto +12 -0
  56. data/test/proto/packed.pb.rb +23 -0
  57. data/test/proto/packed.proto +6 -0
  58. data/test/{types.rb → proto/types.pb.rb} +43 -1
  59. data/test/test_addressbook.rb +30 -17
  60. data/test/test_compiler.rb +79 -78
  61. data/test/test_descriptor.rb +12 -12
  62. data/test/test_enum_value.rb +41 -0
  63. data/test/test_extension.rb +10 -14
  64. data/test/test_lowercase.rb +11 -0
  65. data/test/test_message.rb +44 -41
  66. data/test/test_optional_field.rb +61 -38
  67. data/test/test_packed_field.rb +40 -0
  68. data/test/test_parse.rb +8 -8
  69. data/test/test_repeated_types.rb +29 -3
  70. data/test/test_serialize.rb +12 -12
  71. data/test/test_standard_message.rb +30 -30
  72. data/test/test_types.rb +95 -95
  73. metadata +69 -39
  74. data/test/addressbook.rb +0 -98
  75. data/test/addressbook_base.rb +0 -62
  76. data/test/addressbook_ext.rb +0 -12
  77. data/test/nested.rb +0 -25
  78. data/test/test_ruby_protobuf.rb +0 -1
@@ -1,91 +1,178 @@
1
+ require 'protobuf/common/util'
1
2
  require 'protobuf/common/wire_type'
2
3
  require 'protobuf/descriptor/field_descriptor'
3
4
 
4
5
  module Protobuf
5
6
  module Field
6
- def self.build(message_class, rule, type, name, tag, opts={})
7
- field_class =
8
- if [:double, :float, :int32, :int64, :uint32, :uint64,
9
- :sint32, :sint64, :fixed32, :fixed64, :sfixed32, :sfixed64,
10
- :bool, :string, :bytes].include? type
11
- eval "Protobuf::Field::#{type.to_s.capitalize}Field"
7
+
8
+ PREDEFINED_TYPES = [
9
+ :double, :float,
10
+ :int32, :int64,
11
+ :uint32, :uint64,
12
+ :sint32, :sint64,
13
+ :fixed32, :fixed64,
14
+ :sfixed32, :sfixed64,
15
+ :string, :bytes,
16
+ :bool,
17
+ ].freeze
18
+
19
+ def self.build(message_class, rule, type, name, tag, options={})
20
+ field_class = \
21
+ if PREDEFINED_TYPES.include?(type)
22
+ const_get("#{type.to_s.capitalize}Field")
12
23
  else
13
- Protobuf::Field::FieldProxy
24
+ FieldProxy
14
25
  end
15
- field_class.new message_class, rule, type, name, tag, opts
26
+ field_class.new(message_class, rule, type, name, tag, options)
16
27
  end
17
28
 
18
- class InvalidRuleError < StandardError; end
19
-
20
29
  class BaseField
21
- class <<self
22
- def descriptor
23
- @descriptor ||= Protobuf::Descriptor::FieldDescriptor.new
24
- end
25
30
 
26
- def default; nil end
31
+ def self.descriptor
32
+ @descriptor ||= Descriptor::FieldDescriptor.new
33
+ end
34
+
35
+ def self.default
36
+ nil
27
37
  end
28
38
 
29
- attr_accessor :message_class, :rule, :type, :name, :tag, :default
39
+ attr_reader :message_class, :rule, :type, :name, :tag, :default
40
+ attr_reader :default_value
30
41
 
31
42
  def descriptor
32
- @descriptor ||= Protobuf::Descriptor::FieldDescriptor.new self
43
+ @descriptor ||= Descriptor::FieldDescriptor.new(self)
33
44
  end
34
45
 
35
- def initialize(message_class, rule, type, name, tag, opts={})
36
- @message_class, @rule, @type, @name, @tag, @default, @extension =
37
- message_class, rule, type, name, tag, opts[:default], opts[:extension]
38
- @error_message = 'Type invalid'
46
+ def initialize(message_class, rule, type, name, tag, options)
47
+ @message_class, @rule, @type, @name, @tag = \
48
+ message_class, rule, type, name, tag
49
+
50
+ @default = options.delete(:default)
51
+ @extension = options.delete(:extension)
52
+ @packed = repeated? && options.delete(:packed)
53
+ unless options.empty?
54
+ warn "WARNING: Invalid options: #{options.inspect} (in #{@message_class.name.split('::').last}.#{@name})"
55
+ end
56
+ if packed? && ! [WireType::VARINT, WireType::FIXED32, WireType::FIXED64].include?(wire_type)
57
+ raise "Can't use packed encoding for `#{@type}' type"
58
+ end
59
+
60
+ @default_value = \
61
+ case @rule
62
+ when :repeated
63
+ FieldArray.new(self).freeze
64
+ when :required
65
+ nil
66
+ when :optional
67
+ typed_default_value
68
+ end
69
+
39
70
  define_accessor
40
71
  end
41
72
 
42
- def ready?; true end
73
+ def ready?
74
+ true
75
+ end
43
76
 
44
- def initialized?(message)
45
- case rule
77
+ def initialized?(message_instance)
78
+ value = message_instance.__send__(@name)
79
+ case @rule
46
80
  when :required
47
- return false if message[name].nil?
48
- return false if is_a?(Protobuf::Field::MessageField) and not message[name].initialized?
81
+ ! value.nil? && (! kind_of?(MessageField) || value.initialized?)
49
82
  when :repeated
50
- return message[name].all? {|msg|
51
- (not is_a?(Protobuf::Field::MessageField)) or msg.initialized?
52
- }
83
+ value.all? {|msg| ! kind_of?(MessageField) || msg.initialized? }
53
84
  when :optional
54
- return false if message[name] and is_a?(Protobuf::Field::MessageField) and not message[name].initialized?
85
+ value.nil? || ! kind_of?(MessageField) || value.initialized?
55
86
  end
56
- true
57
87
  end
58
88
 
59
- def clear(message)
60
- if repeated?
61
- message[name].clear
89
+ # Decode +bytes+ and pass to +message_instance+.
90
+ def set(message_instance, bytes)
91
+ if packed?
92
+ array = message_instance.__send__(@name)
93
+ method = \
94
+ case wire_type
95
+ when WireType::FIXED32 then :read_fixed32
96
+ when WireType::FIXED64 then :read_fixed64
97
+ when WireType::VARINT then :read_varint
98
+ end
99
+ stream = StringIO.new(bytes)
100
+ until stream.eof?
101
+ array << decode(Decoder.__send__(method, stream))
102
+ end
62
103
  else
63
- message.instance_variable_get(:@values).delete(name)
104
+ value = decode(bytes)
105
+ if repeated?
106
+ message_instance.__send__(@name) << value
107
+ else
108
+ message_instance.__send__("#{@name}=", value)
109
+ end
64
110
  end
65
111
  end
66
112
 
67
- def default_value
68
- case rule
69
- when :repeated
70
- FieldArray.new self
71
- when :required
72
- nil
73
- when :optional
74
- typed_default_value default
113
+ # Decode +bytes+ and return a field value.
114
+ def decode(bytes)
115
+ raise NotImplementedError, "#{self.class.name}\#decode"
116
+ end
117
+
118
+ # Encode +value+ and return a byte string.
119
+ def encode(value)
120
+ raise NotImplementedError, "#{self.class.name}\#encode"
121
+ end
122
+
123
+ # Merge +value+ with +message_instance+.
124
+ def merge(message_instance, value)
125
+ if repeated?
126
+ merge_array(message_instance, value)
75
127
  else
76
- raise InvalidRuleError
128
+ merge_value(message_instance, value)
77
129
  end
78
130
  end
79
131
 
80
- def typed_default_value(default=nil)
81
- default or self.class.default
132
+ # Is this a repeated field?
133
+ def repeated?
134
+ @rule == :repeated
135
+ end
136
+
137
+ # Is this a required field?
138
+ def required?
139
+ @rule == :required
140
+ end
141
+
142
+ # Is this a optional field?
143
+ def optional?
144
+ @rule == :optional
145
+ end
146
+
147
+ # Is this a packed repeated field?
148
+ def packed?
149
+ !!@packed
150
+ end
151
+
152
+ # Upper limit for this field.
153
+ def max
154
+ self.class.max
155
+ end
156
+
157
+ # Lower limit for this field.
158
+ def min
159
+ self.class.min
160
+ end
161
+
162
+ # Is a +value+ acceptable for this field?
163
+ def acceptable?(value)
164
+ true
165
+ end
166
+
167
+ def to_s
168
+ "#{@rule} #{@type} #{@name} = #{@tag} #{@default ? "[default=#{@default.inspect}]" : ''}"
82
169
  end
83
170
 
84
171
  private
85
172
 
86
173
  def define_accessor
87
174
  define_getter
88
- if rule == :repeated
175
+ if repeated?
89
176
  define_array_setter
90
177
  else
91
178
  define_setter
@@ -111,7 +198,7 @@ module Protobuf
111
198
  define_method("#{field.name}=") do |val|
112
199
  if val.nil?
113
200
  @values.delete(field.name)
114
- elsif field.acceptable? val
201
+ elsif field.acceptable?(val)
115
202
  @values[field.name] = val
116
203
  end
117
204
  end
@@ -127,117 +214,77 @@ module Protobuf
127
214
  end
128
215
  end
129
216
 
130
- public
131
-
132
- # encoder/decoder related methods
133
-
134
- def set(message_instance, bytes)
135
- value = decode(bytes)
136
- if repeated?
137
- message_instance.send(name) << value
138
- else
139
- message_instance.send("#{name}=", value)
140
- end
141
- end
142
-
143
- def get(value)
144
- encode(value)
145
- end
146
-
147
- def decode(bytes)
148
- raise NotImplementedError.new("#{self.class.name}\#decode")
217
+ def merge_array(message_instance, value)
218
+ message_instance.__send__(@name).concat(value)
149
219
  end
150
- private :decode
151
220
 
152
- def encode(value)
153
- raise NotImplementedError.new("#{self.class.name}\#encode")
221
+ def merge_value(message_instance, value)
222
+ message_instance.__send__("#{@name}=", value)
154
223
  end
155
- private :encode
156
224
 
157
- def merge(message_instance, value)
158
- if repeated?
159
- merge_array message_instance, value
225
+ def typed_default_value
226
+ if @default.nil?
227
+ self.class.default
160
228
  else
161
- merge_value message_instance, value
229
+ @default
162
230
  end
163
231
  end
164
232
 
165
- def merge_array(message_instance, value)
166
- message_instance[tag].concat value
167
- end
233
+ end # BaseField
168
234
 
169
- def merge_value(message_instance, value)
170
- message_instance[tag] = value
171
- end
172
-
173
- # utility methods
174
-
175
- def repeated?; rule == :repeated end
176
- def required?; rule == :required end
177
- def optional?; rule == :optional end
178
-
179
- def max; self.class.max end
180
- def min; self.class.min end
181
-
182
- def acceptable?(val)
183
- true
184
- end
185
235
 
186
- def error_message
187
- @error_message
188
- end
236
+ class FieldProxy
189
237
 
190
- def to_s
191
- "#{rule} #{type} #{name} = #{tag} #{default ? "[default=#{default}]" : ''}"
238
+ def initialize(message_class, rule, type, name, tag, options)
239
+ @message_class, @rule, @type, @name, @tag, @options =
240
+ message_class, rule, type, name, tag, options
192
241
  end
193
- end
194
242
 
195
- class FieldProxy
196
- def initialize(message_class, rule, type, name, tag, opts={})
197
- @message_class, @rule, @type, @name, @tag, @opts =
198
- message_class, rule, type, name, tag, opts
243
+ def ready?
244
+ false
199
245
  end
200
246
 
201
- def ready?; false end
202
-
203
247
  def setup
204
- type = typename_to_class @message_class, @type
205
- field_class =
206
- if type.superclass == Protobuf::Enum
207
- Protobuf::Field::EnumField
208
- elsif type.superclass == Protobuf::Message
209
- Protobuf::Field::MessageField
248
+ type = typename_to_class(@message_class, @type)
249
+ field_class = \
250
+ if type < Enum
251
+ EnumField
252
+ elsif type < Message
253
+ MessageField
210
254
  else
211
- raise TypeError.new(type.inspect)
255
+ raise TypeError, type.inspect
212
256
  end
213
- field_class.new @message_class, @rule, type, @name, @tag, @opts
257
+ field_class.new(@message_class, @rule, type, @name, @tag, @options)
214
258
  end
215
259
 
260
+ private
261
+
216
262
  def typename_to_class(message_class, type)
217
- suffix = type.to_s.split('::')
218
- modules = message_class.to_s.split('::')
219
- args = (Object.method(:const_defined?).arity == 1) ? [] : [nil, false]
263
+ names = type.to_s.split('::').map {|s| Util.camelize(s) }
264
+ outer = message_class.to_s.split('::')
265
+ args = (Object.method(:const_defined?).arity == 1) ? [] : [false]
220
266
  while
221
- mod = modules.empty? ? Object : eval(modules.join('::'))
222
- mod = suffix.inject(mod) {|m, s|
223
- args[0] = s
224
- m and m.const_defined?(*args) and m.const_get(s)
267
+ mod = outer.empty? ? Object : eval(outer.join('::'))
268
+ mod = names.inject(mod) {|m, s|
269
+ m && m.const_defined?(s, *args) && m.const_get(s)
225
270
  }
226
271
  break if mod
227
- raise NameError.new("type not found: #{type}", type) if modules.empty?
228
- modules.pop
272
+ raise NameError.new("type not found: #{type}", type) if outer.empty?
273
+ outer.pop
229
274
  end
230
275
  mod
231
276
  end
277
+
232
278
  end
233
279
 
234
280
  class FieldArray < Array
281
+
235
282
  def initialize(field)
236
283
  @field = field
237
284
  end
238
285
 
239
286
  def []=(nth, val)
240
- super(normalize(val))
287
+ super(nth, normalize(val))
241
288
  end
242
289
 
243
290
  def <<(val)
@@ -272,39 +319,49 @@ module Protobuf
272
319
  val
273
320
  end
274
321
  end
322
+
275
323
  end
276
324
 
325
+ # Field class for +bytes+ type.
277
326
  class BytesField < BaseField
278
- class <<self
279
- def default; '' end
327
+ def self.default
328
+ ''
280
329
  end
281
330
 
282
331
  def wire_type
283
- Protobuf::WireType::LENGTH_DELIMITED
332
+ WireType::LENGTH_DELIMITED
284
333
  end
285
334
 
286
335
  def acceptable?(val)
287
- raise TypeError unless val.instance_of? String
336
+ raise TypeError unless val.instance_of?(String)
288
337
  true
289
338
  end
290
339
 
291
340
  def decode(bytes)
292
- bytes.pack('C*')
341
+ bytes.force_encoding(Encoding::ASCII_8BIT) if bytes.respond_to?(:force_encoding)
342
+ bytes
293
343
  end
294
344
 
295
345
  def encode(value)
296
- value = value.dup
297
- value.force_encoding('ASCII-8BIT') if value.respond_to?(:force_encoding)
298
- string_size = VarintField.encode(value.size)
299
- string_size << value
346
+ if value.respond_to?(:force_encoding)
347
+ # Ruby 1.9
348
+ old_encoding = value.encoding
349
+ result = VarintField.encode(value.bytesize)
350
+ result << value.force_encoding(Encoding::ASCII_8BIT)
351
+ value.force_encoding(old_encoding)
352
+ result
353
+ else
354
+ # Ruby 1.8
355
+ result = VarintField.encode(value.size)
356
+ result << value
357
+ end
300
358
  end
301
359
  end
302
360
 
303
361
  class StringField < BytesField
304
362
  def decode(bytes)
305
- message = bytes.pack('C*')
306
- message.force_encoding('UTF-8') if message.respond_to?(:force_encoding)
307
- message
363
+ bytes.force_encoding(Encoding::UTF_8) if bytes.respond_to?(:force_encoding)
364
+ bytes
308
365
  end
309
366
  end
310
367
 
@@ -317,7 +374,9 @@ module Protobuf
317
374
  UINT64_MAX = 2**64 - 1
318
375
 
319
376
  class <<self
320
- def default; 0 end
377
+ def default
378
+ 0
379
+ end
321
380
 
322
381
  def decode(bytes)
323
382
  value = 0
@@ -328,7 +387,7 @@ module Protobuf
328
387
  end
329
388
 
330
389
  def encode(value)
331
- raise RangeError.new(value) if value < 0
390
+ raise RangeError, "#{value} is negative" if value < 0
332
391
  return [value].pack('C') if value < 128
333
392
  bytes = []
334
393
  until value == 0
@@ -341,11 +400,11 @@ module Protobuf
341
400
  end
342
401
 
343
402
  def wire_type
344
- Protobuf::WireType::VARINT
403
+ WireType::VARINT
345
404
  end
346
405
 
347
- def decode(bytes)
348
- self.class.decode(bytes)
406
+ def decode(value)
407
+ value
349
408
  end
350
409
 
351
410
  def encode(value)
@@ -353,8 +412,8 @@ module Protobuf
353
412
  end
354
413
 
355
414
  def acceptable?(val)
356
- raise TypeError.new(val.class.name) unless val.is_a? Integer
357
- raise RangeError.new(val) if val < min or max < val
415
+ raise TypeError, val.class.name unless val.is_a?(Integer)
416
+ raise RangeError if val < min || max < val
358
417
  true
359
418
  end
360
419
  end
@@ -366,8 +425,7 @@ module Protobuf
366
425
  VarintField.encode(value & 0xffff_ffff_ffff_ffff)
367
426
  end
368
427
 
369
- def decode(bytes)
370
- value = VarintField.decode(bytes)
428
+ def decode(value)
371
429
  value -= 0x1_0000_0000_0000_0000 if (value & 0x8000_0000_0000_0000).nonzero?
372
430
  value
373
431
  end
@@ -395,8 +453,7 @@ module Protobuf
395
453
 
396
454
  # Base class for sint32 and sint64
397
455
  class SignedIntegerField < VarintField
398
- def decode(bytes)
399
- value = VarintField.decode(bytes)
456
+ def decode(value)
400
457
  if (value & 1).zero?
401
458
  value >> 1 # positive value
402
459
  else
@@ -429,7 +486,7 @@ module Protobuf
429
486
  def self.min; -1.0/0; end
430
487
 
431
488
  def wire_type
432
- Protobuf::WireType::FIXED32
489
+ WireType::FIXED32
433
490
  end
434
491
 
435
492
  def decode(bytes)
@@ -441,15 +498,15 @@ module Protobuf
441
498
  end
442
499
 
443
500
  def acceptable?(val)
444
- raise TypeError.new(val.class.name) unless val.is_a? Numeric
445
- raise RangeError.new(val) if val < min or max < val
501
+ raise TypeError, val.class.name unless val.is_a?(Numeric)
502
+ raise RangeError if val < min || max < val
446
503
  true
447
504
  end
448
505
  end
449
506
 
450
507
  class DoubleField < FloatField
451
508
  def wire_type
452
- Protobuf::WireType::FIXED64
509
+ WireType::FIXED64
453
510
  end
454
511
 
455
512
  def decode(bytes)
@@ -463,7 +520,7 @@ module Protobuf
463
520
 
464
521
  class Fixed32Field < Uint32Field
465
522
  def wire_type
466
- Protobuf::WireType::FIXED32
523
+ WireType::FIXED32
467
524
  end
468
525
 
469
526
  def decode(bytes)
@@ -477,7 +534,7 @@ module Protobuf
477
534
 
478
535
  class Fixed64Field < Uint64Field
479
536
  def wire_type
480
- Protobuf::WireType::FIXED64
537
+ WireType::FIXED64
481
538
  end
482
539
 
483
540
  def decode(bytes)
@@ -494,7 +551,7 @@ module Protobuf
494
551
 
495
552
  class Sfixed32Field < Int32Field
496
553
  def wire_type
497
- Protobuf::WireType::FIXED32
554
+ WireType::FIXED32
498
555
  end
499
556
 
500
557
  def decode(bytes)
@@ -510,7 +567,7 @@ module Protobuf
510
567
 
511
568
  class Sfixed64Field < Int64Field
512
569
  def wire_type
513
- Protobuf::WireType::FIXED64
570
+ WireType::FIXED64
514
571
  end
515
572
 
516
573
  def decode(bytes)
@@ -528,17 +585,17 @@ module Protobuf
528
585
  end
529
586
 
530
587
  class BoolField < VarintField
531
- class <<self
532
- def default; false end
588
+ def self.default
589
+ false
533
590
  end
534
591
 
535
592
  def acceptable?(val)
536
- raise TypeError unless [TrueClass, FalseClass].include? val.class
593
+ raise TypeError unless [true, false].include?(val)
537
594
  true
538
595
  end
539
596
 
540
- def decode(bytes)
541
- bytes.first == 1
597
+ def decode(value)
598
+ value == 1
542
599
  end
543
600
 
544
601
  def encode(value)
@@ -546,11 +603,31 @@ module Protobuf
546
603
  end
547
604
  end
548
605
 
606
+
549
607
  class MessageField < BaseField
550
- class <<self
551
- def default; nil end
608
+ def wire_type
609
+ WireType::LENGTH_DELIMITED
610
+ end
611
+
612
+ def acceptable?(val)
613
+ raise TypeError unless val.instance_of?(type) || val.instance_of?(Hash)
614
+ true
615
+ end
616
+
617
+ def decode(bytes)
618
+ message = type.new
619
+ message.parse_from_string(bytes)
620
+ message
621
+ end
622
+
623
+ def encode(value)
624
+ bytes = value.serialize_to_string
625
+ result = VarintField.encode(bytes.size)
626
+ result << bytes
552
627
  end
553
628
 
629
+ private
630
+
554
631
  def define_setter
555
632
  field = self
556
633
  @message_class.class_eval do
@@ -563,59 +640,70 @@ module Protobuf
563
640
  when field.type
564
641
  @values[field.name] = val
565
642
  else
566
- raise TypeError
643
+ raise TypeError, "Expected value of type '#{field.type}', but got '#{val.class}'"
567
644
  end
568
645
  end
569
646
  end
570
647
  end
571
648
 
572
- def wire_type
573
- Protobuf::WireType::LENGTH_DELIMITED
649
+ def merge_value(message_instance, value)
650
+ message_instance.__send__(@name).merge_from(value)
574
651
  end
652
+ end
575
653
 
576
- def typed_default_value(default=nil)
577
- if default.is_a? Symbol
578
- type.module_eval default.to_s
579
- else
580
- default
581
- end
582
- end
583
654
 
655
+ class EnumField < VarintField
584
656
  def acceptable?(val)
585
- raise TypeError unless val.instance_of?(type) or val.instance_of?(Hash)
657
+ case val
658
+ when Symbol
659
+ raise TypeError unless @type.const_defined?(val)
660
+ when EnumValue
661
+ raise TypeError if val.parent_class != @type
662
+ else
663
+ raise TypeError unless @type.valid_tag?(val)
664
+ end
586
665
  true
587
666
  end
588
667
 
589
- def decode(bytes)
590
- message = type.new
591
- message.parse_from_string bytes.pack('C*') # TODO
592
- message
593
- end
594
-
595
668
  def encode(value)
596
- bytes = value.serialize_to_string
597
- string_size = VarintField.encode bytes.size
598
- string_size << bytes
669
+ super(value.to_i)
599
670
  end
600
671
 
601
- def merge_value(message_instance, value)
602
- message_instance[tag].merge_from value
603
- end
604
- end
672
+ private
605
673
 
606
- class EnumField < VarintField
607
- def default
674
+ def typed_default_value
608
675
  if @default.is_a?(Symbol)
609
- type.const_get @default
676
+ @type.const_get(@default)
610
677
  else
611
- @default
678
+ self.class.default
612
679
  end
613
680
  end
614
681
 
615
- def acceptable?(val)
616
- raise TypeError unless type.valid_tag? val
617
- true
682
+ def define_setter
683
+ field = self
684
+ @message_class.class_eval do
685
+ define_method("#{field.name}=") do |val|
686
+ if val.nil?
687
+ @values.delete(field.name)
688
+ else
689
+ val = \
690
+ case val
691
+ when Symbol
692
+ field.type.const_get(val) rescue nil
693
+ when Integer
694
+ field.type.const_get(field.type.name_by_value(val)) rescue nil
695
+ when EnumValue
696
+ raise TypeError, "Invalid value: #{val.inspect}" if val.parent_class != field.type
697
+ val
698
+ end
699
+ raise TypeError, "Invalid value: #{val.inspect}" unless val
700
+
701
+ @values[field.name] = val
702
+ end
703
+ end
704
+ end
618
705
  end
706
+
619
707
  end
620
708
  end
621
709
  end