stark 0.7.0 → 0.8.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/.travis.yml +10 -0
- data/History.txt +19 -0
- data/Manifest.txt +17 -3
- data/README.md +164 -0
- data/Rakefile +4 -1
- data/bin/stark +11 -3
- data/examples/README.md +114 -0
- data/examples/client.rb +13 -0
- data/examples/health.thrift +9 -0
- data/examples/server.rb +18 -0
- data/lib/stark.rb +16 -2
- data/lib/stark/ast.rb +5 -0
- data/lib/stark/client.rb +3 -67
- data/lib/stark/exception.rb +9 -9
- data/lib/stark/processor.rb +13 -52
- data/lib/stark/protocol_helpers.rb +161 -0
- data/lib/stark/raw_parser.rb +75 -14
- data/lib/stark/ruby.rb +267 -248
- data/lib/stark/struct.rb +37 -26
- data/lib/stark/thrift.kpeg +6 -4
- data/stark.gemspec +15 -15
- data/test/ThriftSpec.thrift +4 -0
- data/test/comments.thrift +15 -0
- data/test/leg.rb +0 -2
- data/test/parsing_error.thrift +5 -0
- data/test/properties.thrift +9 -0
- data/test/test_client.rb +116 -241
- data/test/test_coerce_strings.rb +187 -0
- data/test/test_helper.rb +113 -0
- data/test/test_marshal.rb +131 -0
- data/test/test_parser.rb +61 -0
- data/test/test_ruby.rb +148 -9
- data/test/test_server.rb +96 -212
- data/test/test_stark.rb +67 -0
- data/test/types.thrift +49 -0
- data/test/users.thrift +16 -0
- metadata +33 -15
- data/README.txt +0 -67
- data/lib/stark/converters.rb +0 -188
- data/lib/stark/field.rb +0 -27
data/lib/stark/ruby.rb
CHANGED
|
@@ -12,12 +12,10 @@ module Stark
|
|
|
12
12
|
|
|
13
13
|
@stream = stream
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
o "require 'set'"
|
|
16
16
|
o "require 'stark/client'"
|
|
17
|
-
o "require 'stark/struct'"
|
|
18
|
-
o "require 'stark/field'"
|
|
19
|
-
o "require 'stark/converters'"
|
|
20
17
|
o "require 'stark/processor'"
|
|
18
|
+
o "require 'stark/struct'"
|
|
21
19
|
o "require 'stark/exception'"
|
|
22
20
|
end
|
|
23
21
|
|
|
@@ -27,6 +25,7 @@ module Stark
|
|
|
27
25
|
end
|
|
28
26
|
|
|
29
27
|
def close
|
|
28
|
+
write_protocol
|
|
30
29
|
if @namespace
|
|
31
30
|
outdent
|
|
32
31
|
o "end"
|
|
@@ -34,109 +33,74 @@ module Stark
|
|
|
34
33
|
end
|
|
35
34
|
|
|
36
35
|
def process_namespace(ns)
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
return unless [nil, 'rb'].include?(ns.lang)
|
|
37
|
+
@namespace = ns.namespace.gsub('.', '::')
|
|
38
|
+
parts = @namespace.split('::')
|
|
39
|
+
if parts.length > 1
|
|
40
|
+
0.upto(parts.length - 2) do |i|
|
|
41
|
+
o "module #{parts[0..i].join('::')}; end unless defined?(#{parts[0..i].join('::')})"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
o
|
|
45
|
+
o "module #{@namespace}"
|
|
39
46
|
indent
|
|
40
47
|
end
|
|
41
48
|
|
|
42
49
|
def process_include(inc)
|
|
50
|
+
raise NotImplementedError, "include not implemented"
|
|
43
51
|
end
|
|
44
52
|
|
|
45
53
|
def process_enum(enum)
|
|
54
|
+
@enums[enum.name] = enum
|
|
46
55
|
e = "Enum_#{enum.name}"
|
|
47
56
|
o "#{e} = Hash.new { |h,k| p [:bad, k]; h[k] = -1 }"
|
|
48
|
-
|
|
49
57
|
idx = 0
|
|
50
58
|
enum.values.each do |f|
|
|
51
59
|
o "#{e}[#{idx}] = :'#{f}'"
|
|
52
60
|
o "#{e}[:'#{f}'] = #{idx}"
|
|
53
61
|
idx += 1
|
|
54
62
|
end
|
|
55
|
-
|
|
56
|
-
@enums[enum.name] = enum
|
|
57
63
|
end
|
|
58
64
|
|
|
59
|
-
def
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
def write_field_declarations(fields)
|
|
66
|
+
max_field_len = fields.inject(0) {|max,f| f.name.length > max ? f.name.length : max }
|
|
67
|
+
max_index_len = fields.inject(0) {|max,f| f.index.to_s.length > max ? f.index.to_s.length : max }
|
|
68
|
+
|
|
69
|
+
current_index = 1
|
|
70
|
+
fields.each do |f|
|
|
71
|
+
if f.index != current_index
|
|
72
|
+
o "field_number #{f.index}"
|
|
73
|
+
current_index = f.index
|
|
74
|
+
end
|
|
75
|
+
current_index += 1
|
|
76
|
+
o("attr_accessor :%-*s # %*s: %s" % [max_field_len, f.name, max_index_len, f.index, object_type(f.type)])
|
|
70
77
|
end
|
|
71
78
|
end
|
|
72
79
|
|
|
73
80
|
def process_struct(str)
|
|
74
81
|
@structs[str.name] = str
|
|
75
82
|
|
|
83
|
+
o
|
|
76
84
|
o "class #{str.name} < Stark::Struct"
|
|
77
85
|
indent
|
|
78
|
-
|
|
79
|
-
indent
|
|
80
|
-
|
|
81
|
-
fields = str.fields.map do |f|
|
|
82
|
-
c = converter f.type
|
|
83
|
-
"#{f.index} => Stark::Field.new(#{f.index}, '#{f.name}', #{c})"
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
o " #{fields.join(', ')}"
|
|
87
|
-
|
|
88
|
-
outdent
|
|
89
|
-
o "}"
|
|
90
|
-
|
|
91
|
-
str.fields.each do |f|
|
|
92
|
-
o "def #{f.name}; @fields['#{f.name}']; end"
|
|
93
|
-
end
|
|
94
|
-
|
|
86
|
+
write_field_declarations str.fields
|
|
95
87
|
outdent
|
|
96
88
|
o "end"
|
|
97
|
-
|
|
98
89
|
end
|
|
99
90
|
|
|
100
|
-
BUILTINS = %w!bool byte i16 i32 i64 double string!
|
|
101
|
-
|
|
102
91
|
def process_exception(str)
|
|
103
92
|
@exceptions[str.name] = str
|
|
104
93
|
|
|
94
|
+
o
|
|
105
95
|
o "class #{str.name} < Stark::Exception"
|
|
106
96
|
indent
|
|
107
|
-
|
|
108
|
-
o "class Struct < Stark::Struct"
|
|
109
|
-
indent
|
|
110
|
-
o "Fields = {"
|
|
111
|
-
indent
|
|
112
|
-
|
|
113
|
-
fields = str.fields.map do |f|
|
|
114
|
-
c = converter f.type
|
|
115
|
-
"#{f.index} => Stark::Field.new(#{f.index}, '#{f.name}', #{c})"
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
o " #{fields.join(', ')}"
|
|
119
|
-
|
|
120
|
-
outdent
|
|
121
|
-
o "}"
|
|
122
|
-
|
|
123
|
-
str.fields.each do |f|
|
|
124
|
-
o "def #{f.name}; @fields['#{f.name}']; end"
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
outdent
|
|
128
|
-
o "end"
|
|
129
|
-
|
|
130
|
-
str.fields.each do |f|
|
|
131
|
-
o "def #{f.name}; @struct.#{f.name}; end"
|
|
132
|
-
end
|
|
133
|
-
|
|
97
|
+
write_field_declarations str.fields
|
|
134
98
|
outdent
|
|
135
99
|
o "end"
|
|
136
100
|
end
|
|
137
101
|
|
|
138
|
-
def o(str)
|
|
139
|
-
@stream.print(" " * @indent)
|
|
102
|
+
def o(str = nil)
|
|
103
|
+
@stream.print(" " * @indent) if str
|
|
140
104
|
@stream.puts str
|
|
141
105
|
end
|
|
142
106
|
|
|
@@ -156,6 +120,7 @@ module Stark
|
|
|
156
120
|
'i32' => "::Thrift::Types::I32",
|
|
157
121
|
'i64' => "::Thrift::Types::I64",
|
|
158
122
|
'string' => '::Thrift::Types::STRING',
|
|
123
|
+
'binary' => '::Thrift::Types::STRING',
|
|
159
124
|
'struct' => '::Thrift::Types::STRUCT',
|
|
160
125
|
'map' => '::Thrift::Types::MAP',
|
|
161
126
|
'set' => '::Thrift::Types::SET',
|
|
@@ -170,6 +135,7 @@ module Stark
|
|
|
170
135
|
'i32' => "read_i32",
|
|
171
136
|
'i64' => "read_i64",
|
|
172
137
|
'string' => 'read_string',
|
|
138
|
+
'binary' => 'read_string',
|
|
173
139
|
}
|
|
174
140
|
|
|
175
141
|
WriteFunc = {
|
|
@@ -180,6 +146,7 @@ module Stark
|
|
|
180
146
|
'i32' => "write_i32",
|
|
181
147
|
'i64' => "write_i64",
|
|
182
148
|
'string' => 'write_string',
|
|
149
|
+
'binary' => 'write_string',
|
|
183
150
|
}
|
|
184
151
|
|
|
185
152
|
def type(t)
|
|
@@ -187,7 +154,7 @@ module Stark
|
|
|
187
154
|
end
|
|
188
155
|
|
|
189
156
|
def wire_type(t)
|
|
190
|
-
return "::Thrift::Types::STRUCT" if @structs[t]
|
|
157
|
+
return "::Thrift::Types::STRUCT" if @structs[t] || @exceptions[t]
|
|
191
158
|
return "::Thrift::Types::I32" if @enums[t]
|
|
192
159
|
|
|
193
160
|
case t
|
|
@@ -202,9 +169,23 @@ module Stark
|
|
|
202
169
|
end
|
|
203
170
|
end
|
|
204
171
|
|
|
172
|
+
def wire_type_and_ruby_type(t)
|
|
173
|
+
return "::Thrift::Types::STRUCT, #{t}" if @structs[t] || @exceptions[t]
|
|
174
|
+
return "::Thrift::Types::I32, Enum_#{t}" if @enums[t]
|
|
175
|
+
wire_type(t)
|
|
176
|
+
end
|
|
177
|
+
|
|
205
178
|
def object_type(t)
|
|
206
|
-
|
|
207
|
-
|
|
179
|
+
case t
|
|
180
|
+
when Stark::Parser::AST::Map
|
|
181
|
+
"map<#{object_type(t.key)},#{object_type(t.value)}>"
|
|
182
|
+
when Stark::Parser::AST::List
|
|
183
|
+
"list<#{object_type(t.value)}>"
|
|
184
|
+
when Stark::Parser::AST::Set
|
|
185
|
+
"set<#{object_type(t.value)}>"
|
|
186
|
+
else
|
|
187
|
+
t
|
|
188
|
+
end
|
|
208
189
|
end
|
|
209
190
|
|
|
210
191
|
def read_func(t)
|
|
@@ -215,146 +196,160 @@ module Stark
|
|
|
215
196
|
WriteFunc[t] || raise("unknown type - #{t}")
|
|
216
197
|
end
|
|
217
198
|
|
|
218
|
-
def
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
o "
|
|
199
|
+
def read_type(t, lhs, found_type = 'rtype')
|
|
200
|
+
o "#{lhs} = expect ip, #{wire_type(t)}, #{found_type} do"
|
|
201
|
+
indent
|
|
202
|
+
if desc = @structs[t]
|
|
203
|
+
o "read_#{desc.name}(ip)"
|
|
204
|
+
elsif desc = @enums[t]
|
|
205
|
+
o "Enum_#{desc.name}[ip.read_i32]"
|
|
206
|
+
elsif t.kind_of? Stark::Parser::AST::Map
|
|
207
|
+
o "expect_map ip, #{wire_type(t.key)}, #{wire_type(t.value)} do |kt,vt,size|"
|
|
208
|
+
indent
|
|
209
|
+
o "{}.tap do |_hash|"
|
|
210
|
+
indent
|
|
211
|
+
o "size.times do"
|
|
212
|
+
indent
|
|
213
|
+
read_type(t.key, "k", "kt")
|
|
214
|
+
read_type(t.value, "v", "vt")
|
|
215
|
+
o "_hash[k] = v"
|
|
216
|
+
outdent
|
|
217
|
+
o "end"
|
|
218
|
+
outdent
|
|
219
|
+
o "end"
|
|
220
|
+
outdent
|
|
221
|
+
o "end"
|
|
222
|
+
elsif t.kind_of? Stark::Parser::AST::List
|
|
223
|
+
o "expect_list ip, #{wire_type(t.value)} do |vt,size|"
|
|
224
|
+
indent
|
|
225
|
+
o "Array.new(size) do"
|
|
226
|
+
indent
|
|
227
|
+
read_type t.value, "_elem", "vt"
|
|
228
|
+
outdent
|
|
229
|
+
o "end"
|
|
230
|
+
outdent
|
|
231
|
+
o "end"
|
|
232
|
+
elsif t.kind_of? Stark::Parser::AST::Set
|
|
233
|
+
o "expect_set ip, #{wire_type(t.value)} do |vt,size|"
|
|
234
|
+
indent
|
|
235
|
+
o "_arr = Array.new(size) do"
|
|
236
|
+
indent
|
|
237
|
+
read_type t.value, "element", "vt"
|
|
238
|
+
o "element"
|
|
239
|
+
outdent
|
|
240
|
+
o "end"
|
|
241
|
+
o "::Set.new(_arr)"
|
|
242
|
+
outdent
|
|
243
|
+
o "end"
|
|
244
|
+
else
|
|
245
|
+
o "ip.#{read_func(t)}"
|
|
246
|
+
end
|
|
247
|
+
outdent
|
|
248
|
+
o "end"
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def write_type(ft, name)
|
|
252
|
+
if desc = (@structs[ft] || @exceptions[ft])
|
|
253
|
+
o "write_#{desc.name} op, #{name}"
|
|
223
254
|
elsif desc = @enums[ft]
|
|
224
|
-
o "op.write_field_begin '#{name}', ::Thrift::Types::I32, #{idx}"
|
|
225
255
|
o "op.write_i32 Enum_#{desc.name}[#{name}.to_sym]"
|
|
226
|
-
|
|
227
|
-
o "op.write_field_end"
|
|
228
256
|
elsif ft.kind_of? Stark::Parser::AST::Map
|
|
229
257
|
o "#{name} = hash_cast #{name}"
|
|
230
|
-
o "op.write_field_begin '#{name}', ::Thrift::Types::MAP, #{idx}"
|
|
231
258
|
o "op.write_map_begin(#{wire_type(ft.key)}, #{wire_type(ft.value)}, #{name}.size)"
|
|
232
|
-
|
|
233
259
|
o "#{name}.each do |k,v|"
|
|
234
260
|
indent
|
|
235
|
-
|
|
236
|
-
|
|
261
|
+
write_type ft.key, "k"
|
|
262
|
+
write_type ft.value, "v"
|
|
237
263
|
outdent
|
|
238
264
|
o "end"
|
|
239
|
-
|
|
240
265
|
o "op.write_map_end"
|
|
241
|
-
o "op.write_field_end"
|
|
242
266
|
elsif ft.kind_of? Stark::Parser::AST::List
|
|
243
267
|
o "#{name} = Array(#{name})"
|
|
244
|
-
o "op.write_field_begin '#{name}', ::Thrift::Types::LIST, #{idx}"
|
|
245
268
|
o "op.write_list_begin(#{wire_type(ft.value)}, #{name}.size)"
|
|
246
|
-
o "#{name}.each
|
|
269
|
+
o "#{name}.each do |v|"
|
|
270
|
+
indent
|
|
271
|
+
write_type ft.value, "v"
|
|
272
|
+
outdent
|
|
273
|
+
o "end"
|
|
247
274
|
o "op.write_list_end"
|
|
248
|
-
|
|
249
|
-
o "
|
|
275
|
+
elsif ft.kind_of? Stark::Parser::AST::Set
|
|
276
|
+
o "#{name} = Set.new(#{name})"
|
|
277
|
+
o "op.write_list_begin(#{wire_type(ft.value)}, #{name}.size)"
|
|
278
|
+
o "#{name}.each do |v|"
|
|
279
|
+
indent
|
|
280
|
+
write_type ft.value, "v"
|
|
281
|
+
outdent
|
|
282
|
+
o "end"
|
|
283
|
+
o "op.write_set_end"
|
|
250
284
|
elsif ft != "void"
|
|
251
|
-
o "op.write_field_begin '#{name}', #{type(ft)}, #{idx}"
|
|
252
285
|
o "op.#{write_func(ft)} #{name}"
|
|
253
|
-
o "op.write_field_end"
|
|
254
286
|
end
|
|
255
|
-
|
|
256
287
|
end
|
|
257
288
|
|
|
258
|
-
def
|
|
259
|
-
o "op.
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
o "#{f.name} = #{obj}.#{f.name}"
|
|
263
|
-
write_field f.type, f.name, f.index
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
o "op.write_field_stop"
|
|
267
|
-
o "op.write_struct_end"
|
|
289
|
+
def write_field(ft, name, idx)
|
|
290
|
+
o "op.write_field_begin '#{name}', #{wire_type(ft)}, #{idx}"
|
|
291
|
+
write_type ft, name
|
|
292
|
+
o "op.write_field_end"
|
|
268
293
|
end
|
|
269
294
|
|
|
270
295
|
def write_processor(serv)
|
|
271
296
|
o "class Processor < Stark::Processor"
|
|
272
297
|
indent
|
|
298
|
+
o "include Protocol"
|
|
273
299
|
|
|
274
300
|
serv.functions.each do |func|
|
|
301
|
+
o
|
|
275
302
|
o "def process_#{func.name}(seqid, ip, op)"
|
|
276
303
|
indent
|
|
277
304
|
|
|
278
305
|
o "ip.read_struct_begin"
|
|
279
306
|
args = Array(func.arguments)
|
|
280
|
-
o "
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
o "else"
|
|
296
|
-
o " args[#{arg.index - 1}] = Enum_#{desc.name}[ip.read_i32]"
|
|
297
|
-
o "end"
|
|
298
|
-
o "ip.read_field_end"
|
|
299
|
-
|
|
300
|
-
elsif arg.type.kind_of? Stark::Parser::AST::Map
|
|
301
|
-
ft = arg.type
|
|
302
|
-
|
|
303
|
-
o "_, rtype, _ = ip.read_field_begin"
|
|
304
|
-
o "if rtype != #{wire_type(arg.type)}"
|
|
305
|
-
o " handle_unexpected rtype"
|
|
306
|
-
o "else"
|
|
307
|
-
o " kt, vt, size = ip.read_map_begin"
|
|
308
|
-
o " if kt == #{wire_type(ft.key)} && vt == #{wire_type(ft.value)}"
|
|
309
|
-
o " result = {}"
|
|
310
|
-
o " size.times do"
|
|
311
|
-
o " result[ip.#{read_func(ft.key)}] = ip.#{read_func(ft.value)}"
|
|
312
|
-
o " end"
|
|
313
|
-
o " args[#{arg.index - 1}] = result"
|
|
314
|
-
o " else"
|
|
315
|
-
o " handle_bad_map size"
|
|
316
|
-
o " end"
|
|
317
|
-
o " ip.read_map_end"
|
|
318
|
-
o "end"
|
|
319
|
-
o "ip.read_field_end"
|
|
320
|
-
elsif arg.type.kind_of? Stark::Parser::AST::List
|
|
321
|
-
ft = arg.type
|
|
322
|
-
o "_, rtype, _ = ip.read_field_begin"
|
|
323
|
-
o "if rtype == ::Thrift::Types::LIST"
|
|
324
|
-
o " vt, size = ip.read_list_begin"
|
|
325
|
-
o " if vt == #{wire_type(ft.value)}"
|
|
326
|
-
o " args[#{arg.index - 1}] = Array.new(size) { |n| ip.#{read_func(ft.value)} }"
|
|
327
|
-
o " else"
|
|
328
|
-
o " handle_bad_list size"
|
|
329
|
-
o " end"
|
|
330
|
-
o " ip.read_list_end"
|
|
331
|
-
o "else"
|
|
332
|
-
o " handle_unexpected rtype"
|
|
333
|
-
o "end"
|
|
334
|
-
o "ip.read_field_end"
|
|
335
|
-
else
|
|
336
|
-
o "_, rtype, _ = ip.read_field_begin"
|
|
337
|
-
o "if rtype == #{type(arg.type)}"
|
|
338
|
-
o " args[#{arg.index - 1}]= ip.#{read_func(arg.type)}"
|
|
339
|
-
o "else"
|
|
340
|
-
o " handle_unexpected rtype"
|
|
341
|
-
o "end"
|
|
342
|
-
o "ip.read_field_end"
|
|
307
|
+
o "fields = {}"
|
|
308
|
+
|
|
309
|
+
o "while true"
|
|
310
|
+
o " _, ftype, fid = ip.read_field_begin"
|
|
311
|
+
o " break if ftype == ::Thrift::Types::STOP"
|
|
312
|
+
|
|
313
|
+
if args.empty?
|
|
314
|
+
o " ip.skip ftype"
|
|
315
|
+
else
|
|
316
|
+
o " case fid"
|
|
317
|
+
args.each do |arg|
|
|
318
|
+
o " when #{arg.index}"
|
|
319
|
+
indent; indent
|
|
320
|
+
read_type arg.type, "fields[#{arg.index}]", "ftype"
|
|
321
|
+
outdent; outdent
|
|
343
322
|
end
|
|
323
|
+
o " else"
|
|
324
|
+
o " ip.skip ftype"
|
|
325
|
+
o " end"
|
|
344
326
|
end
|
|
345
|
-
|
|
346
|
-
o "
|
|
347
|
-
o "fail unless rtype == ::Thrift::Types::STOP"
|
|
327
|
+
o " ip.read_field_end"
|
|
328
|
+
o "end"
|
|
348
329
|
o "ip.read_struct_end"
|
|
349
330
|
o "ip.read_message_end"
|
|
350
331
|
|
|
351
|
-
|
|
352
|
-
o "result = check_raise_specific('#{func.name}', seqid, op, #{t.first.type}) do"
|
|
353
|
-
o " @handler.#{func.name}(*args)"
|
|
354
|
-
o "end"
|
|
355
|
-
|
|
356
|
-
o "return unless result"
|
|
332
|
+
o "args = #{args.map(&:index).inspect}.inject([]) {|arr,i| arr << fields[i] }"
|
|
357
333
|
|
|
334
|
+
if t = func.throws
|
|
335
|
+
o "begin"
|
|
336
|
+
indent
|
|
337
|
+
o "result = @handler.#{func.name}(*args)"
|
|
338
|
+
outdent
|
|
339
|
+
t.each do |ex|
|
|
340
|
+
o "rescue #{ex.type} => ex#{ex.index}"
|
|
341
|
+
indent
|
|
342
|
+
o "op.write_message_begin '#{func.name}', ::Thrift::MessageTypes::REPLY, seqid"
|
|
343
|
+
o "op.write_struct_begin '#{func.name}_result'"
|
|
344
|
+
write_field ex.type, "ex#{ex.index}", ex.index
|
|
345
|
+
o "op.write_field_stop"
|
|
346
|
+
o "op.write_struct_end"
|
|
347
|
+
o "op.write_message_end"
|
|
348
|
+
o "op.trans.flush"
|
|
349
|
+
o "return"
|
|
350
|
+
outdent
|
|
351
|
+
end
|
|
352
|
+
o "end"
|
|
358
353
|
else
|
|
359
354
|
o "result = @handler.#{func.name}(*args)"
|
|
360
355
|
end
|
|
@@ -366,12 +361,19 @@ module Stark
|
|
|
366
361
|
next
|
|
367
362
|
end
|
|
368
363
|
|
|
364
|
+
ft = func.return_type
|
|
365
|
+
o "result = value_for_write(result, #{wire_type_and_ruby_type(ft)})" if ft != "void"
|
|
366
|
+
|
|
369
367
|
o "op.write_message_begin '#{func.name}', ::Thrift::MessageTypes::REPLY, seqid"
|
|
370
368
|
o "op.write_struct_begin '#{func.name}_result'"
|
|
371
369
|
|
|
372
|
-
ft
|
|
373
|
-
|
|
374
|
-
|
|
370
|
+
if ft != "void"
|
|
371
|
+
o "if result"
|
|
372
|
+
indent
|
|
373
|
+
write_field ft, 'result', 0
|
|
374
|
+
outdent
|
|
375
|
+
o "end"
|
|
376
|
+
end
|
|
375
377
|
|
|
376
378
|
o "op.write_field_stop"
|
|
377
379
|
o "op.write_struct_end"
|
|
@@ -387,31 +389,69 @@ module Stark
|
|
|
387
389
|
o "end"
|
|
388
390
|
end
|
|
389
391
|
|
|
390
|
-
def
|
|
391
|
-
o
|
|
392
|
-
|
|
393
|
-
o "class Client < Stark::Client"
|
|
392
|
+
def write_protocol
|
|
393
|
+
o
|
|
394
|
+
o "module Protocol"
|
|
394
395
|
indent
|
|
396
|
+
@structs.merge(@exceptions).each do |name, struct|
|
|
397
|
+
o
|
|
398
|
+
o "def read_#{name}(ip)"
|
|
399
|
+
indent
|
|
400
|
+
o "obj = #{name}.new"
|
|
401
|
+
o "ip.read_struct_begin"
|
|
395
402
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
o "
|
|
399
|
-
|
|
400
|
-
o " :args => {"
|
|
403
|
+
o "while true"
|
|
404
|
+
o " _, ftype, fid = ip.read_field_begin"
|
|
405
|
+
o " break if ftype == ::Thrift::Types::STOP"
|
|
401
406
|
|
|
402
|
-
|
|
403
|
-
|
|
407
|
+
o " case fid"
|
|
408
|
+
struct.fields.each do |f|
|
|
409
|
+
o " when #{f.index}"
|
|
410
|
+
indent; indent
|
|
411
|
+
read_type f.type, "obj.#{f.name}", 'ftype'
|
|
412
|
+
outdent; outdent
|
|
404
413
|
end
|
|
414
|
+
o " else"
|
|
415
|
+
o " ip.skip ftype"
|
|
416
|
+
o " end"
|
|
417
|
+
o " ip.read_field_end"
|
|
418
|
+
o "end"
|
|
405
419
|
|
|
406
|
-
o "
|
|
420
|
+
o "ip.read_struct_end"
|
|
421
|
+
o "obj"
|
|
422
|
+
outdent
|
|
423
|
+
o "end"
|
|
424
|
+
o
|
|
425
|
+
o "def write_#{name}(op, str)"
|
|
426
|
+
indent
|
|
427
|
+
o "op.write_struct_begin '#{name}'"
|
|
407
428
|
|
|
408
|
-
|
|
409
|
-
|
|
429
|
+
struct.fields.each do |f|
|
|
430
|
+
o "if #{f.name} = value_for_write(str.#{f.name}, #{wire_type_and_ruby_type(f.type)})"
|
|
431
|
+
indent
|
|
432
|
+
write_field f.type, f.name, f.index
|
|
433
|
+
outdent
|
|
434
|
+
o "end"
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
o "op.write_field_stop"
|
|
438
|
+
o "op.write_struct_end"
|
|
439
|
+
outdent
|
|
440
|
+
o "end"
|
|
410
441
|
end
|
|
442
|
+
outdent
|
|
443
|
+
o "end"
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
def write_client(serv)
|
|
447
|
+
o "class Client < Stark::Client"
|
|
448
|
+
indent
|
|
449
|
+
o "include Protocol"
|
|
411
450
|
|
|
412
451
|
serv.functions.each do |func|
|
|
413
452
|
names = Array(func.arguments).map { |f| f.name }.join(", ")
|
|
414
453
|
|
|
454
|
+
o
|
|
415
455
|
o "def #{func.name}(#{names})"
|
|
416
456
|
indent
|
|
417
457
|
o "op = @oprot"
|
|
@@ -419,6 +459,7 @@ module Stark
|
|
|
419
459
|
o "op.write_struct_begin \"#{func.name}_args\""
|
|
420
460
|
|
|
421
461
|
Array(func.arguments).each do |arg|
|
|
462
|
+
o "#{arg.name} = value_for_write #{arg.name}, #{wire_type_and_ruby_type(arg.type)}"
|
|
422
463
|
write_field arg.type, arg.name, arg.index
|
|
423
464
|
end
|
|
424
465
|
|
|
@@ -444,68 +485,32 @@ module Stark
|
|
|
444
485
|
o "_, rtype, rid = ip.read_field_begin"
|
|
445
486
|
|
|
446
487
|
if t = func.throws
|
|
447
|
-
o "
|
|
448
|
-
|
|
488
|
+
o "case rid"
|
|
489
|
+
t.each do |ex|
|
|
490
|
+
o "when #{ex.index}"
|
|
491
|
+
o " _ex = read_#{ex.type}(ip)"
|
|
492
|
+
o " ip.read_field_end"
|
|
493
|
+
o " _, rtype, _ = ip.read_field_begin"
|
|
494
|
+
o " fail if rtype != ::Thrift::Types::STOP"
|
|
495
|
+
o " ip.read_struct_end"
|
|
496
|
+
o " ip.read_message_end"
|
|
497
|
+
o " raise _ex"
|
|
498
|
+
end
|
|
449
499
|
o "end"
|
|
450
500
|
end
|
|
451
501
|
|
|
452
|
-
o "fail unless rid == 0"
|
|
453
|
-
|
|
454
502
|
o "result = nil"
|
|
455
503
|
|
|
456
|
-
|
|
457
|
-
if desc = @structs[func.return_type]
|
|
458
|
-
o "if rtype != #{wire_type(func.return_type)}"
|
|
459
|
-
o " handle_unexpected rtype"
|
|
460
|
-
o "else"
|
|
461
|
-
o " result = read_generic rtype, rid, #{desc.name}"
|
|
462
|
-
o "end"
|
|
463
|
-
elsif desc = @enums[func.return_type]
|
|
464
|
-
o "if rtype != #{wire_type(func.return_type)}"
|
|
465
|
-
o " handle_unexpected rtype"
|
|
466
|
-
o "else"
|
|
467
|
-
o " result = Enum_#{desc.name}[ip.read_i32]"
|
|
468
|
-
o "end"
|
|
469
|
-
|
|
470
|
-
elsif func.return_type.kind_of? Stark::Parser::AST::Map
|
|
471
|
-
ft = func.return_type
|
|
472
|
-
|
|
473
|
-
o "if rtype != #{wire_type(func.return_type)}"
|
|
474
|
-
o " handle_unexpected rtype"
|
|
475
|
-
o "else"
|
|
476
|
-
o " kt, vt, size = ip.read_map_begin"
|
|
477
|
-
o " if kt == #{wire_type(ft.key)} && vt == #{wire_type(ft.value)}"
|
|
478
|
-
o " result = {}"
|
|
479
|
-
o " size.times do"
|
|
480
|
-
o " result[ip.#{read_func(ft.key)}] = ip.#{read_func(ft.value)}"
|
|
481
|
-
o " end"
|
|
482
|
-
o " else"
|
|
483
|
-
o " handle_bad_map size"
|
|
484
|
-
o " end"
|
|
485
|
-
o " ip.read_map_end"
|
|
486
|
-
o "end"
|
|
487
|
-
elsif func.return_type.kind_of? Stark::Parser::AST::List
|
|
488
|
-
ft = func.return_type
|
|
489
|
-
o "if rtype == ::Thrift::Types::LIST"
|
|
490
|
-
o " vt, size = ip.read_list_begin"
|
|
491
|
-
o " if vt == #{wire_type(ft.value)}"
|
|
492
|
-
o " result = Array.new(size) { |n| ip.#{read_func(ft.value)} }"
|
|
493
|
-
o " else"
|
|
494
|
-
o " handle_bad_list size"
|
|
495
|
-
o " end"
|
|
496
|
-
o " ip.read_list_end"
|
|
497
|
-
o "else"
|
|
498
|
-
o " handle_unexpected rtype"
|
|
499
|
-
o "end"
|
|
500
|
-
else
|
|
501
|
-
o "if rtype == #{type(func.return_type)}"
|
|
502
|
-
o " result = ip.#{read_func(func.return_type)}"
|
|
503
|
-
o "else"
|
|
504
|
-
o " handle_unexpected rtype"
|
|
505
|
-
o "end"
|
|
506
|
-
end
|
|
504
|
+
o "fail unless rid == 0"
|
|
507
505
|
|
|
508
|
-
|
|
506
|
+
if func.return_type != "void"
|
|
507
|
+
o "if rtype != ::Thrift::Types::STOP"
|
|
508
|
+
indent
|
|
509
|
+
read_type func.return_type, "result"
|
|
510
|
+
o "ip.read_field_end"
|
|
511
|
+
o "_, rtype, rid = ip.read_field_begin"
|
|
512
|
+
outdent
|
|
513
|
+
o "end"
|
|
509
514
|
end
|
|
510
515
|
|
|
511
516
|
o "fail if rtype != ::Thrift::Types::STOP"
|
|
@@ -521,7 +526,21 @@ module Stark
|
|
|
521
526
|
|
|
522
527
|
outdent
|
|
523
528
|
o "end"
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
def process_service(serv)
|
|
532
|
+
unless @protocol_declared
|
|
533
|
+
o
|
|
534
|
+
o "module Protocol; end"
|
|
535
|
+
@protocol_declared = true
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
o
|
|
539
|
+
o "module #{serv.name}"
|
|
540
|
+
indent
|
|
524
541
|
|
|
542
|
+
write_client serv
|
|
543
|
+
o
|
|
525
544
|
write_processor serv
|
|
526
545
|
|
|
527
546
|
outdent
|