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.
- data/History.txt +6 -1
- data/Manifest.txt +23 -2
- data/bin/rprotoc +5 -5
- data/examples/addressbook.proto +24 -0
- data/examples/addressbook.rb +30 -0
- data/examples/reading_a_message.rb +32 -0
- data/examples/writing_a_message.rb +46 -0
- data/lib/protobuf/compiler/compiler.rb +38 -74
- data/lib/protobuf/compiler/compiler_old.rb +123 -0
- data/lib/protobuf/compiler/nodes.rb +208 -0
- data/lib/protobuf/compiler/proto.y +198 -0
- data/lib/protobuf/compiler/proto2.ebnf +79 -0
- data/lib/protobuf/compiler/proto_parser.rb +1259 -0
- data/lib/protobuf/compiler/template/rpc_bin.erb +4 -0
- data/lib/protobuf/compiler/template/rpc_client.erb +18 -0
- data/lib/protobuf/compiler/template/rpc_service.erb +25 -0
- data/lib/protobuf/compiler/visitors.rb +132 -0
- data/lib/protobuf/message/decoder.rb +8 -3
- data/lib/protobuf/message/enum.rb +4 -0
- data/lib/protobuf/message/field.rb +31 -5
- data/lib/protobuf/message/message.rb +130 -14
- data/lib/protobuf/rpc/client.rb +19 -0
- data/lib/protobuf/rpc/handler.rb +17 -0
- data/lib/protobuf/rpc/server.rb +39 -0
- data/lib/ruby_protobuf.rb +1 -20
- data/test/addressbook.proto +6 -0
- data/test/addressbook.rb +17 -14
- data/test/addressbook_base.proto +26 -0
- data/test/addressbook_base.rb +62 -0
- data/test/addressbook_ext.proto +6 -0
- data/test/addressbook_ext.rb +12 -0
- data/test/rpc.proto +6 -0
- data/test/test_addressbook.rb +3 -2
- data/test/test_compiler.rb +98 -3
- data/test/test_extension.rb +40 -0
- data/test/test_standard_message.rb +83 -0
- data/test/test_types.rb +3 -3
- metadata +31 -8
- data/lib/protobuf/compiler/parser.y +0 -138
- data/test/data/data2.bin +0 -3
data/History.txt
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
-
=== 0.
|
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/
|
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/
|
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
|
-
|
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
|
-
|
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
|
-
|
2
|
-
|
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
|
-
|
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
|
9
|
-
|
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
|
13
|
-
|
14
|
-
|
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
|
-
|
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
|
24
|
-
|
25
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
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
|
34
|
-
File.
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
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
|