ruby_protobuf 0.3.0 → 0.3.2

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 (49) hide show
  1. data/History.txt +3 -1
  2. data/bin/mk_parser +2 -0
  3. data/bin/rprotoc +1 -1
  4. data/lib/protobuf/compiler/compiler.rb +12 -12
  5. data/lib/protobuf/compiler/nodes.rb +140 -35
  6. data/lib/protobuf/compiler/proto.y +7 -4
  7. data/lib/protobuf/compiler/proto_parser.rb +170 -167
  8. data/lib/protobuf/compiler/template/rpc_bin.erb +1 -1
  9. data/lib/protobuf/compiler/template/rpc_client.erb +1 -1
  10. data/lib/protobuf/compiler/visitors.rb +168 -16
  11. data/lib/protobuf/message/enum.rb +3 -0
  12. data/lib/protobuf/message/field.rb +52 -37
  13. data/lib/protobuf/message/message.rb +37 -14
  14. data/lib/protobuf/message/protoable.rb +37 -0
  15. data/lib/ruby_protobuf.rb +1 -1
  16. data/test/addressbook.rb +36 -0
  17. data/test/check_unbuild.rb +1 -1
  18. data/test/collision.rb +18 -0
  19. data/test/data/types.bin +0 -0
  20. data/test/data/unk.png +0 -0
  21. data/test/ext_collision.rb +25 -0
  22. data/test/ext_range.rb +23 -0
  23. data/test/merge.rb +40 -0
  24. data/test/nested.rb +25 -0
  25. data/test/proto/addressbook.pb.rb +69 -0
  26. data/test/{addressbook.proto → proto/addressbook.proto} +1 -0
  27. data/test/proto/addressbook.rb +69 -0
  28. data/test/{addressbook_base.proto → proto/addressbook_base.proto} +0 -0
  29. data/test/{addressbook_ext.proto → proto/addressbook_ext.proto} +0 -0
  30. data/test/proto/bool_default.pb.rb +16 -0
  31. data/test/proto/bool_default.proto +3 -0
  32. data/test/proto/collision.proto +5 -0
  33. data/test/proto/ext_collision.proto +8 -0
  34. data/test/proto/ext_range.proto +7 -0
  35. data/test/proto/float_default.proto +2 -0
  36. data/test/proto/merge.proto +15 -0
  37. data/test/proto/nested.proto +7 -0
  38. data/test/{rpc.proto → proto/rpc.proto} +0 -0
  39. data/test/{types.proto → proto/types.proto} +0 -0
  40. data/test/test_compiler.rb +191 -12
  41. data/test/test_message.rb +86 -0
  42. data/test/test_standard_message.rb +8 -5
  43. data/test/test_types.rb +9 -8
  44. metadata +26 -13
  45. data/Manifest.txt +0 -62
  46. data/examples/addressbook.proto +0 -24
  47. data/examples/addressbook.rb +0 -30
  48. data/examples/reading_a_message.rb +0 -32
  49. data/examples/writing_a_message.rb +0 -46
@@ -1,15 +1,17 @@
1
1
  require 'pp'
2
2
  require 'stringio'
3
+ require 'protobuf/descriptor/descriptor'
3
4
  require 'protobuf/message/decoder'
4
5
  require 'protobuf/message/encoder'
5
6
  require 'protobuf/message/field'
6
- require 'protobuf/descriptor/descriptor'
7
+ require 'protobuf/message/protoable'
7
8
 
8
9
  module Protobuf
9
10
  OPTIONS = {}
10
11
 
11
-
12
12
  class Message
13
+ class TagCollisionError < StandardError; end
14
+
13
15
  class ExtensionFields < Hash
14
16
  def initialize(key_range=0..-1)
15
17
  @key_range = key_range
@@ -26,7 +28,8 @@ module Protobuf
26
28
  end
27
29
 
28
30
  class <<self
29
- attr_reader :fields
31
+ include Protobuf::Protoable
32
+ def fields; @fields ||= [] end #attr_reader :fields
30
33
 
