ruby_protobuf 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/History.txt +6 -1
  2. data/Manifest.txt +23 -2
  3. data/bin/rprotoc +5 -5
  4. data/examples/addressbook.proto +24 -0
  5. data/examples/addressbook.rb +30 -0
  6. data/examples/reading_a_message.rb +32 -0
  7. data/examples/writing_a_message.rb +46 -0
  8. data/lib/protobuf/compiler/compiler.rb +38 -74
  9. data/lib/protobuf/compiler/compiler_old.rb +123 -0
  10. data/lib/protobuf/compiler/nodes.rb +208 -0
  11. data/lib/protobuf/compiler/proto.y +198 -0
  12. data/lib/protobuf/compiler/proto2.ebnf +79 -0
  13. data/lib/protobuf/compiler/proto_parser.rb +1259 -0
  14. data/lib/protobuf/compiler/template/rpc_bin.erb +4 -0
  15. data/lib/protobuf/compiler/template/rpc_client.erb +18 -0
  16. data/lib/protobuf/compiler/template/rpc_service.erb +25 -0
  17. data/lib/protobuf/compiler/visitors.rb +132 -0
  18. data/lib/protobuf/message/decoder.rb +8 -3
  19. data/lib/protobuf/message/enum.rb +4 -0
  20. data/lib/protobuf/message/field.rb +31 -5
  21. data/lib/protobuf/message/message.rb +130 -14
  22. data/lib/protobuf/rpc/client.rb +19 -0
  23. data/lib/protobuf/rpc/handler.rb +17 -0
  24. data/lib/protobuf/rpc/server.rb +39 -0
  25. data/lib/ruby_protobuf.rb +1 -20
  26. data/test/addressbook.proto +6 -0
  27. data/test/addressbook.rb +17 -14
  28. data/test/addressbook_base.proto +26 -0
  29. data/test/addressbook_base.rb +62 -0
  30. data/test/addressbook_ext.proto +6 -0
  31. data/test/addressbook_ext.rb +12 -0
  32. data/test/rpc.proto +6 -0
  33. data/test/test_addressbook.rb +3 -2
  34. data/test/test_compiler.rb +98 -3
  35. data/test/test_extension.rb +40 -0
  36. data/test/test_standard_message.rb +83 -0
  37. data/test/test_types.rb +3 -3
  38. metadata +31 -8
  39. data/lib/protobuf/compiler/parser.y +0 -138
  40. data/test/data/data2.bin +0 -3
data/History.txt CHANGED
@@ -1,5 +1,10 @@
1
- === 0.2.0 / 2008-08-05
1
+ === 0.3.0 / 2008-08-19
2
2
 
3
+ * 0.3.0 RPC is available (rev.124)
4
+ * RPC is available
5
+ * New compiler using racc (ruby version of yacc)
6
+ * Rename `sample' directory to `example'
7
+ * 0.2.1 extensions and import are available (rev.82)
3
8
  * 0.2.0 introduce descriptor (rev.75)
4
9
  * Message structures can be restored from encoded data by means a descriptor object
5
10
  * 0.1.0 fixed a small bug
data/Manifest.txt CHANGED
@@ -3,9 +3,21 @@ Manifest.txt
3
3
  README.txt
4
4
  Rakefile
5
5
  bin/rprotoc
6
+ examples/addressbook.proto
7
+ examples/addressbook.rb
8
+ examples/reading_a_message.rb
9
+ examples/writing_a_message.rb
6
10
  lib/protobuf/common/wire_type.rb
7
11
  lib/protobuf/compiler/compiler.rb
8
- lib/protobuf/compiler/parser.y
12
+ lib/protobuf/compiler/compiler_old.rb
13
+ lib/protobuf/compiler/nodes.rb
14
+ lib/protobuf/compiler/proto.y
15
+ lib/protobuf/compiler/proto2.ebnf
16
+ lib/protobuf/compiler/proto_parser.rb
17
+ lib/protobuf/compiler/template/rpc_bin.erb
18
+ lib/protobuf/compiler/template/rpc_client.erb
19
+ lib/protobuf/compiler/template/rpc_service.erb
20
+ lib/protobuf/compiler/visitors.rb
9
21
  lib/protobuf/descriptor/descriptor.proto
10
22
  lib/protobuf/descriptor/descriptor.rb
