msgpack-idl 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ FURUHASHI Sadayuki <frsyuki _at_ users.sourceforge.jp>
data/ChangeLog ADDED
@@ -0,0 +1,5 @@
1
+
2
+ 2011-04-23 version 0.1.0
3
+
4
+ * Initial release
5
+
data/README ADDED
@@ -0,0 +1,22 @@
1
+
2
+ = MessagePack IDL
3
+
4
+ == Description
5
+
6
+ == Installation
7
+
8
+ === Archive Installation
9
+
10
+ rake
11
+ gem install pkg/msgpack-idl-*
12
+
13
+ === Gem Installation
14
+
15
+ gem install msgpack-idl
16
+
17
+ == Copyright
18
+
19
+ Author:: frsyuki <frsyuki@users.sourceforge.jp>
20
+ Copyright:: Copyright (c) 2011 FURUHASHI Sadayuki
21
+ License:: Apache License, Version 2.0
22
+
data/bin/msgpack-idl ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+ require 'msgpack/idl/command/idl'
@@ -0,0 +1,251 @@
1
+ #
2
+ # MessagePack IDL Processor
3
+ #
4
+ # Copyright (C) 2011 FURUHASHI Sadayuki
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ module MessagePack
19
+ module IDL
20
+
21
+
22
+ module AST
23
+ class Element
24
+ end
25
+
26
+ class Document < Array
27
+ end
28
+
29
+ class Include
30
+ def initialize(path)
31
+ @path = path
32
+ end
33
+ attr_reader :path
34
+ end
35
+
36
+
37
+ class Namespace < Element
38
+ def initialize(scopes, lang=nil)
39
+ @scopes = scopes
40
+ @lang = lang
41
+ end
42
+ attr_reader :scopes, :lang
43
+ end
44
+
45
+
46
+ class Message < Element
47
+ def initialize(name, super_class, fields)
48
+ @name = name
49
+ @super_class = super_class
50
+ @fields = fields
51
+ end
52
+ attr_reader :name, :super_class, :fields
53
+ end
54
+
55
+
56
+ class Exception < Message
57
+ end
58
+
59
+
60
+ class Field < Element
61
+ def initialize(id, type, modifier, name)
62
+ @id = id
63
+ @type = type
64
+ @name = name
65
+ @modifier = modifier
66
+ end
67
+ attr_reader :id, :type, :name, :modifier
68
+ end
69
+
70
+ class ValueAssignedField < Field
71
+ def initialize(id, type, modifier, name, value)
72
+ super(id, type, modifier, name)
73
+ @value = value
74
+ end
75
+ attr_reader :value
76
+ end
77
+
78
+
79
+ class Enum < Element
80
+ def initialize(name, fields)
81
+ @name = name
82
+ @fields = fields
83
+ end
84
+ attr_reader :name, :fields
85
+ end
86
+
87
+ class EnumField < Element
88
+ def initialize(id, name)
89
+ @id = id
90
+ @name = name
91
+ end
92
+ attr_reader :id, :name
93
+ end
94
+
95
+
96
+ class Service < Element
97
+ def initialize(name, version, funcs)
98
+ @name = name
99
+ @version = version
100
+ @funcs = funcs
101
+ end
102
+ attr_reader :name, :version, :funcs
103
+ end
104
+
105
+ class Func < Element
106
+ def initialize(name, return_type, args, exceptions)
107
+ @name = name
108
+ @return_type = return_type
109
+ @args = args
110
+ @exceptions = exceptions
111
+ end
112
+ attr_reader :name, :return_type, :args, :exceptions
113
+ end
114
+
115
+
116
+ class Application < Element
117
+ def initialize(name, scopes)
118
+ @name = name
119
+ @scopes = scopes
120
+ end
121
+
122
+ attr_reader :name
123
+ attr_reader :scopes
124
+ end
125
+
126
+ class Scope < Element
127
+ def initialize(service, version, name, default)
128
+ @service = service
129
+ @version = version
130
+ @name = name
131
+ @default = default
132
+ end
133
+ attr_reader :service, :version, :name, :default
134
+
135
+ def default?
136
+ @default
137
+ end
138
+ end
139
+
140
+
141
+ class Type < Element
142
+ def initialize(name, nullable=false)
143
+ @name = name
144
+ @nullable = nullable
145
+ end
146
+ attr_reader :name, :nullable
147
+
148
+ def nullable?
149
+ @nullable
150
+ end
151
+ end
152
+
153
+ class GenericType < Type
154
+ def initialize(name, type_params, nullable=false)
155
+ super(name, nullable)
156
+ @type_params = type_params
157
+ end
158
+ attr_reader :type_params
159
+ end
160
+
161
+ FIELD_OPTIONAL = :optional
162
+ FIELD_REQUIRED = :required
163
+
164
+
165
+ class Literal
166
+ end
167
+
168
+ class ConstLiteral < Literal
169
+ def initialize(name)
170
+ @name = name
171
+ end
172
+ attr_reader :name
173
+ end
174
+
175
+ class EnumLiteral < Literal
176
+ def initialize(name, field)
177
+ @name = name
178
+ @field = field
179
+ end
180
+ attr_reader :name, :field
181
+ end
182
+
183
+ class IntLiteral < Literal
184
+ def initialize(value)
185
+ @value = value
186
+ end
187
+ attr_reader :value
188
+ end
189
+
190
+ class FlaotLiteral < Literal
191
+ def initialize(value)
192
+ @value = value
193
+ end
194
+ attr_reader :value
195
+ end
196
+
197
+ class NilLiteral < Literal
198
+ end
199
+
200
+ class BoolLiteral < Literal
201
+ def initialize(value)
202
+ @value = value
203
+ end
204
+ attr_reader :value
205
+ end
206
+
207
+ class TrueLiteral < BoolLiteral
208
+ def initialize
209
+ super(true)
210
+ end
211
+ end
212
+
213
+ class FalseLiteral < BoolLiteral
214
+ def initialize
215
+ super(false)
216
+ end
217
+ end
218
+
219
+ class StringLiteral < Literal
220
+ def initialize(value)
221
+ @value = value
222
+ end
223
+ end
224
+
225
+ #class ListLiteral < Literal
226
+ # def initialize(array)
227
+ # @array = array
228
+ # end
229
+ #end
230
+
231
+ #class MapLiteralPair
232
+ # def initialize(k, v)
233
+ # @key = k
234
+ # @value = v
235
+ # end
236
+ #end
237
+
238
+ #class MapLiteral < Literal
239
+ # def initialize(pairs)
240
+ # @pairs = pairs
241
+ # end
242
+ #end
243
+
244
+
245
+ class Sequence < Array
246
+ end
247
+ end
248
+
249
+
250
+ end
251
+ end
@@ -0,0 +1,135 @@
1
+ #
2
+ # MessagePack IDL Processor
3
+ #
4
+ # Copyright (C) 2011 FURUHASHI Sadayuki
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ module Example
19
+ LIST = []
20
+
21
+ def self.list
22
+ LIST
23
+ end
24
+
25
+ def self.show(name)
26
+ n, summary, code = LIST.find {|n, summary, code|
27
+ name == n
28
+ }
29
+ unless code
30
+ raise "unknown example name: #{name}"
31
+ end
32
+ puts "# #{name} - #{summary} example"
33
+ puts code
34
+ nil
35
+ end
36
+
37
+ def self.add(name, summary, code)
38
+ LIST << [name, summary, code]
39
+ end
40
+
41
+ add 'syntax', 'basic syntax', <<EOF
42
+
43
+ # this is a comment
44
+ // this is a comment
45
+
46
+ /*
47
+ this is also a comment
48
+ */
49
+
50
+ # namespace declaration
51
+ # java: this becomes the package name
52
+ namespace com.example
53
+
54
+ # message type declaration
55
+ message MessageName {
56
+ # <id>: ["optional"] <type> <name> [= <initial value>]
57
+ 1: map<string,string> property
58
+ 2: optional string name
59
+ }
60
+
61
+ # include other files
62
+ include sample.msgspec
63
+ EOF
64
+
65
+ add 'types', 'basic types', <<EOF
66
+ namespace com.example
67
+
68
+ message BasicTypeExample {
69
+ 1: byte f1 # signed 8-bit integer
70
+ 2: short f2 # signed 16-bit integer
71
+ 3: int f3 # signed 32-bit integer
72
+ 4: long f4 # signed 64-bit integer
73
+ 5: ubyte f5 # unsigned 8-bit integer
74
+ 6: ushort f6 # unsigned 16-bit integer
75
+ 7: uint f7 # unsigned 32-bit integer
76
+ 8: ulong f8 # unsigned 64-bit integer
77
+ 9: float f9 # single precision float
78
+ 10: double f10 # double precision float
79
+ 11: bool f11 # boolean
80
+ 12: raw f12 # raw bytes
81
+ 13: string f13 # string
82
+ }
83
+
84
+ message ContainerTypeExample {
85
+ 1: list<string> f1 # list
86
+ 2: map<string,int> f2 # map
87
+ 2: map<string, list<string>> f2 # nesting is ok
88
+ }
89
+ EOF
90
+
91
+ add 'optional', 'optional fields', <<EOF
92
+ namespace com.example
93
+
94
+ message OptionalExample {
95
+ 1: int f1 # required field
96
+ 2: required int f1 # required field
97
+ 3: optional int f2 # optional field
98
+
99
+ 4: int? f1 # required nullable field
100
+ 5: required int? f1 # required nullable field
101
+ 6: optional int? f2 # optional nullable field
102
+ }
103
+ EOF
104
+
105
+ add 'enum', 'enum definition', <<EOF
106
+ enum EnumExcample {
107
+ 0: RED
108
+ 1: GREEN
109
+ 2: BLUE
110
+ }
111
+ EOF
112
+
113
+ add 'sample', 'simple sample', <<EOF
114
+ namespace com.example
115
+
116
+ message UserInfo {
117
+ 1: int uid
118
+ 2: string name
119
+ 3: optional int flags = 1
120
+ }
121
+
122
+ enum Sites {
123
+ 0: SiteA
124
+ 1: SiteB
125
+ 2: SiteC
126
+ }
127
+
128
+ message LogInLog {
129
+ 1: UserInfo user
130
+ 2: Sites site
131
+ }
132
+ EOF
133
+
134
+ end
135
+
@@ -0,0 +1,262 @@
1
+ #
2
+ # MessagePack IDL Processor
3
+ #
4
+ # Copyright (C) 2011 FURUHASHI Sadayuki
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ require 'optparse'
19
+
20
+ op = OptionParser.new
21
+
22
+ prog = File.basename($0)
23
+ op.banner = <<EOF
24
+ Usage: #{prog} [options] -g LANG files...
25
+ #{prog} --list
26
+ #{prog} --example [NAME]
27
+ #{prog} --update LANG [or 'self']
28
+
29
+ options:
30
+ EOF
31
+
32
+ comment = <<EOF
33
+ examples:
34
+ - generate java code from test.msgspec file:
35
+ $ #{prog} -g java test.msgspec
36
+ $ ls gen-java # generated codes are here
37
+
38
+ - generate java code from test.msgspec file to ./out directory:
39
+ $ #{prog} -g java -o out test.msgspec
40
+
41
+ - install or update language module
42
+ $ msgpack-idl --update java
43
+
44
+ - show examples
45
+ $ msgpack-idl --example # show list of examples
46
+ $ msgpack-idl --example "types"
47
+
48
+ - generate sample code
49
+ $ msgpack-idl --update java
50
+ $ msgpack-idl --example sample > sample.msgspec
51
+ $ msgpack-idl -g java sample.msgspec
52
+ EOF
53
+
54
+ (class<<self;self;end).module_eval do
55
+ define_method(:usage) do |msg|
56
+ puts op.to_s
57
+ puts ""
58
+ puts comment
59
+ puts ""
60
+ puts "error: #{msg}" if msg
61
+ exit 1
62
+ end
63
+ end
64
+
65
+ cmd = :generate
66
+ conf = {
67
+ :lang => nil,
68
+ :out => nil,
69
+ :show_ast => nil,
70
+ :show_ir => nil,
71
+ }
72
+
73
+ op.on('--example', 'show IDL examples') {
74
+ cmd = :example
75
+ }
76
+
77
+ op.on('--install', 'install or update a language module') {
78
+ cmd = :update
79
+ }
80
+
81
+ op.on('--update', 'install or update a language module') {
82
+ cmd = :update
83
+ }
84
+
85
+ op.on('--list', 'show list of available language modules') {
86
+ cmd = :list
87
+ }
88
+
89
+ op.on_tail('--help', 'show this message') {
90
+ usage nil
91
+ }
92
+
93
+ op.on_tail('--version', 'show version') {
94
+ require 'msgpack/idl/version'
95
+ puts MessagePack::IDL::VERSION
96
+ exit 0
97
+ }
98
+
99
+ op.on('-g', '--lang LANG', 'output language') {|s|
100
+ conf[:lang] = s
101
+ }
102
+
103
+ op.on('-o', '--output DIR', 'output directory (default: ./gen-LANG)') {|s|
104
+ conf[:out] = s
105
+ }
106
+
107
+ op.on('--show-ast', 'show AST for debugging') {
108
+ conf[:show_ast] = true
109
+ }
110
+
111
+ op.on('--show-ir', 'show IR for debugging') {
112
+ conf[:show_ir] = true
113
+ }
114
+
115
+ begin
116
+ op.parse!(ARGV)
117
+ rescue
118
+ usage $!.to_s
119
+ end
120
+
121
+ case cmd
122
+ when :example
123
+ require 'msgpack/idl/command/example'
124
+
125
+ def show_available_examples
126
+ puts "available examples:"
127
+ Example.list.each {|name,summary,code|
128
+ puts " #{name}#{" "*(10-name.length)}: #{summary}"
129
+ }
130
+ end
131
+
132
+ if ARGV.length == 0
133
+ show_available_examples
134
+ exit 1
135
+ elsif ARGV.length > 1
136
+ usage "unknown option: #{ARGV[1]}"
137
+ exit 1
138
+ end
139
+
140
+ name = ARGV[0]
141
+ begin
142
+ Example.show(name)
143
+ rescue
144
+ show_available_examples
145
+ puts ""
146
+ puts "error: unknown example name: #{name.dump}"
147
+ exit 1
148
+ end
149
+
150
+ when :update
151
+ require 'rubygems'
152
+ require 'rubygems/gem_runner'
153
+ require 'rubygems/exceptions'
154
+
155
+ if ARGV.length == 0
156
+ usage "language name or 'self' is required."
157
+ exit 1
158
+ elsif ARGV.length > 1
159
+ usage "unknown option: #{ARGV[1]}"
160
+ exit 1
161
+ end
162
+
163
+ name = ARGV[0]
164
+ if name == 'self'
165
+ pkg = "msgpack-idl"
166
+ else
167
+ pkg = "msgpack-idl-#{name}"
168
+ end
169
+
170
+ args = ["install", pkg]
171
+ puts "installing #{pkg}..."
172
+
173
+ begin
174
+ Gem::GemRunner.new.run args
175
+ rescue Gem::SystemExitException => e
176
+ exit e.exit_code
177
+ end
178
+
179
+ when :list
180
+ list = []
181
+ dirs = Gem.all_load_paths.grep("msgpack-idl")
182
+ dirs.each {|dir|
183
+ path = File.join(dir, "msgpack/idl/lang")
184
+ if File.directory?(path)
185
+ list.concat Dir.entries(path)
186
+ end
187
+ }
188
+
189
+ puts "available language modules:"
190
+ list.each {|lang|
191
+ puts " #{lang}"
192
+ }
193
+
194
+ when :generate
195
+ if ARGV.length == 0
196
+ usage nil
197
+ end
198
+ unless conf[:lang]
199
+ usage "-g option is required."
200
+ end
201
+
202
+ lang = conf[:lang]
203
+ out = conf[:out] || "gen-#{lang}"
204
+ files = ARGV
205
+
206
+ require 'parslet'
207
+ require 'msgpack/idl/version'
208
+ require 'msgpack/idl/module'
209
+ require 'msgpack/idl/error'
210
+ require 'msgpack/idl/ast'
211
+ require 'msgpack/idl/ir'
212
+ require 'msgpack/idl/parser/rule'
213
+ require 'msgpack/idl/parser/transform'
214
+ require 'msgpack/idl/parser'
215
+ require 'msgpack/idl/evaluator'
216
+ require 'msgpack/idl/generator'
217
+
218
+ begin
219
+ require "msgpack/idl/lang/#{lang}"
220
+ available = true
221
+ rescue LoadError
222
+ available = false
223
+ end
224
+ if !available || !MessagePack::IDL::Generator.available?(lang)
225
+ puts "Language module #{lang.dump} is not available."
226
+ puts "Try to install it as follows:"
227
+ puts " $ #{prog} --install #{lang}"
228
+ exit 1
229
+ end
230
+
231
+ parser = MessagePack::IDL::Parser.new
232
+ files.each {|path|
233
+ if path == "-"
234
+ text = STDIN.read
235
+ parser.parse(text, '(stdin)', '.')
236
+ else
237
+ parser.parse_file(path)
238
+ end
239
+ }
240
+ ast = parser.ast
241
+
242
+ if conf[:show_ast]
243
+ require 'pp'
244
+ $stderr.puts "AST:"
245
+ $stderr.puts ast.pretty_inspect
246
+ end
247
+
248
+ ev = MessagePack::IDL::Evaluator.new
249
+ ev.evaluate(ast)
250
+ ev.evaluate_inheritance
251
+ ir = ev.evaluate_spec(lang)
252
+
253
+ if conf[:show_ir]
254
+ require 'pp'
255
+ $stderr.puts "IR:"
256
+ $stderr.puts ir.pretty_inspect
257
+ end
258
+
259
+ gen = MessagePack::IDL::Generator.new
260
+ gen.generate(lang, ir, out)
261
+ end
262
+