msgpack-idl 0.1.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/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
+