11
23
  lib/protobuf/descriptor/descriptor_builder.rb
@@ -20,22 +32,31 @@ lib/protobuf/message/extend.rb
20
32
  lib/protobuf/message/field.rb
21
33
  lib/protobuf/message/message.rb
22
34
  lib/protobuf/message/service.rb
35
+ lib/protobuf/rpc/client.rb
36
+ lib/protobuf/rpc/handler.rb
37
+ lib/protobuf/rpc/server.rb
23
38
  lib/ruby_protobuf.rb
24
39
  test/addressbook.proto
25
40
  test/addressbook.rb
41
+ test/addressbook_base.proto
42
+ test/addressbook_base.rb
43
+ test/addressbook_ext.proto
44
+ test/addressbook_ext.rb
26
45
  test/check_unbuild.rb
27
46
  test/data/data.bin
28
- test/data/data2.bin
29
47
  test/data/data_source.py
30
48
  test/data/types.bin
31
49
  test/data/types_source.py
50
+ test/rpc.proto
32
51
  test/test_addressbook.rb
33
52
  test/test_compiler.rb
34
53
  test/test_descriptor.rb
54
+ test/test_extension.rb
35
55
  test/test_message.rb
36
56
  test/test_parse.rb
37
57
  test/test_ruby_protobuf.rb
38
58
  test/test_serialize.rb
59
+ test/test_standard_message.rb
39
60
  test/test_types.rb
40
61
  test/types.proto
41
62
  test/types.rb
data/bin/rprotoc CHANGED
@@ -1,13 +1,15 @@
1
- #!/usr/local/bin/ruby
1
+ #!/usr/bin/ruby
2
2
  $: << "#{File.dirname(__FILE__)}/../lib"
3
3
  require 'optparse'
4
4
  require 'ruby_protobuf'
5
+ #require 'protobuf/compiler/compiler_old'
6
+ require 'protobuf/compiler/compiler'
5
7
 
6
8
 
7
9
  COMMAND_LINE = "#{$0} #{ARGV.join(' ')} PROTO_FILE"
8
10
  OPT = {}
9
11
  opts = OptionParser.new
10
- #opts.on('-p', '--proto_path <PATH>', 'Specify the directory in which to search for imports. The current directory is default.'){|v| OPT[:proto_path] = v}
12
+ opts.on('-p', '--proto_path <PATH>', 'Specify the directory in which to search for imports. The current directory is default.'){|v| OPT[:proto_path] = v}
11
13
  opts.on('-o', '--out <OUT_DIR>', 'Specify the directory in which Ruby source file is generated. The current directory is default.'){|v| OPT[:out] = v}
12
14
  opts.on_tail('-v', '--version', 'Show version.'){puts(opts.ver); exit}
13
15
  opts.on_tail('-h', '--help', 'Show this message.'){puts(opts.help); exit}
@@ -16,6 +18,4 @@ opts.on_tail('-h', '--help', 'Show this message.'){puts(opts.help); exit}
16
18
  opts.order! ARGV
17
19
  PROTO_FILE = ARGV.shift
18
20
 
