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
@@ -10,7 +10,6 @@ module Protobuf
10
10
  OPTIONS = {}
11
11
 
12
12
  class Message
13
- class TagCollisionError < StandardError; end
14
13
 
15
14
  class ExtensionFields < Hash
16
15
  def initialize(key_range=0..-1)
@@ -18,65 +17,78 @@ module Protobuf
18
17
  end
19
18
 
20
19
  def []=(key, value)
21
- raise RangeError.new("#{key} is not in #{@key_range}") unless @key_range.include? key
20
+ raise RangeError, "#{key} is not in #{@key_range}" unless @key_range.include?(key)
22
21
  super
23
22
  end
24
23
 
25
24
  def include_tag?(tag)
26
- @key_range.include? tag
25
+ @key_range.include?(tag)
27
26
  end
28
27
  end
29
28
 
30
29
  class <<self
31
- include Protobuf::Protoable
32
- def fields; @fields ||= {} end
30
+ include Protoable
33
31
 
32
+ # Reserve field numbers for extensions. Don't use this method directly.
34
33
  def extensions(range)
35
- @extension_fields = ExtensionFields.new range
34
+ @extension_fields = ExtensionFields.new(range)
36
35
  end
37
36
 
38
- def required(type, name, tag, opts={})
39
- define_field :required, type, name, tag, opts
37
+ # Define a required field. Don't use this method directly.
38
+ def required(type, name, tag, options={})
39
+ define_field(:required, type, name, tag, options)
40
40
  end
41
41
 
42
- def optional(type, name, tag, opts={})
43
- define_field :optional, type, name, tag, opts
42
+ # Define a optional field. Don't use this method directly.
43
+ def optional(type, name, tag, options={})
44
+ define_field(:optional, type, name, tag, options)
44
45
  end
45
46
 
46
- def repeated(type, name, tag, opts={})
47
- define_field :repeated, type, name, tag, opts
47
+ # Define a repeated field. Don't use this method directly.
48
+ def repeated(type, name, tag, options={})
49
+ define_field(:repeated, type, name, tag, options)
48
50
  end
49
51
 