31
34
  def extensions(range)
32
35
  @extension_fields = ExtensionFields.new range
@@ -44,10 +47,13 @@ module Protobuf
44
47
  define_field :repeated, type, name, tag, opts
45
48
  end
46
49
 
47
- def define_field(rule, type, name, tag, opts={})
50
+ def define_field(rule, type, fname, tag, opts={})
48
51
  field_hash = opts[:extension] ? extension_fields : (@fields ||= {})
49
- field_hash[tag] = Protobuf::Field.build self, rule, type, name, tag, opts
50
- #(@fields ||= {})[tag] = Protobuf::Field.build self, rule, type, name, tag, opts
52
+ raise Protobuf::Message::TagCollisionError.new(<<-eos.strip) if field_hash.keys.include? tag
53
+ Field number #{tag} has already been used in "#{self.name}" by field "#{fname}".
54
+ eos
55
+ field_hash[tag] = Protobuf::Field.build self, rule, type, fname, tag, opts
56
+ #(@fields ||= {})[tag] = Protobuf::Field.build self, rule, type, fname, tag, opts
51
57
  end
52
58
 
53
59
  def extension_tag?(tag)
@@ -70,7 +76,7 @@ module Protobuf
70
76
  case tag_or_name
71
77
  when Integer; get_field_by_tag tag_or_name
72
78
  when String, Symbol; get_field_by_name tag_or_name
73
- else; raise TypeError
79
+ else; raise TypeError.new(tag_or_name.class)
74
80
  end
75
81
  end
76
82
 
@@ -89,7 +95,7 @@ module Protobuf
89
95
  case tag_or_name
90
96
  when Integer; get_ext_field_by_tag tag_or_name
91
97
  when String, Symbol; get_ext_field_by_name tag_or_name
92
- else; raise TypeError
98
+ else; raise TypeError.new(tag_or_name.class)
93
99
  end
94
100
  end
95
101
 
@@ -98,7 +104,7 @@ module Protobuf
98
104
  end
99
105
  end
100
106
 
101
- def initialize
107
+ def initialize(values={})
102
108
  fields.each do |tag, field|
103
109
  unless field.ready?
104
110
  field = field.setup
@@ -115,6 +121,8 @@ module Protobuf
115
121
  end
116
122
  field.define_accessor self
117
123
  end
124
+
125
+ values.each {|tag, val| self[tag] = val}
118
126
  end
119
127
 
120
128
  def initialized?
@@ -126,6 +134,14 @@ module Protobuf
126
134
  end
127
135
  end
128
136
 
137
+ def ==(obj)
138
+ return false unless obj.is_a? self.class
139
+ each_field do |field, value|
140
+ return false unless value == obj[field.name]
141
+ end
142
+ true
143
+ end
144
+
129
145
  def clear!
130
146
  each_field do |field, value|
131
147
  field.clear self
@@ -146,13 +162,13 @@ module Protobuf
146
162
  ret
147
163
  end
148
164
 
149
- def to_s(indent=0)
165
+ def inspect(indent=0)
150
166
  ret = ''
151
167
  i = ' ' * indent
152
168
  field_value_to_string = lambda do |field, value|
153
169
  ret +=
154
170
  if field.is_a? Protobuf::Field::MessageField
155
- "#{i}#{field.name} {\n#{value.to_s(indent + 1)}#{i}}\n"
171
+ "#{i}#{field.name} {\n#{value.inspect(indent + 1)}#{i}}\n"
156
172
  elsif field.is_a? Protobuf::Field::EnumField
157
173
  "#{i}#{field.name}: #{field.type.name_by_value(value)}\n"
158
174
  else
@@ -194,6 +210,7 @@ module Protobuf
194
210
  serialize_to io
195
211
  io.string
196
212
  end
213
+ alias to_s serialize_to_string
197
214
 
198
215
  def serialize_to_file(filename)
199
216
  if filename.is_a? File
@@ -209,14 +226,20 @@ module Protobuf
209
226
  Protobuf::Encoder.encode stream, self