19
- RubyProtobuf.new.start PROTO_FILE, OPT
20
-
21
-
21
+ Protobuf::Compiler.compile(PROTO_FILE, (OPT[:proto_path] or '.'), (OPT[:out] or '.'))
@@ -0,0 +1,24 @@
1
+ package tutorial;
2
+
3
+ message Person {
4
+ required string name = 1;
5
+ required int32 id = 2;
6
+ optional string email = 3;
7
+
8
+ enum PhoneType {
9
+ MOBILE = 0;
10
+ HOME = 1;
11
+ WORK = 2;
12
+ }
13
+
14
+ message PhoneNumber {
15
+ required string number = 1;
16
+ optional PhoneType type = 2 [default = HOME];
17
+ }
18
+
19
+ repeated PhoneNumber phone = 4;
20
+ }
21
+
22
+ message AddressBook {
23
+ repeated Person person = 1;
24
+ }
@@ -0,0 +1,30 @@
1
+ require 'protobuf/message/message'
2
+ require 'protobuf/message/enum'
3
+ require 'protobuf/message/service'
4
+ require 'protobuf/message/extend'
5
+
6
+ module Tutorial
7
+
8
+ class Person < ::Protobuf::Message
9
+ required :string, :name, 1
10
+ required :int32, :id, 2
11
+ optional :string, :email, 3
12
+
13
+ class PhoneType < ::Protobuf::Enum
14
+ MOBILE = 0
15
+ HOME = 1
16
+ WORK = 2
17
+ end
18
+
19
+ class PhoneNumber < ::Protobuf::Message
20
+ required :string, :number, 1
21
+ optional :PhoneType, :type, 2, {:default => :HOME}
22
+ end
23
+
24
+ repeated :PhoneNumber, :phone, 4
25
+ end
26
+
27
+ class AddressBook < ::Protobuf::Message
28
+ repeated :Person, :person, 1
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'addressbook'
4
+
5
+ def list_people(address_book)
6
+ address_book.person.each do |person|
7
+ puts "Person ID: #{person.id}"
8
+ puts " Name: #{person.name}"
9
+ puts " E-mail: #{person.email}" unless person.email.empty?
10
+ person.phone.each do |phone_number|
11
+ print(case phone_number.type
12
+ when Tutorial::Person::PhoneType::MOBILE
13
+ ' Mobile phone #: '
14
+ when Tutorial::Person::PhoneType::HOME
15
+ ' Home phone #: '
16
+ when Tutorial::Person::PhoneType::WORK
17
+ ' Work phone #: '
18
+ end)
19
+ puts phone_number.number
20
+ end
21
+ end
22
+ end
23
+
24
+ unless ARGV.size == 1
25
+ puts "Usage: #{$0} ADDRESS_BOOK_FILE"
26
+ exit
27
+ end
28
+
29
+ address_book = Tutorial::AddressBook.new
30
+ address_book.parse_from_file ARGV[0]
31
+
32
+ list_people address_book
@@ -0,0 +1,46 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'addressbook'
4
+
5
+ def prompt_for_address(person)
6
+ print 'Enter person ID number: '
7
+ person.id = STDIN.gets.strip.to_i
8
+ print 'Enter name: '
9
+ person.name = STDIN.gets.strip
10
+ print 'Enter email address (blank for none): '
11
+ email = STDIN.gets.strip
12
+ person.email = email unless email.empty?
13
+
14
+ loop do
15
+ print 'Enter a phone number (or leave blank to finish): '
16
+ break if (number = STDIN.gets.strip).empty?
17
+
18
+ person.phone << Tutorial::Person::PhoneNumber.new
19
+ person.phone.last.number = number
20
+
21
+ print 'Is this a mobile, home, or work phone? '
22
+ person.phone.last.type =
23
+ case type = STDIN.gets.strip
24
+ when 'mobile'
25
+ Tutorial::Person::PhoneType::MOBILE
26
+ when 'home'
27
+ Tutorial::Person::PhoneType::HOME
28
+ when 'work'
29
+ Tutorial::Person::PhoneType::WORK
30
+ else
31
+ puts 'Unknown phone type; leaving as default value.'
32
+ nil
33
+ end
34
+ end
35
+ end
36
+
37
+ unless ARGV.size == 1
38
+ puts "Usage: #{$0} ADDRESS_BOOK_FILE"
39
+ exit
40
+ end
41
+
42
+ address_book = Tutorial::AddressBook.new
43
+ address_book.parse_from_file ARGV[0] if File.exist? ARGV[0]
44
+ address_book.person << Tutorial::Person.new
45
+ prompt_for_address address_book.person.last
46
+ address_book.serialize_to_file ARGV[0]
@@ -1,90 +1,54 @@
1
- # This is a quite temporary implementation.
2
- # I'll create a compiler class using Racc.
1
+ require 'fileutils'
2
+ require 'protobuf/compiler/proto_parser'
3
+ require 'protobuf/compiler/nodes'
4
+ require 'protobuf/compiler/visitors'
3
5
 
4
6
  module Protobuf
5
7
  class Compiler
6
- INDENT_UNIT = ' '
8
+ def self.compile(proto_file, proto_dir='.', out_dir='.', file_create=true)
9
+ self.new.compile proto_file, proto_dir, out_dir, file_create
10
+ end
7
11
 
8
- def self.compile(filename)
9
- self.new.compile filename
12
+ def compile(proto_file, proto_dir='.', out_dir='.', file_create=true)
13
+ create_message proto_file, proto_dir, out_dir, file_create
14
+ create_rpc proto_file, proto_dir, out_dir, file_create
10
15
  end
