macks-ruby_protobuf 0.3.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/History.txt +14 -0
  2. data/Manifest.txt +74 -0
  3. data/README.txt +58 -0
  4. data/Rakefile +18 -0
  5. data/bin/mk_parser +2 -0
  6. data/bin/rprotoc +36 -0
  7. data/examples/addressbook.pb.rb +56 -0
  8. data/examples/addressbook.proto +24 -0
  9. data/examples/reading_a_message.rb +32 -0
  10. data/examples/writing_a_message.rb +46 -0
  11. data/lib/protobuf/common/wire_type.rb +10 -0
  12. data/lib/protobuf/compiler/compiler.rb +54 -0
  13. data/lib/protobuf/compiler/nodes.rb +319 -0
  14. data/lib/protobuf/compiler/proto.y +203 -0
  15. data/lib/protobuf/compiler/proto2.ebnf +79 -0
  16. data/lib/protobuf/compiler/proto_parser.rb +1394 -0
  17. data/lib/protobuf/compiler/template/rpc_bin.erb +4 -0
  18. data/lib/protobuf/compiler/template/rpc_client.erb +18 -0
  19. data/lib/protobuf/compiler/template/rpc_service.erb +25 -0
  20. data/lib/protobuf/compiler/visitors.rb +288 -0
  21. data/lib/protobuf/descriptor/descriptor.proto +286 -0
  22. data/lib/protobuf/descriptor/descriptor.rb +54 -0
  23. data/lib/protobuf/descriptor/descriptor_builder.rb +144 -0
  24. data/lib/protobuf/descriptor/descriptor_proto.rb +119 -0
  25. data/lib/protobuf/descriptor/enum_descriptor.rb +33 -0
  26. data/lib/protobuf/descriptor/field_descriptor.rb +50 -0
  27. data/lib/protobuf/descriptor/file_descriptor.rb +38 -0
  28. data/lib/protobuf/message/decoder.rb +93 -0
  29. data/lib/protobuf/message/encoder.rb +37 -0
  30. data/lib/protobuf/message/enum.rb +28 -0
  31. data/lib/protobuf/message/extend.rb +8 -0
  32. data/lib/protobuf/message/field.rb +654 -0
  33. data/lib/protobuf/message/message.rb +308 -0
  34. data/lib/protobuf/message/protoable.rb +37 -0
  35. data/lib/protobuf/message/service.rb +9 -0
  36. data/lib/protobuf/rpc/client.rb +19 -0
  37. data/lib/protobuf/rpc/handler.rb +17 -0
  38. data/lib/protobuf/rpc/server.rb +39 -0
  39. data/lib/ruby_protobuf.rb +3 -0
  40. data/test/addressbook.rb +98 -0
  41. data/test/addressbook_base.rb +62 -0
  42. data/test/addressbook_ext.rb +12 -0
  43. data/test/check_unbuild.rb +30 -0
  44. data/test/collision.rb +18 -0
  45. data/test/data/data.bin +3 -0
  46. data/test/data/data_source.py +14 -0
  47. data/test/data/types.bin +0 -0
  48. data/test/data/types_source.py +22 -0
  49. data/test/data/unk.png +0 -0
  50. data/test/ext_collision.rb +25 -0
  51. data/test/ext_range.rb +23 -0
  52. data/test/merge.rb +40 -0
  53. data/test/nested.rb +25 -0
  54. data/test/proto/addressbook.proto +31 -0
  55. data/test/proto/addressbook_base.proto +26 -0
  56. data/test/proto/addressbook_ext.proto +6 -0
  57. data/test/proto/collision.proto +5 -0
  58. data/test/proto/ext_collision.proto +8 -0
  59. data/test/proto/ext_range.proto +7 -0
  60. data/test/proto/merge.proto +15 -0
  61. data/test/proto/nested.proto +7 -0
  62. data/test/proto/rpc.proto +6 -0
  63. data/test/proto/types.proto +17 -0
  64. data/test/test_addressbook.rb +43 -0
  65. data/test/test_compiler.rb +313 -0
  66. data/test/test_descriptor.rb +122 -0
  67. data/test/test_extension.rb +40 -0
  68. data/test/test_message.rb +106 -0
  69. data/test/test_optional_field.rb +68 -0
  70. data/test/test_parse.rb +15 -0
  71. data/test/test_ruby_protobuf.rb +1 -0
  72. data/test/test_serialize.rb +42 -0
  73. data/test/test_standard_message.rb +96 -0
  74. data/test/test_types.rb +181 -0
  75. data/test/types.rb +22 -0
  76. metadata +150 -0