210
227
  end
211
228
 
229
+ def merge_from(message)
230
+ # TODO
231
+ fields.each {|tag, field| merge_field tag, message[tag]}
232
+ self.class.extension_fields.each {|tag, field| merge_field tag, message[tag]}
233
+ end
234
+
212
235
  def set_field(tag, bytes)
213
- #get_field_by_tag(tag).set self, bytes
236
+ #get_field_by_tag(tag).set self, bytes # TODO
214
237
  (get_field_by_tag(tag) or get_ext_field_by_tag(tag)).set self, bytes
215
238
  end
216
239
 
217
240
  def merge_field(tag, value)
218
- # TODO
219
- #get_field_by_tag(tag).merge self, bytes
241
+ #get_field_by_tag(tag).merge self, bytes #TODO
242
+ (get_field_by_tag(tag) or get_ext_field_by_tag(tag)).merge self, value
220
243
  end
221
244
 
222
245
  def [](tag_or_name)
@@ -0,0 +1,37 @@
1
+ module Protobuf
2
+ module Protoable
3
+ def defined_filenames
4
+ @defined_filenames ||= []
5
+ end
6
+
7
+ def defined_in(filename)
8
+ defined_filenames << File.expand_path(filename)
9
+ end
10
+
11
+ def proto_filenames
12
+ defined_filenames.map do |filename|
13
+ retrieve_header(File.read(filename)).first
14
+ end
15
+ end
16
+
17
+ def proto_contents
18
+ #TODO: temporary implementation because the result includes not only this message but also all messages
19
+ ret = {}
20
+ defined_filenames.map do |filename|
21
+ header = retrieve_header File.read(filename)
22
+ ret[header.first] = header.last
23
+ end
24
+ ret
25
+ end
26
+
27
+ def retrieve_header(contents)
28
+ if contents =~ /### Generated by rprotoc\. DO NOT EDIT!\n### <proto file: (.*)>\n((# .*\n)+)/
29
+ proto_filename = $1
30
+ proto_contents = $2.gsub(/^# /, '')
31
+ [proto_filename, proto_contents]
32
+ else
33
+ [nil, nil]
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,3 +1,3 @@
1
1
  class RubyProtobuf
2
- VERSION = '0.3.0'
2
+ VERSION = '0.3.2'
3
3
  end
@@ -1,3 +1,35 @@
1
+ ### Generated by rprotoc. DO NOT EDIT!
2
+ ### <proto file: test/addressbook.proto>
3
+ # package tutorial;
4
+ #
5
+ # message Person {
6
+ # required string name = 1;
7
+ # required int32 id = 2;
8
+ # optional string email = 3;
9
+ #
10
+ # enum PhoneType {
11
+ # MOBILE = 0;
12
+ # HOME = 1;
13
+ # WORK = 2;
14
+ # }
15
+ #
16
+ # message PhoneNumber {
17
+ # required string number = 1;
18
+ # optional PhoneType type = 2 [default = HOME];
19
+ # }
20
+ #
21
+ # repeated PhoneNumber phone = 4;
22
+ #
23
+ # extensions 100 to 200;
24
+ # }
25
+ #
26
+ # extend Person {
27
+ # optional int32 age = 100;
28
+ # }
29
+ #
30
+ # message AddressBook {
31
+ # repeated Person person = 1;
32
+ # }
1
33
  require 'protobuf/message/message'
2
34
  require 'protobuf/message/enum'
3
35
  require 'protobuf/message/service'
@@ -6,17 +38,20 @@ require 'protobuf/message/extend'
6
38
  module Tutorial
7
39
 
8
40
  class Person < ::Protobuf::Message
41
+ defined_in __FILE__
9
42
  required :string, :name, 1
10
43
  required :int32, :id, 2
11
44
  optional :string, :email, 3
12
45
 
13
46
  class PhoneType < ::Protobuf::Enum
47
+ defined_in __FILE__
14
48
  MOBILE = 0
15
49
  HOME = 1
16
50
  WORK = 2
17
51
  end
18
52
 
19
53
  class PhoneNumber < ::Protobuf::Message
54
+ defined_in __FILE__
20
55
  required :string, :number, 1
21
56
  optional :PhoneType, :type, 2, {:default => :HOME}
22
57
  end
@@ -32,6 +67,7 @@ module Tutorial
32
67
  #end
33
68
 
34
69
  class AddressBook < ::Protobuf::Message
70
+ defined_in __FILE__
35
71
  repeated :Person, :person, 1
36
72
  end
37
73
 
@@ -1,4 +1,4 @@
1
- #!/usr/local/bin/ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  $:.push "#{File.dirname(__FILE__)}/../lib"
4
4
 
@@ -0,0 +1,18 @@
1
+ ### Generated by rprotoc. DO NOT EDIT!
2
+ ### <proto file: test/proto/collision.proto>
3
+ # message CollisionTest {
4
+ # optional string a = 1;
5
+ # optional string b = 1;
6
+ # }
7
+ #
8
+
9
+ require 'protobuf/message/message'
10
+ require 'protobuf/message/enum'
11
+ require 'protobuf/message/service'
12
+ require 'protobuf/message/extend'
13
+
14
+ class CollisionTest < ::Protobuf::Message
15
+ defined_in __FILE__
16
+ optional :string, :a, 1
17
+ optional :string, :b, 1
18
+ end
Binary file
Binary file
@@ -0,0 +1,25 @@
1
+ ### Generated by rprotoc. DO NOT EDIT!
2
+ ### <proto file: test/proto/ext_collision.proto>
3
+ # message ExtCollisionTest {
4
+ # extensions 1 to 10;
5
+ # }
6
+ #
7
+ # message ExtCollisionTest {
8
+ # optional string a = 1;
9
+ # optional string b = 1;
10
+ # }
11
+
12
+ require 'protobuf/message/message'
13
+ require 'protobuf/message/enum'
14
+ require 'protobuf/message/service'
15
+ require 'protobuf/message/extend'
16
+
17
+ class ExtCollisionTest < ::Protobuf::Message
18
+ defined_in __FILE__
19
+ extensions 1..10
20
+ end
21
+ class ExtCollisionTest < ::Protobuf::Message
22
+ defined_in __FILE__
23
+ optional :string, :a, 1
24
+ optional :string, :b, 1
25
+ end
@@ -0,0 +1,23 @@
1
+ ### Generated by rprotoc. DO NOT EDIT!
2
+ ### <proto file: test/proto/ext_range.proto>
3
+ # message ExtCollisionTest {
4
+ # extensions 1 to 10;
5
+ # }
6
+ #
7
+ # message ExtCollisionTest {
8
+ # optional string a = 11;
9
+ # }
10
+
11
+ require 'protobuf/message/message'
12
+ require 'protobuf/message/enum'
13
+ require 'protobuf/message/service'
14
+ require 'protobuf/message/extend'
15
+
16
+ class ExtCollisionTest < ::Protobuf::Message
17
+ defined_in __FILE__
18
+ extensions 1..10
19
+ end
20
+ class ExtCollisionTest < ::Protobuf::Message
21
+ defined_in __FILE__
22
+ optional :string, :a, 11, :extension => true
23
+ end
@@ -0,0 +1,40 @@
1
+ ### Generated by rprotoc. DO NOT EDIT!
2
+ ### <proto file: test/merge.proto>
3
+ # package test;
4
+ #
5
+ # message MergeMessage {
6
+ # message InnerMessage1 {
7
+ # required string name = 1;
8
+ # }
9
+ # message InnerMessage2 {
10
+ # required string name = 1;
11
+ # repeated InnerMessage1 repeate_message = 2;
12
+ # }
13
+ #
14
+ # required string name = 1;
15
+ # repeated InnerMessage1 repeate_message = 2;
16
+ # required InnerMessage2 require_message = 3;
17
+ # }
18
+
19
+ require 'protobuf/message/message'
20
+ require 'protobuf/message/enum'
21
+ require 'protobuf/message/service'
22
+ require 'protobuf/message/extend'
23
+
24
+ module Test
25
+ class MergeMessage < ::Protobuf::Message
26
+ defined_in __FILE__
27
+ class InnerMessage1 < ::Protobuf::Message
28
+ defined_in __FILE__
29
+ required :string, :name, 1
30
+ end
31
+ class InnerMessage2 < ::Protobuf::Message
32
+ defined_in __FILE__
33
+ required :string, :name, 1
34
+ repeated :InnerMessage1, :repeate_message, 2
35
+ end
36
+ required :string, :name, 1
37
+ repeated :InnerMessage1, :repeate_message, 2
38
+ required :InnerMessage2, :require_message, 3
39
+ end
40
+ end
@@ -0,0 +1,25 @@
1
+ ### Generated by rprotoc. DO NOT EDIT!
2
+ ### <proto file: test/nested.proto>
3
+ # message Foo {
4
+ # message Bar {
5
+ # }
6
+ # }
7
+ # message Baaz {
8
+ # optional Foo.Bar x = 1;
9
+ # }
10
+
11
+ require 'protobuf/message/message'
12
+ require 'protobuf/message/enum'
13
+ require 'protobuf/message/service'
14
+ require 'protobuf/message/extend'
15
+
16
+ class Foo < ::Protobuf::Message
17
+ defined_in __FILE__
18
+ class Bar < ::Protobuf::Message
19
+ defined_in __FILE__
20
+ end
21
+ end
22
+ class Baaz < ::Protobuf::Message
23
+ defined_in __FILE__
24
+ optional :'Foo::Bar', :x, 1
25
+ end
@@ -0,0 +1,69 @@
1
+ ### Generated by rprotoc. DO NOT EDIT!
2
+ ### <proto file: test/proto/addressbook.proto>
3
+ # package tutorial;
4
+ #
5
+ # message Person {
6
+ # required string name = 1;
7
+ # required int32 id = 2;
8
+ # optional string email = 3;
9
+ #
10
+ # enum PhoneType {
11
+ # MOBILE = 0;
12
+ # HOME = 1;
13
+ # WORK = 2;
14
+ # }
15
+ #
16
+ # message PhoneNumber {
17
+ # required string number = 1;
18
+ # optional PhoneType type = 2 [default = HOME];
19
+ # }
20
+ #
21
+ # repeated PhoneNumber phone = 4;
22
+ # optional uint32 age = 5 [default = 20];
23
+ #
24
+ # extensions 100 to 200;
25
+ # }
26
+ #
27
+ # extend Person {
28
+ # optional int32 age = 100;
29
+ # }
30
+ #
31
+ # message AddressBook {
32
+ # repeated Person person = 1;
33
+ # }
34
+
35
+ require 'protobuf/message/message'
36
+ require 'protobuf/message/enum'
37
+ require 'protobuf/message/service'
38
+ require 'protobuf/message/extend'
39
+
40
+ module Tutorial
41
+ class Person < ::Protobuf::Message
42
+ defined_in __FILE__
43
+ required :string, :name, 1
44
+ required :int32, :id, 2
45
+ optional :string, :email, 3
46
+ class PhoneType < ::Protobuf::Enum
47
+ defined_in __FILE__
48
+ MOBILE = 0
49
+ HOME = 1
50
+ WORK = 2
51
+ end
52
+ class PhoneNumber < ::Protobuf::Message
53
+ defined_in __FILE__
54
+ required :string, :number, 1
55
+ optional :PhoneType, :type, 2, :default => :HOME
56
+ end
57
+ repeated :PhoneNumber, :phone, 4
58
+ optional :uint32, :age, 5, :default => 20
59
+ extensions 100..200
60
+ end
61
+ class Person < ::Protobuf::Message
62
+ defined_in __FILE__
63
+ optional :int32, :age, 100, :extension => true
64
+ end
65
+ class AddressBook < ::Protobuf::Message
66
+ defined_in __FILE__
67
+ repeated :Person, :person, 1
68
+ end
69
+ end