11
16
 
12
- def initialize
13
- @indent_level = 0
14
- @ret = <<-eos
15
- require 'protobuf/message/message'
16
- require 'protobuf/message/enum'
17
- require 'protobuf/message/service'
18
- require 'protobuf/message/extend'
17
+ def create_message(proto_file, proto_dir='.', out_dir='.', file_create=true)
18
+ rb_file = "#{out_dir}/#{proto_file.sub(/\.proto$/, '.rb')}"
19
+ proto_path = validate_existence proto_file, proto_dir
19
20
 
20
- eos
21
+ message_visitor = Protobuf::Visitor::CreateMessageVisitor.new proto_dir, out_dir
22
+ File.open proto_path, 'r' do |file|
23
+ message_visitor.visit Protobuf::ProtoParser.new.parse(file)
24
+ end
25
+ if file_create
26
+ puts "#{rb_file} writing..."
27
+ FileUtils.mkpath File.dirname(rb_file)
28
+ File.open(rb_file, 'w') {|f| f.write message_visitor.to_s}
29
+ else
30
+ message_visitor.to_s
31
+ end
21
32
  end
22
33
 
23
- def indent
24
- INDENT_UNIT * @indent_level
25
- end
34
+ def create_rpc(proto_file, proto_dir='.', out_dir='.', file_create=true)
35
+ rb_file = "#{out_dir}/#{proto_file.sub(/\.proto$/, '.rb')}"
36
+ proto_path = validate_existence proto_file, proto_dir
26
37
 
27
- def puts_with_indent(string)
28
- #puts "#{indent}#{string}"
29
- @ret += "#{indent}#{string}\n"
38
+ rpc_visitor = Protobuf::Visitor::CreateRpcVisitor.new# proto_dir, out_dir
39
+ File.open proto_path, 'r' do |file|
40
+ rpc_visitor.visit Protobuf::ProtoParser.new.parse(file)
41
+ end
42
+ rpc_visitor.create_files rb_file, out_dir, file_create
30
43
  end
31
- alias putswi puts_with_indent
32
44
 
