ruby_protobuf 0.2.0 → 0.3.0

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 (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