ruby_protobuf 0.3.3 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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;