@@ -0,0 +1,654 @@
1
+ require 'protobuf/common/wire_type'
2
+ require 'protobuf/descriptor/field_descriptor'
3
+
4
+ module Protobuf
5
+ 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"
12
+ else
13
+ Protobuf::Field::FieldProxy
14
+ end
15
+ field_class.new message_class, rule, type, name, tag, opts
16
+ end
17
+
18
+ class InvalidRuleError < StandardError; end
19
+
20
+ class BaseField
21
+ class <<self
22
+ def descriptor
23
+ @descriptor ||= Protobuf::Descriptor::FieldDescriptor.new
24
+ end
25
+
26
+ def default; nil end
27
+ end
28
+
29
+ attr_accessor :message_class, :rule, :type, :name, :tag, :default
30
+
31
+ def descriptor
32
+ @descriptor ||= Protobuf::Descriptor::FieldDescriptor.new self
33
+ end
34
+
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'
39
+ end
40
+
41
+ def ready?; true end
42
+
43
+ def initialized?(message)
44
+ case rule
45
+ when :required
46
+ return false if message[name].nil?
47
+ return false if is_a?(Protobuf::Field::MessageField) and not message[name].initialized?
48
+ when :repeated
49
+ return message[name].inject(true) do |result, msg|
50
+ result and msg.initialized?
51
+ end
52
+ when :optional
53
+ return false if message[name] and is_a?(Protobuf::Field::MessageField) and not message[name].initialized?
54
+ end
55
+ true
56
+ end
57
+
58
+ def clear(message)
59
+ if repeated?
60
+ message[name].clear
61
+ else
62
+ message.instance_variable_get(:@values).delete(name)
63
+ end
64
+ end
65
+
66
+ def default_value
67
+ case rule
68
+ when :repeated
69
+ FieldArray.new self
70
+ when :required
71
+ nil
72
+ when :optional
73
+ typed_default_value default
74
+ else
75
+ raise InvalidRuleError
76
+ end
77
+ end
78
+
79
+ def typed_default_value(default=nil)
80
+ default or self.class.default
81
+ end
82
+
83
+ def define_accessor(message_instance)
84
+ message_instance.instance_variable_get(:@values)[name] = default_value if rule == :repeated
85
+ define_getter message_instance
86
+ define_setter message_instance unless rule == :repeated
87
+ end
88
+
89
+ def define_getter(message_instance)
90
+ field = self
91
+ metaclass = (class << message_instance; self; end)
92
+ metaclass.class_eval do
93
+ define_method(field.name) do
94
+ @values[field.name] or field.default_value
95
+ end
96
+ end
97
+ end
98
+
99
+ def define_setter(message_instance)
100
+ field = self
101
+ metaclass = (class << message_instance; self; end)
102
+ metaclass.class_eval do
103
+ define_method("#{field.name}=") do |val|
104
+ if val.nil?
105
+ @values.delete(field.name)
106
+ elsif field.acceptable? val
107
+ @values[field.name] = val
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ def set(message_instance, bytes)
114
+ if repeated?
115
+ set_array message_instance, bytes
116
+ else
117
+ set_bytes message_instance, bytes
118
+ end
119
+ end
120
+
121
+ def set_array(message_instance, bytes)
122
+ raise NotImplementedError
123
+ end
124
+
125
+ def set_bytes(message_instance, bytes)
126
+ raise NotImplementedError
127
+ end
128
+
129
+ def get(value)
130
+ get_bytes value
131
+ end
132
+
133
+ def get_bytes(value)
134
+ raise NotImplementedError
135
+ end
136
+
137
+ def merge(message_instance, value)
138
+ if repeated?
139
+ merge_array message_instance, value
140
+ else
141
+ merge_value message_instance, value
142
+ end
143
+ end
144
+
145
+ def merge_array(message_instance, value)
146
+ message_instance[tag].concat value
147
+ end
148
+
149
+ def merge_value(message_instance, value)
150
+ message_instance[tag] = value
151
+ end
152
+
153
+ def repeated?; rule == :repeated end
154
+ def required?; rule == :required end
155
+ def optional?; rule == :optional end
156
+
157
+ def max; self.class.max end
158
+ def min; self.class.min end
159
+
160
+ def acceptable?(val)
161
+ true
162
+ end
163
+
164
+ def error_message
165
+ @error_message
166
+ end
167
+
168
+ def to_s
169
+ "#{rule} #{type} #{name} = #{tag} #{default ? "[default=#{default}]" : ''}"
170
+ end
171
+ end
172
+
173
+ class FieldProxy
174
+ def initialize(message_class, rule, type, name, tag, opts={})
175
+ @message_class, @rule, @type, @name, @tag, @opts =
176
+ message_class, rule, type, name, tag, opts
177
+ end
178
+
179
+ def ready?; false end
180
+
181
+ def setup
182
+ type = typename_to_class @message_class, @type
183
+ field_class =
184
+ if type.superclass == Protobuf::Enum
185
+ Protobuf::Field::EnumField
186
+ elsif type.superclass == Protobuf::Message
187
+ Protobuf::Field::MessageField
188
+ else
189
+ raise $!
190
+ end
191
+ field_class.new @message_class, @rule, type, @name, @tag, @opts
192
+ end
193
+
194
+ def typename_to_class(message_class, type)
195
+ modules = message_class.to_s.split('::')
196
+ while
197
+ begin
198
+ type = eval((modules | [type.to_s]).join('::'))
199
+ break
200
+ rescue NameError
201
+ modules.empty? ? raise($!) : modules.pop
202
+ end
203
+ end
204
+ type
205
+ end
206
+ =begin
207
+ def typename_to_class(message_class, type)
208
+ suffix = type.to_s.split('::')
209
+ modules = message_class.to_s.split('::')
210
+ while
211
+ mod = modules.empty? ? Object : eval(modules.join('::'))
212
+ suffix.each do |s|
213
+ if mod.const_defined?(s)
214
+ mod = mod.const_get(s)
215
+ else
216
+ mod = nil
217
+ break
218
+ end
219
+ end
220
+ break if mod
221
+ raise NameError.new("type not found: #{type}", type) if modules.empty?
222
+ modules.pop
223
+ end
224
+ mod
225
+ end
226
+ =end
227
+ end
228
+
229
+ class FieldArray < Array
230
+ def initialize(field)
231
+ @field = field
232
+ end
233
+
234
+ def []=(nth, val)
235
+ if @field.acceptable? val
236
+ super
237
+ end
238
+ end
239
+
240
+ def <<(val)
241
+ if @field.acceptable? val
242
+ super
243
+ end
244
+ end
245
+
246
+ def push(val)
247
+ if @field.acceptable? val
248
+ super
249
+ end
250
+ end
251
+
252
+ def unshift(val)
253
+ if @field.acceptable? val
254
+ super
255
+ end
256
+ end
257
+
258
+ def to_s
259
+ "[#{@field.name}]"
260
+ end
261
+ end
262
+
263
+ class StringField < BaseField
264
+ class <<self
265
+ def default; '' end
266
+ end
267
+
268
+ def wire_type
269
+ Protobuf::WireType::LENGTH_DELIMITED
270
+ end
271
+
272
+ def acceptable?(val)
273
+ raise TypeError unless val.instance_of? String
274
+ true
275
+ end
276
+
277
+ def set_bytes(message_instance, bytes)
278
+ message = bytes.pack('C*')
279
+ message.force_encoding('UTF-8') if message.respond_to?(:force_encoding)
280
+ message_instance.send("#{name}=", message)
281
+ end
282
+
283
+ def set_array(message_instance, bytes)
284
+ message = bytes.pack('C*')
285
+ message.force_encoding('UTF-8') if message.respond_to?(:force_encoding)
286
+ arr = message_instance.send name
287
+ arr << message
288
+ end
289
+
290
+ def get_bytes(value)
291
+ bytes = value.unpack('C*')
292
+ string_size = VarintField.get_bytes bytes.size
293
+ string_size + bytes.pack('C*')
294
+ end
295
+ end
296
+
297
+ class BytesField < BaseField
298
+ class <<self
299
+ def default; '' end
300
+ end
301
+
302
+ def wire_type
303
+ Protobuf::WireType::LENGTH_DELIMITED
304
+ end
305
+
306
+ def acceptable?(val)
307
+ raise TypeError unless val.instance_of? String
308
+ true
309
+ end
310
+
311
+ def set_bytes(message_instance, bytes)
312
+ message_instance.send("#{name}=", bytes.pack('C*'))
313
+ end
314
+
315
+ def set_array(message_instance, bytes)
316
+ message = bytes.pack('C*')
317
+ arr = message_instance.send name
318
+ arr << message
319
+ end
320
+
321
+ def get_bytes(value)
322
+ string_size = VarintField.get_bytes value.unpack('C*').size
323
+ string_size + value
324
+ end
325
+ end
326
+
327
+ class VarintField < BaseField
328
+ class <<self
329
+ def default; 0 end
330
+ end
331
+
332
+ def wire_type
333
+ Protobuf::WireType::VARINT
334
+ end
335
+
336
+ def set_bytes(message_instance, bytes)
337
+ # TODO should refactor using pack('w*')
338
+ value = 0
339
+ bytes.each_with_index do |byte, index|
340
+ value |= byte << (7 * index)
341
+ end
342
+ message_instance.send("#{name}=", value)
343
+ end
344
+
345
+ def self.get_bytes(value)
346
+ # TODO should refactor using unpack('w*')
347
+ #return [value].pack('w*').unpack('C*')
348
+ return [0].pack('C') if value == 0
349
+ bytes = []
350
+ until value == 0
351
+ byte = 0
352
+ 7.times do |i|
353
+ byte |= (value & 1) << i
354
+ value >>= 1
355
+ end
356
+ byte |= 0b10000000
357
+ bytes << byte
358
+ end
359
+ #bytes[0] &= 0b01111111
360
+ #bytes
361
+ bytes[bytes.size - 1] &= 0b01111111
362
+ bytes.pack('C*')
363
+ end
364
+
365
+ def get_bytes(value)
366
+ self.class.get_bytes value
367
+ end
368
+
369
+ def acceptable?(val)
370
+ raise TypeError.new(val.class.name) unless val.is_a? Integer
371
+ raise RangeError.new(val) if val < min or max < val
372
+ true
373
+ end
374
+ end
375
+
376
+ class Int32Field < VarintField
377
+ def self.max; 1.0/0.0 end
378
+ def self.min; -1.0/0.0 end
379
+ end
380
+
381
+ class Int64Field < VarintField
382
+ def self.max; 1.0/0.0 end
383
+ def self.min; -1.0/0.0 end
384
+ end
385
+
386
+ class Uint32Field < VarintField
387
+ def self.max; 1.0/0.0 end
388
+ def self.min; 0 end
389
+ end
390
+
391
+ class Uint64Field < VarintField
392
+ def self.max; 1.0/0.0 end
393
+ def self.min; 0 end
394
+ end
395
+
396
+ class Sint32Field < VarintField
397
+ def self.max; 1.0/0.0 end
398
+ def self.min; -1.0/0.0 end
399
+
400
+ def set_bytes(message_instance, bytes)
401
+ # TODO use only bit-operations
402
+ byte = bytes.first
403
+ value =
404
+ if byte % 2 == 0
405
+ byte / 2
406
+ else
407
+ -(byte + 1) / 2
408
+ end
409
+ message_instance.send("#{name}=", value)
410
+ end
411
+
412
+ def get_bytes(value)
413
+ #(value << 1) ^ (value >> 31)
414
+ [(value << 1) ^ (value >> 31)].pack('C*')
415
+ end
416
+ end
417
+
418
+ class Sint64Field < VarintField
419
+ def self.max; 1.0/0.0 end
420
+ def self.min; -1.0/0.0 end
421
+
422
+ def set_bytes(message_instance, bytes)
423
+ # TODO use only bit-operations
424
+ byte = bytes.first
425
+ value =
426
+ if byte % 2 == 0
427
+ byte / 2
428
+ else
429
+ -(byte + 1) / 2
430
+ end
431
+ message_instance.send("#{name}=", value)
432
+ end
433
+
434
+ def get_bytes(value)
435
+ #(value << 1) ^ (value >> 63)
436
+ [(value << 1) ^ (value >> 63)].pack('C*')
437
+ end
438
+ end
439
+
440
+ class DoubleField < VarintField
441
+ def wire_type
442
+ Protobuf::WireType::FIXED64
443
+ end
444
+
445
+ #TODO
446
+ def self.max
447
+ '0x7fefffffffffffff'.unpack('d').first
448
+ end
449
+
450
+ #TODO
451
+ def self.min
452
+ -(2**(64/2) - 1)
453
+ end
454
+
455
+ def set_bytes(message_instance, bytes)
456
+ message_instance.send("#{name}=", bytes.unpack('E').first)
457
+ end
458
+
459
+ def get_bytes(value)
460
+ [value].pack('E')
461
+ end
462
+
463
+ def acceptable?(val)
464
+ raise TypeError.new(val.class.name) unless val.is_a? Numeric
465
+ raise RangeError.new(val) if val < min or max < val
466
+ true
467
+ end
468
+ end
469
+
470
+ class FloatField < VarintField
471
+ def wire_type
472
+ Protobuf::WireType::FIXED32
473
+ end
474
+
475
+ #TODO
476
+ def self.max
477
+ '0x7fefffffffffffff'.unpack('e').first
478
+ end
479
+
480
+ #TODO
481
+ def self.min
482
+ -(2**(32/2) - 1)
483
+ end
484
+
485
+ def set_bytes(message_instance, bytes)
486
+ message_instance.send("#{name}=", bytes.unpack('e').first)
487
+ end
488
+
489
+ def get_bytes(value)
490
+ [value].pack('e')
491
+ end
492
+
493
+ def acceptable?(val)
494
+ raise TypeError unless val.is_a? Numeric
495
+ raise RangeError if val < min or max < val
496
+ true
497
+ end
498
+ end
499
+
500
+ class Fixed32Field < VarintField
501
+ def wire_type
502
+ Protobuf::WireType::FIXED32
503
+ end
504
+
505
+ def self.max
506
+ 2**32
507
+ end
508
+
509
+ def self.min
510
+ 0
511
+ end
512
+
513
+ def set_bytes(message_instance, bytes)
514
+ message_instance.send("#{name}=", bytes.unpack('L').first)
515
+ end
516
+
517
+ def get_bytes(value)
518
+ [value].pack('L')
519
+ end
520
+ end
521
+
522
+ class Fixed64Field < VarintField
523
+ def wire_type
524
+ Protobuf::WireType::FIXED64
525
+ end
526
+
527
+ def self.max
528
+ 2**64
529
+ end
530
+
531
+ def self.min
532
+ 0
533
+ end
534
+
535
+ def set_bytes(message_instance, bytes)
536
+ message_instance.send("#{name}=", bytes.unpack('l').first)
537
+ end
538
+
539
+ def get_bytes(value)
540
+ [value].pack('Q')
541
+ end
542
+ end
543
+
544
+ class Sfinxed32Field < VarintField
545
+ def wire_type
546
+ Protobuf::WireType::FIXED32
547
+ end
548
+
549
+ def self.max
550
+ 2**(32/2)
551
+ end
552
+
553
+ def self.min
554
+ -(2**(32/2) - 1)
555
+ end
556
+ end
557
+
558
+ class Sfixed64Field < VarintField
559
+ def wire_type
560
+ Protobuf::WireType::FIXED64
561
+ end
562
+
563
+ def self.max
564
+ 2**(64/2)
565
+ end
566
+
567
+ def self.min
568
+ -(2**(64/2) - 1)
569
+ end
570
+ end
571
+
572
+ class BoolField < VarintField
573
+ class <<self
574
+ def default; false end
575
+ end
576
+
577
+ def acceptable?(val)
578
+ raise TypeError unless [TrueClass, FalseClass].include? val.class
579
+ true
580
+ end
581
+
582
+ def set_bytes(message_instance, bytes)
583
+ message_instance.send("#{name}=", bytes.first == 1)
584
+ end
585
+
586
+ def get_bytes(value)
587
+ [value ? 1 : 0].pack('C')
588
+ end
589
+ end
590
+
591
+ class MessageField < BaseField
592
+ class <<self
593
+ def default; nil end
594
+ end
595
+
596
+ def wire_type
597
+ Protobuf::WireType::LENGTH_DELIMITED
598
+ end
599
+
600
+ def typed_default_value(default=nil)
601
+ if default.is_a? Symbol
602
+ type.module_eval default.to_s
603
+ else
604
+ default
605
+ end
606
+ end
607
+
608
+ def acceptable?(val)
609
+ raise TypeError unless val.instance_of? type
610
+ true
611
+ end
612
+
613
+ def set_bytes(message_instance, bytes)
614
+ message = type.new
615
+ message.parse_from_string bytes.pack('C*') # TODO
616
+ message_instance.send("#{name}=", message)
617
+ end
618
+
619
+ def set_array(message_instance, bytes)
620
+ message = type.new
621
+ message.parse_from_string bytes.pack('C*')
622
+ arr = message_instance.send name
623
+ arr << message
624
+ end
625
+
626
+ def get_bytes(value)
627
+ stringio = StringIO.new ''
628
+ value.serialize_to stringio
629
+ bytes = stringio.string.unpack 'C*'
630
+ string_size = VarintField.get_bytes bytes.size
631
+ string_size + bytes.pack('C*')
632
+ end
633
+
634
+ def merge_value(message_instance, value)
635
+ message_instance[tag].merge_from value
636
+ end
637
+ end
638
+
639
+ class EnumField < VarintField
640
+ def default
641
+ if @default.is_a?(Symbol)
642
+ type.const_get @default
643
+ else
644
+ @default
645
+ end
646
+ end
647
+
648
+ def acceptable?(val)
649
+ raise TypeError unless type.valid_tag? val
650
+ true
651
+ end
652
+ end
653
+ end
654
+ end