50
- def define_field(rule, type, fname, tag, opts={})
51
- field_hash = opts[:extension] ? extension_fields : (@fields ||= {})
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
52
+ # Define a field. Don't use this method directly.
53
+ def define_field(rule, type, fname, tag, options)
54
+ field_hash = options[:extension] ? extension_fields : fields
55
+ if field_hash.keys.include?(tag)
56
+ raise TagCollisionError, %!{Field number #{tag} has already been used in "#{self.name}" by field "#{fname}".!
57
+ end
58
+ field_hash[tag] = Field.build(self, rule, type, fname, tag, options)
56
59
  end
57
60
 
58
61
  def extension_tag?(tag)
59
- extension_fields.include_tag? tag
62
+ extension_fields.include_tag?(tag)
63
+ end
64
+
65
+ # A collection of field object.
66
+ def fields
67
+ @fields ||= {}
60
68
  end
61
69
 
70
+ # An extension field object.
62
71
  def extension_fields
63
72
  @extension_fields ||= ExtensionFields.new
64
73
  end
65
74
 
75
+ # Find a field object by +name+.
66
76
  def get_field_by_name(name)
67
77
  name = name.to_sym
68
78
  fields.values.find {|field| field.name == name}
69
79
  end
70
80
 
81
+ # Find a field object by +tag+ number.
71
82
  def get_field_by_tag(tag)
72
83
  fields[tag]
73
84
  end
74
85
 
86
+ # Find a field object by +tag_or_name+.
75
87
  def get_field(tag_or_name)
76
88
  case tag_or_name
77
- when Integer; get_field_by_tag tag_or_name
78
- when String, Symbol; get_field_by_name tag_or_name
79
- else; raise TypeError.new(tag_or_name.class)
89
+ when Integer then get_field_by_tag(tag_or_name)
90
+ when String, Symbol then get_field_by_name(tag_or_name)
91
+ else raise TypeError, tag_or_name.class
80
92
  end
81
93
  end
82
94
 
@@ -94,38 +106,38 @@ module Protobuf
94
106
  #TODO merge to get_field
95
107
  def get_ext_field(tag_or_name)
96
108
  case tag_or_name
97
- when Integer; get_ext_field_by_tag tag_or_name
98
- when String, Symbol; get_ext_field_by_name tag_or_name
99
- else; raise TypeError.new(tag_or_name.class)
109
+ when Integer then get_ext_field_by_tag(tag_or_name)
110
+ when String, Symbol then get_ext_field_by_name(tag_or_name)
111
+ else raise TypeError, tag_or_name.class
100
112
  end
101
113
  end
102
114
 
103
115
  def descriptor
104
- @descriptor ||= Protobuf::Descriptor::Descriptor.new(self)
116
+ @descriptor ||= Descriptor::Descriptor.new(self)
105
117
  end
106
118
  end
107
119
 
108
120
  def initialize(values={})
109
121
  @values = {}
110
122
 
111
- self.class.fields.each do |tag, field|
123
+ self.class.fields.to_a.each do |tag, field|
112
124
  unless field.ready?
113
125
  field = field.setup
114
- self.class.class_eval {@fields[tag] = field}
126
+ self.class.fields[tag] = field
115
127
  end
116
128
  if field.repeated?
117
- @values[field.name] = Protobuf::Field::FieldArray.new(field)
129
+ @values[field.name] = Field::FieldArray.new(field)
118
130
  end
119
131
  end
120
132
 
121
133
  # TODO
122
- self.class.extension_fields.each do |tag, field|
134
+ self.class.extension_fields.to_a.each do |tag, field|
123
135
  unless field.ready?
124
136
  field = field.setup
125
- self.class.class_eval {@extension_fields[tag] = field}
137
+ self.class.extension_fields[tag] = field
126
138
  end
127
139
  if field.repeated?
128
- @values[field.name] = Protobuf::Field::FieldArray.new(field)
140
+ @values[field.name] = Field::FieldArray.new(field)
129
141
  end
130
142
  end
131
143
 
@@ -134,175 +146,219 @@ module Protobuf
134
146
 
135
147
  def initialized?
136
148
  fields.all? {|tag, field| field.initialized?(self) } && \
137
- extension_fields.all? {|tag, field| field.initialized?(self) }
149
+ extension_fields.all? {|tag, field| field.initialized?(self) }
138
150
  end
139
151
 
140
152
  def has_field?(tag_or_name)
141
153
  field = get_field(tag_or_name) || get_ext_field(tag_or_name)
142
- raise ArgumentError.new("unknown field: #{tag_or_name.inspect}") unless field
154
+ raise ArgumentError, "unknown field: #{tag_or_name.inspect}" unless field
143
155
  @values.has_key?(field.name)
144
156
  end
145
157
 
146
158
  def ==(obj)
147
- return false unless obj.is_a? self.class
159
+ return false unless obj.is_a?(self.class)
148
160
  each_field do |field, value|
149
- return false unless value == obj.send(field.name)
161
+ return false unless value == obj.__send__(field.name)
150
162
  end
151
163
  true
152
164
  end
153
165
 
154
166
  def clear!
155
- each_field do |field, value|
156
- field.clear self
167
+ @values.delete_if do |_, value|
168
+ if value.is_a?(Field::FieldArray)
169
+ value.clear
170
+ false
171
+ else
172
+ true
173
+ end
157
174
  end
175
+ self
158
176
  end
159
177
 
160
178
  def dup
161
- ret = self.class.new
162
- each_field do |field, value|
163
- if field.repeated?
164
- field_array = ret.send(field.name)
165
- value.each do |v|
166
- field_array << (v.is_a?(Numeric) ? v : v.dup)
167
- end
179
+ copy_to(super, :dup)
180
+ end
181
+
182
+ def clone
183
+ copy_to(super, :clone)
184
+ end
185
+
186
+ def copy_to(object, method)
187
+ duplicate = proc {|obj|
188
+ case obj
189
+ when Message, String then obj.__send__(method)
190
+ else obj
191
+ end
192
+ }
193
+
194
+ object.__send__(:initialize)
195
+ @values.each do |name, value|
196
+ if value.is_a?(Field::FieldArray)
197
+ object.__send__(name).replace(value.map {|v| duplicate.call(v)})
168
198
  else
169
- ret.send("#{field.name}=", value.is_a?(Numeric) ? value : value.dup)
199
+ object.__send__("#{name}=", duplicate.call(value))
170
200
  end
171
201
  end
172
- ret
202
+ object
173
203
  end
204
+ private :copy_to
174
205
 
175
206
  def inspect(indent=0)
176
- ret = ''
207
+ result = []
177
208
  i = ' ' * indent
178
- field_value_to_string = lambda do |field, value|
179
- ret +=
180
- if field.is_a? Protobuf::Field::MessageField
181
- if value.nil?
182
- if $DEBUG
183
- "#{i}#{field.name} {\n#{' ' * (indent + 1)}nil\n#{i}}\n"
184
- else
209
+ field_value_to_string = lambda {|field, value|
210
+ result << \
211
+ if field.optional? && ! has_field?(field.name)
212
+ ''
213
+ else
214
+ case field
215
+ when Field::MessageField
216
+ if value.nil?
185
217
  "#{i}#{field.name} {}\n"
218
+ else
219
+ "#{i}#{field.name} {\n#{value.inspect(indent + 1)}#{i}}\n"
186
220
  end
187
- else
188
- "#{i}#{field.name} {\n#{value.inspect(indent + 1)}#{i}}\n"
189
- end
190
- elsif field.is_a? Protobuf::Field::EnumField
191
- if field.optional? and not has_field?(field.name)
192
- ''
193
- else
194
- "#{i}#{field.name}: #{field.type.name_by_value(value)}\n"
195
- end
196
- else
197
- if $DEBUG
198
- "#{i}#{field.name}: #{value.inspect}\n"
199
- else
200
- if field.optional? and not has_field?(field.name)
201
- ''
221
+ when Field::EnumField
222
+ if value.is_a?(EnumValue)
223
+ "#{i}#{field.name}: #{value.name}\n"
202
224
  else
203
- "#{i}#{field.name}: #{value.inspect}\n"
225
+ "#{i}#{field.name}: #{field.type.name_by_value(value)}\n"
204
226
  end
227
+ else
228
+ "#{i}#{field.name}: #{value.inspect}\n"
205
229
  end
206
230
  end
207
- end
231
+ }
208
232
  each_field do |field, value|
209
233
  if field.repeated?
210
- value.each do |v|
211
- field_value_to_string.call field, v
234
+ value.each do |v|
235
+ field_value_to_string.call(field, v)
212
236
  end
213
- else
214
- field_value_to_string.call field, value
237
+ else
238
+ field_value_to_string.call(field, value)
215
239
  end
216
240
  end
217
- ret
241
+ result.join
218
242
  end
219
243
 
220
244
  def parse_from_string(string)
221
- parse_from StringIO.new(string)
245
+ parse_from(StringIO.new(string))
222
246
  end
223
247
 
224
248
  def parse_from_file(filename)
225
- if filename.is_a? File
226
- parse_from filename
249
+ if filename.is_a?(File)
250
+ parse_from(filename)
227
251
  else
228
252
  File.open(filename, 'rb') do |f|
229
- parse_from f
253
+ parse_from(f)
230
254
  end
231
255
  end
232
256
  end
233
257
 
234
258
  def parse_from(stream)
235
- Protobuf::Decoder.decode stream, self
259
+ Decoder.decode(stream, self)
236
260
  end
237
261
 
238
262
  def serialize_to_string(string='')
239
- io = StringIO.new string
240
- serialize_to io
263
+ io = StringIO.new(string)
264
+ serialize_to(io)
241
265
  result = io.string
242
- result.force_encoding('ASCII-8BIT') if result.respond_to?(:force_encoding)
266
+ result.force_encoding(Encoding::ASCII_8BIT) if result.respond_to?(:force_encoding)
243
267
  result
244
268
  end
245
269
  alias to_s serialize_to_string
246
270
 
247
271
  def serialize_to_file(filename)
248
- if filename.is_a? File
249
- serialize_to filename
272
+ if filename.is_a?(File)
273
+ serialize_to(filename)
250
274
  else
251
275
  File.open(filename, 'wb') do |f|
252
- serialize_to f
276
+ serialize_to(f)
253
277
  end
254
278
  end
255
279
  end
256
280
 
257
281
  def serialize_to(stream)
258
- Protobuf::Encoder.encode stream, self
282
+ Encoder.encode(stream, self)
259
283
  end
260
284
 
261
285
  def merge_from(message)
262
286
  # TODO
263
- fields.each {|tag, field| merge_field tag, message[tag]}
264
- self.class.extension_fields.each {|tag, field| merge_field tag, message[tag]}
287
+ fields.each {|tag, field| merge_field(tag, message.__send__(field.name))}
288
+ extension_fields.each {|tag, field| merge_field(tag, message.__send__(field.name))}
265
289
  end
266
290
 
267
291
  def set_field(tag, bytes)
268
- field = (get_field_by_tag(tag) or get_ext_field_by_tag(tag))
269
- field.set self, bytes if field
292
+ field = (get_field_by_tag(tag) || get_ext_field_by_tag(tag))
293
+ field.set(self, bytes) if field
270
294
  end
271
-
295
+
272
296
  def merge_field(tag, value)
273
297
  #get_field_by_tag(tag).merge self, bytes #TODO
274
- (get_field_by_tag(tag) or get_ext_field_by_tag(tag)).merge self, value
298
+ (get_field_by_tag(tag) || get_ext_field_by_tag(tag)).merge(self, value)
275
299
  end
276
-
300
+
277
301
  def [](tag_or_name)
278
302
  if field = get_field(tag_or_name) || get_ext_field(tag_or_name)
279
- send field.name
303
+ __send__(field.name)
280
304
  else
281
- raise NoMethodError.new("No such field: #{tag_or_name.inspect}")
305
+ raise NoMethodError, "No such field: #{tag_or_name.inspect}"
282
306
  end
283
307
  end
284
308
 
285
309
  def []=(tag_or_name, value)
286
310
  if field = get_field(tag_or_name) || get_ext_field(tag_or_name)
287
- send "#{field.name}=", value
311
+ __send__("#{field.name}=", value)
288
312
  else
289
- raise NoMethodError.new("No such field: #{tag_or_name.inspect}")
313
+ raise NoMethodError, "No such field: #{tag_or_name.inspect}"
290
314
  end
291
315
  end
292
316
 
293
- def fields; self.class.fields end
294
- def get_field_by_name(name); self.class.get_field_by_name(name) end
295
- def get_field_by_tag(tag); self.class.get_field_by_tag(tag) end
296
- def get_field(tag_or_name); self.class.get_field(tag_or_name) end
317
+ # Returns a hash; which key is a tag number, and value is a field object.
318
+ def fields
319
+ self.class.fields
320
+ end
321
+
322
+ # Returns field object or +nil+.
323
+ def get_field_by_name(name)
324
+ self.class.get_field_by_name(name)
325
+ end
297
326
 
298
- def extension_fields; self.class.extension_fields end
299
- def get_ext_field_by_name(name); self.class.get_ext_field_by_name(name) end
300
- def get_ext_field_by_tag(tag); self.class.get_ext_field_by_tag(tag) end
301
- def get_ext_field(tag_or_name); self.class.get_ext_field(tag_or_name) end
327
+ # Returns field object or +nil+.
328
+ def get_field_by_tag(tag)
329
+ self.class.get_field_by_tag(tag)
330
+ end
331
+
332
+ # Returns field object or +nil+.
333
+ def get_field(tag_or_name)
334
+ self.class.get_field(tag_or_name)
335
+ end
336
+
337
+ # Returns extension fields. See Message#fields method.
338
+ def extension_fields
339
+ self.class.extension_fields
340
+ end
341
+
342
+ def get_ext_field_by_name(name) # :nodoc:
343
+ self.class.get_ext_field_by_name(name)
344
+ end
345
+
346
+ def get_ext_field_by_tag(tag) # :nodoc:
347
+ self.class.get_ext_field_by_tag(tag)
348
+ end
349
+
350
+ def get_ext_field(tag_or_name) # :nodoc:
351
+ self.class.get_ext_field(tag_or_name)
352
+ end
302
353
 
354
+ # Iterate over a field collection.
355
+ # message.each_field do |field_object, value|
356
+ # # do something
357
+ # end
303
358
  def each_field
304
- (fields.merge extension_fields).sort_by {|tag, field| tag}.each do |tag, field|
305
- yield field, send(field.name)
359
+ fields.merge(extension_fields).sort_by {|tag, _| tag}.each do |_, field|
360
+ value = __send__(field.name)
361
+ yield(field, value)
306
362
  end
307
363
  end
308
364
  end
@@ -5,7 +5,8 @@ module Protobuf
5
5
  end
6
6
 
7
7
  def defined_in(filename)
8
- defined_filenames << File.expand_path(filename)
8
+ path = File.expand_path(filename)
9
+ defined_filenames << path unless defined_filenames.include?(path)
9
10
  end
10
11
 
11
12
  def proto_filenames
@@ -17,8 +18,8 @@ module Protobuf
17
18
  def proto_contents
18
19
  #TODO: temporary implementation because the result includes not only this message but also all messages
19
20
  ret = {}
20
- defined_filenames.map do |filename|
21
- header = retrieve_header File.read(filename)
21
+ defined_filenames.each do |filename|
22
+ header = retrieve_header(File.read(filename))
22
23
  ret[header.first] = header.last
23
24
  end
24
25
  ret
@@ -2,7 +2,7 @@ module Protobuf
2
2
  class Service
3
3
  class <<self
4
4
  def rpc(hash)
5
- raise NotImplementedError('TODO')
5
+ raise NotImplementedError, 'TODO'
6
6
  end
7
7
  end
8
8
  end
@@ -8,11 +8,11 @@ module Protobuf
8
8
  end
9
9
 
10
10
  def call(name, request, response)
11
- socket = TCPSocket.open @host, @port
11
+ socket = TCPSocket.open(@host, @port)
12
12
  socket.write "#{name}\n"
13
- request.serialize_to socket
13
+ request.serialize_to(socket)
14
14
  socket.close_write
15
- response.parse_from socket
15
+ response.parse_from(socket)
16
16
  end
17
17
  end
18
18
  end
@@ -7,7 +7,7 @@ module Protobuf
7
7
  def request(request_class)
8
8
  @request_class = request_class
9
9
  end
10
-
10
+
11
11
  def response(response_class)
12
12
  @response_class = response_class
13
13
  end
@@ -5,7 +5,7 @@ module Protobuf
5
5
  module Rpc
6
6
  class Server < WEBrick::GenericServer
7
7
  def initialize(config={:Port => 9999}, default=WEBrick::Config::General)
8
- super config, default
8
+ super(config, default)
9
9
  setup_handlers
10
10
  end
11
11
 
@@ -20,17 +20,17 @@ module Protobuf
20
20
  def run(socket)
21
21
  handler = get_handler socket
22
22
  request = handler.request_class.new
23
- request.parse_from socket
23
+ request.parse_from(socket)
24
24
  response = handler.response_class.new
25
25
  begin
26
- handler.process_request request, response
27
- rescue StandardError => ex
28
- @logger.error ex
26
+ handler.process_request(request, response)
27
+ rescue StandardError
28
+ @logger.error $!
29
29
  ensure
30
30
  begin
31
- response.serialize_to socket
32
- rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN => ex
33
- @logger.error ex
31
+ response.serialize_to(socket)
32
+ rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN
33
+ @logger.error $!
34
34
  end
35
35
  end
36
36
  end
data/lib/ruby_protobuf.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class RubyProtobuf
2
- VERSION = '0.3.3'
2
+ VERSION = '0.4.1'
3
3
  end
@@ -14,17 +14,17 @@ class DescriptorTest < Test::Unit::TestCase
14
14
 
15
15
  assert_nothing_raised {Tutorial::Person}
16
16
  assert_nothing_raised {Tutorial::Person.new}
17
- assert_equal ['email', 'id', 'name', 'phone'],
18
- Tutorial::Person.fields.map{|tag, field| field.name}.sort
17
+ assert_equal(['age', 'email', 'id', 'name', 'phone'],
18
+ Tutorial::Person.fields.map{|tag, field| field.name}.sort)
19
19
 
20
20
  assert_nothing_raised {Tutorial::Person::PhoneNumber}
21
21
  assert_nothing_raised {Tutorial::Person::PhoneNumber.new}
22
- assert_equal ['number', 'type'],
23
- Tutorial::Person::PhoneNumber.fields.map{|tag, field| field.name}.sort
22
+ assert_equal(['number', 'type'],
23
+ Tutorial::Person::PhoneNumber.fields.map{|tag, field| field.name}.sort)
24
24
 
25
25
  assert_nothing_raised {Tutorial::Person::PhoneType}
26
- assert_equal 0, Tutorial::Person::PhoneType::MOBILE
27
- assert_equal 1, Tutorial::Person::PhoneType::HOME
28
- assert_equal 2, Tutorial::Person::PhoneType::WORK
26
+ assert_equal(0, Tutorial::Person::PhoneType::MOBILE)
27
+ assert_equal(1, Tutorial::Person::PhoneType::HOME)
28
+ assert_equal(2, Tutorial::Person::PhoneType::WORK)
29
29
  end
30
30
  end
@@ -0,0 +1,67 @@
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
+ # /*
28
+ # extend Person {
29
+ # optional int32 age = 100;
30
+ # }
31
+ # */
32
+ #
33
+ # message AddressBook {
34
+ # repeated Person person = 1;
35
+ # }
36
+
37
+ require 'protobuf/message/message'
38
+ require 'protobuf/message/enum'
39
+ require 'protobuf/message/service'
40
+ require 'protobuf/message/extend'
41
+
42
+ module Tutorial
43
+ class Person < ::Protobuf::Message
44
+ defined_in __FILE__
45
+ required :string, :name, 1
46
+ required :int32, :id, 2
47
+ optional :string, :email, 3
48
+ class PhoneType < ::Protobuf::Enum
49
+ defined_in __FILE__
50
+ define :MOBILE, 0
51
+ define :HOME, 1
52
+ define :WORK, 2
53
+ end
54
+ class PhoneNumber < ::Protobuf::Message
55
+ defined_in __FILE__
56
+ required :string, :number, 1
57
+ optional :PhoneType, :type, 2, :default => :HOME
58
+ end
59
+ repeated :PhoneNumber, :phone, 4
60
+ optional :uint32, :age, 5, :default => 20
61
+ extensions 100..200
62
+ end
63
+ class AddressBook < ::Protobuf::Message
64
+ defined_in __FILE__
65
+ repeated :Person, :person, 1
66
+ end
67
+ end
@@ -22,9 +22,11 @@ message Person {
22
22
  extensions 100 to 200;
23
23
  }
24
24
 
25
+ /*
25
26
  extend Person {
26
27
  optional int32 age = 100;
27
28
  }
29
+ */
28
30
 
29
31
  message AddressBook {
30
32
  repeated Person person = 1;