33
- def compile(filename)
34
- File.open filename, 'r' do |file|
35
- file.each_line do |line|
36
- line.sub!(/^(.*)\/\/.*/, '\1')
37
- line.strip!
38
- case line
39
- when /^package\s+(\w+(\.\w+)?)\s*;$/
40
- $1.split('.').each do |path|
41
- putswi "module #{path.capitalize}"
42
- @indent_level += 1
43
- end
44
- when /^message\s+(\w+)\s*\{$/
45
- putswi "class #{$1} < ::Protobuf::Message"
46
- @indent_level += 1
47
- when /^(required|optional|repeated)\s+(\w+(\.\w+)?)\s+(\w+)\s*=\s*(\d+)\s*(\[\s*default\s*=\s*(\w+)\s*\])?\s*;$/
48
- rule, type, name, tag, default = $1, $2, $4, $5, $7
49
- if default
50
- default = default =~ /\d+(\.\d+)/ \
51
- ? ", {:default => #{default}}" \
52
- : ", {:default => :#{default}}"
53
- end
54
- putswi "#{rule} :#{type}, :#{name}, #{tag}#{default}"
55
- when /^enum\s+(\w+)\s*\{$/
56
- putswi "class #{$1} < ::Protobuf::Enum"
57
- @indent_level += 1
58
- when /^(\w+)\s*=\s*(\w+)\s*;$/
59
- putswi "#{$1} = #{$2}"
60
- when /^extensions\s+(\w+)\s+to\s+(\w+)\s*;/
61
- low, high = $1, $2
62
- low = '::Protobuf::Extend.MIN' if low == 'min'
63
- high = '::Protobuf::Extend.MAX' if high == 'max'
64
- putswi "extensions #{min}..#{max}"
65
- when /^extend\s+(\w+)\s*\{/
66
- putswi "class #{$1} < ::Protobuf::Extend"
67
- @indent_level += 1
68
- when /^service\s+(\w+)\s*\{/
69
- putswi "class #{$1} < ::Protobuf::Service"
70
- @indent_level += 1
71
- when /^rpc\s+(\w+)\s+\(\s*(\w+)\s*\)\s+returns\s+\(\s*(\w+)\s*\)\s*;/
72
- putswi "rpc :#{$1} => :#{$2}, :#{$3} => :#{$4}"
73
- when /^option\s+(\w+)\s*=\s*(.+)\s*;/
74
- putswi "::Protobuf::OPTIONS[:#{$1}] = :#{$2}"
75
- when /^\}\s*;?$/
76
- @indent_level -= 1
77
- putswi "end"
78
- when ''
79
- putswi ''
80
- end
81
- end
82
- while 0 < @indent_level
83
- @indent_level -= 1
84
- putswi "end"
85
- end
45
+ def validate_existence(path, base_dir)
46
+ if File.exist? path
47
+ elsif File.exist?(path = "#{base_dir or '.'}/#{path}")
48
+ else
49
+ raise ArgumentError.new("File does not exist: #{path}")
86
50
  end
87
- @ret
51
+ path
88
52
  end
89
53
  end
90
54
  end
@@ -0,0 +1,123 @@
1
+ # This is a quite temporary implementation.
2
+ # I'll create a compiler class using Racc.
3
+
4
+ require 'fileutils'
5
+
6
+ module Protobuf
7
+ class Compiler
8
+ INDENT_UNIT = ' '
9
+
10
+ def self.compile(proto_file, proto_dir='.', out_dir='.', file_create=true)
11
+ self.new.compile proto_file, proto_dir, out_dir, file_create
12
+ end
13
+
14
+ def initialize
15
+ @indent_level = 0
16
+ @ret = <<-eos
17
+ require 'protobuf/message/message'
18
+ require 'protobuf/message/enum'
19
+ require 'protobuf/message/service'
20
+ require 'protobuf/message/extend'
21
+
22
+ eos
23
+ end
24
+
25
+ def indent
26
+ INDENT_UNIT * @indent_level
27
+ end
28
+
29
+ def puts_with_indent(string)
30
+ #puts "#{indent}#{string}"
31
+ @ret += "#{indent}#{string}\n"
32
+ end
33
+ alias putswi puts_with_indent
34
+
35
+ def compile(proto_file, proto_dir='.', out_dir='.', file_create=true)
36
+ rb_file = "#{out_dir}/#{proto_file.sub(/\.proto$/, '.rb')}"
37
+ proto_path = validate_existence proto_file, proto_dir
38
+ File.open proto_path, 'r' do |file|
39
+ file.each_line do |line|
40
+ line.sub!(/^(.*)\/\/.*/, '\1')
41
+ line.strip!
42
+ case line
43
+ when /^package\s+(\w+(\.\w+)?)\s*;$/
44
+ $1.split('.').each do |path|
45
+ putswi "module #{path.capitalize}"
46
+ @indent_level += 1
47
+ end
48
+ when /^import\s+"((?:[^"\\]+|\\.)*)"\s*;$/
49
+ putswi "require '#{required_message_from_proto $1, proto_dir, out_dir}'"
50
+ when /^message\s+(\w+)\s*\{$/
51
+ putswi "class #{$1} < ::Protobuf::Message"
52
+ @extension = false
53
+ @indent_level += 1
54
+ when /^(required|optional|repeated)\s+(\w+(\.\w+)?)\s+(\w+)\s*=\s*(\d+)\s*(\[\s*default\s*=\s*(\w+)\s*\])?\s*;$/
55
+ rule, type, name, tag, default = $1, $2, $4, $5, $7
56
+ if default
57
+ default = default =~ /\d+(\.\d+)/ \
58
+ ? ", {:default => #{default}}" \
59
+ : ", {:default => :#{default}}"
60
+ end
61
+ extension = @extension ? ', :extension => true' : ''
62
+ putswi "#{rule} :#{type}, :#{name}, #{tag}#{default}#{extension}"
63
+ when /^enum\s+(\w+)\s*\{$/
64
+ putswi "class #{$1} < ::Protobuf::Enum"
65
+ @indent_level += 1
66
+ when /^(\w+)\s*=\s*(\w+)\s*;$/
67
+ putswi "#{$1} = #{$2}"
68
+ when /^extensions\s+(\w+)\s+to\s+(\w+)\s*;/
69
+ low, high = $1, $2
70
+ low = '::Protobuf::Extend.MIN' if low == 'min'
71
+ high = '::Protobuf::Extend.MAX' if high == 'max'
72
+ putswi "extensions #{low}..#{high}"
73
+ when /^extend\s+(\w+)\s*\{/
74
+ putswi "class #{$1} < ::Protobuf::Message"
75
+ @extension = true
76
+ @indent_level += 1
77
+ when /^service\s+(\w+)\s*\{/
78
+ putswi "class #{$1} < ::Protobuf::Service"
79
+ @indent_level += 1
80
+ when /^rpc\s+(\w+)\s+\(\s*(\w+)\s*\)\s+returns\s+\(\s*(\w+)\s*\)\s*;/
81
+ putswi "rpc :#{$1} => :#{$2}, :#{$3} => :#{$4}"
82
+ when /^option\s+(\w+)\s*=\s*(.+)\s*;/
83
+ putswi "::Protobuf::OPTIONS[:#{$1}] = :#{$2}"
84
+ when /^\}\s*;?$/
85
+ @indent_level -= 1
86
+ putswi "end"
87
+ when ''
88
+ putswi ''
89
+ end
90
+ end
91
+ while 0 < @indent_level
92
+ @indent_level -= 1
93
+ putswi "end"
94
+ end
95
+ end
96
+ if file_create
97
+ puts "#{rb_file} writing..."
98
+ FileUtils.mkpath File.dirname(rb_file)
99
+ File.open(rb_file, 'w') {|f| f.write @ret}
100
+ end
101
+ @ret
102
+ end
103
+
104
+ def validate_existence(path, base_dir)
105
+ if File.exist? path
106
+ elsif File.exist?(path = "#{base_dir or '.'}/#{path}")
107
+ else
108
+ raise ArgumentError.new("File does not exist: #{path}")
109
+ end
110
+ path
111
+ end
112
+
113
+ def required_message_from_proto(proto_file, proto_dir, out_dir)
114
+ rb_path = proto_file.sub(/\.proto$/, '.rb')
115
+ proto_dir ||= '.'
116
+ out_dir ||= '.'
117
+ unless File.exist?("#{out_dir}/#{rb_path}")
118
+ Compiler.compile proto_file, proto_dir, out_dir
119
+ end
120
+ rb_path
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,208 @@
1
+ module Protobuf
2
+ module Node
3
+ class Base
4
+ def accept_rpc_creator(vistor)
5
+ end
6
+ end
7
+
8
+ class ProtoNode < Base
9
+ attr_reader :children
10
+
11
+ def initialize(children)
12
+ @children = children
13
+ end
14
+
15
+ def accept_message_creator(visitor)
16
+ visitor.write <<-eos
17
+ require 'protobuf/message/message'
18
+ require 'protobuf/message/enum'
19
+ require 'protobuf/message/service'
20
+ require 'protobuf/message/extend'
21
+ eos
22
+ @children.map{|child| child.accept_message_creator visitor}
23
+ visitor.close_ruby
24
+ end
25
+
26
+ def accept_rpc_creator(visitor)
27
+ @children.map{|child| child.accept_rpc_creator visitor}
28
+ end
29
+ end
30
+
31
+ class ImportNode < Base
32
+ def initialize(path)
33
+ @path = path
34
+ end
35
+
36
+ def accept_message_creator(visitor)
37
+ visitor.write "require '#{visitor.required_message_from_proto @path}'"
38
+ end
39
+ end
40
+
41
+ class PackageNode < Base
42
+ def initialize(path_list)
43
+ @path_list = path_list
44
+ end
45
+
46
+ def accept_message_creator(visitor)
47
+ @path_list.each do |path|
48
+ visitor.write "module #{path.to_s.capitalize}"
49
+ visitor.increment
50
+ end
51
+ end
52
+
53
+ def accept_rpc_creator(visitor)
54
+ visitor.package = @path_list.dup
55
+ end
56
+ end
57
+
58
+ class OptionNode < Base
59
+ def initialize(name_list, value)
60
+ @name_list, @value = name_list, value
61
+ end
62
+
63
+ def accept_message_creator(visitor)
64
+ visitor.write "::Protobuf::OPTIONS[:#{@name_list.join('.').inspect}] = #{@value.inspect}"
65
+ end
66
+ end
67
+
68
+ class MessageNode < Base
69
+ def initialize(name, children)
70
+ @name, @children = name, children
71
+ end
72
+
73
+ def accept_message_creator(visitor)
74
+ visitor.write "class #{@name} < ::Protobuf::Message"
75
+ visitor.in_context self.class do
76
+ @children.each {|child| child.accept_message_creator visitor}
77
+ end
78
+ visitor.write "end"
79
+ end
80
+ end
81
+
82
+ class ExtendNode < Base
83
+ def initialize(name, children)
84
+ @name, @children = name, children
85
+ end
86
+
87
+ def accept_message_creator(visitor)
88
+ visitor.write "class #{@name} < ::Protobuf::Message"
89
+ visitor.in_context self.class do
90
+ @children.each {|child| child.accept_message_creator visitor}
91
+ end
92
+ visitor.write "end"
93
+ end
94
+ end
95
+
96
+ class EnumNode < Base
97
+ def initialize(name, children)
98
+ @name, @children = name, children
99
+ end
100
+
101
+ def accept_message_creator(visitor)
102
+ visitor.write "class #{@name} < ::Protobuf::Enum"
103
+ visitor.in_context self.class do
104
+ @children.each {|child| child.accept_message_creator visitor}
105
+ end
106
+ visitor.write "end"
107
+ end
108
+ end
109
+
110
+ class EnumFieldNode < Base
111
+ def initialize(name, value)
112
+ @name, @value = name, value
113
+ end
114
+
115
+ def accept_message_creator(visitor)
116
+ visitor.write "#{@name} = #{@value}"
117
+ end
118
+ end
119
+
120
+ class ServiceNode < Base
121
+ def initialize(name, children)
122
+ @name, @children = name, children
123
+ end
124
+
125
+ def accept_message_creator(visitor)
126
+ # do nothing
127
+ #visitor.write "class #{@name} < ::Protobuf::Service"
128
+ #visitor.in_context self.class do
129
+ # @children.each {|child| child.accept_message_creator visitor}
130
+ #end
131
+ #visitor.write "end"
132
+ end
133
+
134
+ def accept_rpc_creator(visitor)
135
+ visitor.current_service = @name
136
+ @children.each {|child| child.accept_rpc_creator visitor}
137
+ end
138
+ end
139
+
140
+ class RpcNode < Base
141
+ def initialize(name, request, response)
142
+ @name, @request, @response = name, request, response
143
+ end
144
+
145
+ def accept_message_creator(visitor)
146
+ # do nothing
147
+ #visitor.write "rpc :#{@name}, :request => :#{@request}, :response => :#{@response}"
148
+ end
149
+
150
+ def accept_rpc_creator(visitor)
151
+ visitor.add_rpc @name, @request, @response
152
+ end
153
+ end
154
+
155
+ class GroupNode < Base
156
+ def initialize(label, name, value, children)
157
+ @label, @name, @value, @children = label, name, value, children
158
+ end
159
+
160
+ def accept_message_creator(visitor)
161
+ raise ArgumentError.new('have not implement')
162
+ end
163
+ end
164
+
165
+ class FieldNode < Base
166
+ def initialize(label, type, name, value, opts=[])
167
+ @label, @type, @name, @value, @opts = label, type, name, value, opts
168
+ end
169
+
170
+ def accept_message_creator(visitor)
171
+ opts = @opts.empty? ? '' : ", #{@opts.map{|k, v| ":#{k} => :#{v}"}.join(', ')}"
172
+ if visitor.context.first == Protobuf::Node::ExtendNode
173
+ opts += ', :extension => true'
174
+ end
175
+ visitor.write "#{@label} :#{@type}, :#{@name}, #{@value}#{opts}"
176
+ end
177
+ end
178
+
179
+ class ExtensionsNode < Base
180
+ def initialize(range)
181
+ @range = range
182
+ end
183
+
184
+ def accept_message_creator(visitor)
185
+ visitor.write "extensions #{@range.to_s}"
186
+ end
187
+ end
188
+
189
+ class ExtensionRangeNode < Base
190
+ def initialize(low, high=nil)
191
+ @low, @high = low, high
192
+ end
193
+
194
+ #def accept_message_creator(visitor)
195
+ #end
196
+
197
+ def to_s
198
+ if @high.nil?
199
+ @low.to_s
200
+ elsif @high == :max
201
+ "#{@low}..Protobuf::Extend::MAX"
202
+ else
203
+ "#{@low}..#{@high}"
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end