blob: b6e3628ae47c3e36dd326713394e88f8c1125f2f [file] [log] [blame]
Roger Meier6cf0ffc2014-04-05 00:45:42 +02001--
2-- Licensed to the Apache Software Foundation (ASF) under one
3-- or more contributor license agreements. See the NOTICE file
4-- distributed with this work for additional information
5-- regarding copyright ownership. The ASF licenses this file
6-- to you under the Apache License, Version 2.0 (the
7-- "License"); you may not use this file except in compliance
8-- with the License. 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,
13-- software distributed under the License is distributed on an
14-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15-- KIND, either express or implied. See the License for the
16-- specific language governing permissions and limitations
17-- under the License.
18--
19
20---- namespace thrift
21--thrift = {}
22--setmetatable(thrift, {__index = _G}) --> perf hit for accessing global methods
23--setfenv(1, thrift)
24
25package.cpath = package.cpath .. ';bin/?.so' -- TODO FIX
Thomaseb684d32024-07-28 15:32:23 +020026
27local libluabitwise = require 'libluabitwise'
28
Roger Meier6cf0ffc2014-04-05 00:45:42 +020029function ttype(obj)
30 if type(obj) == 'table' and
31 obj.__type and
32 type(obj.__type) == 'string' then
33 return obj.__type
34 end
35 return type(obj)
36end
37
38function terror(e)
39 if e and e.__tostring then
40 error(e:__tostring())
41 return
42 end
43 error(e)
44end
45
winsweetde76a372014-12-09 16:14:51 +080046function ttable_size(t)
47 local count = 0
48 for k, v in pairs(t) do
49 count = count + 1
50 end
51 return count
52end
53
Jens Geyeref199cc2024-09-03 01:28:31 +020054version = '0.22.0'
Roger Meier6cf0ffc2014-04-05 00:45:42 +020055
56TType = {
57 STOP = 0,
58 VOID = 1,
59 BOOL = 2,
60 BYTE = 3,
61 I08 = 3,
62 DOUBLE = 4,
63 I16 = 6,
64 I32 = 8,
65 I64 = 10,
66 STRING = 11,
67 UTF7 = 11,
68 STRUCT = 12,
69 MAP = 13,
70 SET = 14,
71 LIST = 15,
Thomaseb684d32024-07-28 15:32:23 +020072 UUID = 16
Roger Meier6cf0ffc2014-04-05 00:45:42 +020073}
74
75TMessageType = {
76 CALL = 1,
77 REPLY = 2,
78 EXCEPTION = 3,
79 ONEWAY = 4
80}
81
Konrad Grochowski3b5dacb2014-11-24 10:55:31 +010082-- Recursive __index function to achieve inheritance
Roger Meier6cf0ffc2014-04-05 00:45:42 +020083function __tobj_index(self, key)
84 local v = rawget(self, key)
85 if v ~= nil then
86 return v
87 end
88
89 local p = rawget(self, '__parent')
90 if p then
91 return __tobj_index(p, key)
92 end
93
94 return nil
95end
96
97-- Basic Thrift-Lua Object
98__TObject = {
99 __type = '__TObject',
100 __mt = {
101 __index = __tobj_index
102 }
103}
104function __TObject:new(init_obj)
105 local obj = {}
106 if ttype(obj) == 'table' then
107 obj = init_obj
108 end
109
110 -- Use the __parent key and the __index function to achieve inheritance
111 obj.__parent = self
112 setmetatable(obj, __TObject.__mt)
113 return obj
114end
115
116-- Return a string representation of any lua variable
117function thrift_print_r(t)
118 local ret = ''
119 local ltype = type(t)
120 if (ltype == 'table') then
121 ret = ret .. '{ '
122 for key,value in pairs(t) do
123 ret = ret .. tostring(key) .. '=' .. thrift_print_r(value) .. ' '
124 end
125 ret = ret .. '}'
126 elseif ltype == 'string' then
127 ret = ret .. "'" .. tostring(t) .. "'"
128 else
129 ret = ret .. tostring(t)
130 end
131 return ret
132end
133
134-- Basic Exception
135TException = __TObject:new{
136 message,
137 errorCode,
138 __type = 'TException'
139}
140function TException:__tostring()
141 if self.message then
142 return string.format('%s: %s', self.__type, self.message)
143 else
144 local message
145 if self.errorCode and self.__errorCodeToString then
146 message = string.format('%d: %s', self.errorCode, self:__errorCodeToString())
147 else
148 message = thrift_print_r(self)
149 end
150 return string.format('%s:%s', self.__type, message)
151 end
152end
153
154TApplicationException = TException:new{
155 UNKNOWN = 0,
156 UNKNOWN_METHOD = 1,
157 INVALID_MESSAGE_TYPE = 2,
158 WRONG_METHOD_NAME = 3,
159 BAD_SEQUENCE_ID = 4,
160 MISSING_RESULT = 5,
161 INTERNAL_ERROR = 6,
162 PROTOCOL_ERROR = 7,
163 INVALID_TRANSFORM = 8,
164 INVALID_PROTOCOL = 9,
165 UNSUPPORTED_CLIENT_TYPE = 10,
166 errorCode = 0,
167 __type = 'TApplicationException'
168}
169
170function TApplicationException:__errorCodeToString()
171 if self.errorCode == self.UNKNOWN_METHOD then
172 return 'Unknown method'
173 elseif self.errorCode == self.INVALID_MESSAGE_TYPE then
174 return 'Invalid message type'
175 elseif self.errorCode == self.WRONG_METHOD_NAME then
176 return 'Wrong method name'
177 elseif self.errorCode == self.BAD_SEQUENCE_ID then
178 return 'Bad sequence ID'
179 elseif self.errorCode == self.MISSING_RESULT then
180 return 'Missing result'
181 elseif self.errorCode == self.INTERNAL_ERROR then
182 return 'Internal error'
183 elseif self.errorCode == self.PROTOCOL_ERROR then
184 return 'Protocol error'
185 elseif self.errorCode == self.INVALID_TRANSFORM then
186 return 'Invalid transform'
187 elseif self.errorCode == self.INVALID_PROTOCOL then
188 return 'Invalid protocol'
189 elseif self.errorCode == self.UNSUPPORTED_CLIENT_TYPE then
190 return 'Unsupported client type'
191 else
192 return 'Default (unknown)'
193 end
194end
195
196function TException:read(iprot)
197 iprot:readStructBegin()
198 while true do
199 local fname, ftype, fid = iprot:readFieldBegin()
200 if ftype == TType.STOP then
201 break
202 elseif fid == 1 then
203 if ftype == TType.STRING then
204 self.message = iprot:readString()
205 else
206 iprot:skip(ftype)
207 end
208 elseif fid == 2 then
209 if ftype == TType.I32 then
210 self.errorCode = iprot:readI32()
211 else
212 iprot:skip(ftype)
213 end
214 else
215 iprot:skip(ftype)
216 end
217 iprot:readFieldEnd()
218 end
219 iprot:readStructEnd()
220end
221
222function TException:write(oprot)
223 oprot:writeStructBegin('TApplicationException')
224 if self.message then
225 oprot:writeFieldBegin('message', TType.STRING, 1)
226 oprot:writeString(self.message)
227 oprot:writeFieldEnd()
228 end
229 if self.errorCode then
230 oprot:writeFieldBegin('type', TType.I32, 2)
231 oprot:writeI32(self.errorCode)
232 oprot:writeFieldEnd()
233 end
234 oprot:writeFieldStop()
235 oprot:writeStructEnd()
236end
237
Thomaseb684d32024-07-28 15:32:23 +0200238TUUID = {
239 zero,
240 one,
241 two,
242 three
243}
244
245TUUID = __TObject:new{
246 __type = 'TUUID'
247}
248
249function TUUIDfromString(str)
250 local iterator = string.gmatch(str, "[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]")
251 return TUUID:new {
252 zero = libluabitwise.buor(libluabitwise.ushiftl(tonumber(iterator(), 16), 16), tonumber(iterator(), 16)),
253 one = libluabitwise.buor(libluabitwise.ushiftl(tonumber(iterator(), 16), 16), tonumber(iterator(), 16)),
254 two = libluabitwise.buor(libluabitwise.ushiftl(tonumber(iterator(), 16), 16), tonumber(iterator(), 16)),
255 three = libluabitwise.buor(libluabitwise.ushiftl(tonumber(iterator(), 16), 16), tonumber(iterator(), 16))
256 }
257end
258
259function TUUID:getString()
260 return string.format("%08x-%04x-%04x-%04x-%04x%08x", self.zero, libluabitwise.ushiftr(self.one, 16), libluabitwise.buand(self.one, 0xFFFF), libluabitwise.ushiftr(self.two, 16), libluabitwise.buand(self.two, 0xFFFF), self.three)
261end
262
263function TUUID:__tostring()
264 return "<TUUID: " .. self:getString() .. ">"
265end
266
Roger Meier6cf0ffc2014-04-05 00:45:42 +0200267-- Basic Client (used in generated lua code)
268__TClient = __TObject:new{
269 __type = '__TClient',
270 _seqid = 0
271}
272function __TClient:new(obj)
273 if ttype(obj) ~= 'table' then
274 error('TClient must be initialized with a table')
275 end
276
277 -- Set iprot & oprot
278 if obj.protocol then
279 obj.iprot = obj.protocol
280 obj.oprot = obj.protocol
281 obj.protocol = nil
282 elseif not obj.iprot then
283 error('You must provide ' .. ttype(self) .. ' with an iprot')
284 end
285 if not obj.oprot then
286 obj.oprot = obj.iprot
287 end
288
289 return __TObject.new(self, obj)
290end
291
292function __TClient:close()
293 self.iprot.trans:close()
294 self.oprot.trans:close()
295end
296
297-- Basic Processor (used in generated lua code)
298__TProcessor = __TObject:new{
299 __type = '__TProcessor'
300}
301function __TProcessor:new(obj)
302 if ttype(obj) ~= 'table' then
303 error('TProcessor must be initialized with a table')
304 end
305
306 -- Ensure a handler is provided
307 if not obj.handler then
308 error('You must provide ' .. ttype(self) .. ' with a handler')
309 end
310
311 return __TObject.new(self, obj)
312end