1 /*
2 * Copyright (c) 2009-2021, Google LLC
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Google LLC nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <float.h>
29 #include <math.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include "lauxlib.h"
33 #include "upb/bindings/lua/upb.h"
34 #include "upb/def.h"
35
36 #define LUPB_ENUMDEF "lupb.enumdef"
37 #define LUPB_ENUMVALDEF "lupb.enumvaldef"
38 #define LUPB_FIELDDEF "lupb.fielddef"
39 #define LUPB_FILEDEF "lupb.filedef"
40 #define LUPB_MSGDEF "lupb.msgdef"
41 #define LUPB_ONEOFDEF "lupb.oneof"
42 #define LUPB_SYMTAB "lupb.symtab"
43 #define LUPB_OBJCACHE "lupb.objcache"
44
45 static void lupb_symtab_pushwrapper(lua_State *L, int narg, const void *def,
46 const char *type);
47
48 /* lupb_wrapper ***************************************************************/
49
50 /* Wrappers around upb def objects. The userval contains a reference to the
51 * symtab. */
52
53 #define LUPB_SYMTAB_INDEX 1
54
55 typedef struct {
56 const void* def; /* upb_msgdef, upb_enumdef, upb_oneofdef, etc. */
57 } lupb_wrapper;
58
lupb_wrapper_check(lua_State * L,int narg,const char * type)59 static const void *lupb_wrapper_check(lua_State *L, int narg,
60 const char *type) {
61 lupb_wrapper *w = luaL_checkudata(L, narg, type);
62 return w->def;
63 }
64
lupb_wrapper_pushsymtab(lua_State * L,int narg)65 static void lupb_wrapper_pushsymtab(lua_State *L, int narg) {
66 lua_getiuservalue(L, narg, LUPB_SYMTAB_INDEX);
67 }
68
69 /* lupb_wrapper_pushwrapper()
70 *
71 * For a given def wrapper at index |narg|, pushes a wrapper for the given |def|
72 * and the given |type|. The new wrapper will be part of the same symtab. */
lupb_wrapper_pushwrapper(lua_State * L,int narg,const void * def,const char * type)73 static void lupb_wrapper_pushwrapper(lua_State *L, int narg, const void *def,
74 const char *type) {
75 lupb_wrapper_pushsymtab(L, narg);
76 lupb_symtab_pushwrapper(L, -1, def, type);
77 lua_replace(L, -2); /* Remove symtab from stack. */
78 }
79
80 /* lupb_msgdef_pushsubmsgdef()
81 *
82 * Pops the msgdef wrapper at the top of the stack and replaces it with a msgdef
83 * wrapper for field |f| of this msgdef (submsg may not be direct, for example it
84 * may be the submessage of the map value).
85 */
lupb_msgdef_pushsubmsgdef(lua_State * L,const upb_fielddef * f)86 void lupb_msgdef_pushsubmsgdef(lua_State *L, const upb_fielddef *f) {
87 const upb_msgdef *m = upb_fielddef_msgsubdef(f);
88 assert(m);
89 lupb_wrapper_pushwrapper(L, -1, m, LUPB_MSGDEF);
90 lua_replace(L, -2); /* Replace msgdef with submsgdef. */
91 }
92
93 /* lupb_fielddef **************************************************************/
94
lupb_fielddef_check(lua_State * L,int narg)95 const upb_fielddef *lupb_fielddef_check(lua_State *L, int narg) {
96 return lupb_wrapper_check(L, narg, LUPB_FIELDDEF);
97 }
98
lupb_fielddef_containingoneof(lua_State * L)99 static int lupb_fielddef_containingoneof(lua_State *L) {
100 const upb_fielddef *f = lupb_fielddef_check(L, 1);
101 const upb_oneofdef *o = upb_fielddef_containingoneof(f);
102 lupb_wrapper_pushwrapper(L, 1, o, LUPB_ONEOFDEF);
103 return 1;
104 }
105
lupb_fielddef_containingtype(lua_State * L)106 static int lupb_fielddef_containingtype(lua_State *L) {
107 const upb_fielddef *f = lupb_fielddef_check(L, 1);
108 const upb_msgdef *m = upb_fielddef_containingtype(f);
109 lupb_wrapper_pushwrapper(L, 1, m, LUPB_MSGDEF);
110 return 1;
111 }
112
lupb_fielddef_default(lua_State * L)113 static int lupb_fielddef_default(lua_State *L) {
114 const upb_fielddef *f = lupb_fielddef_check(L, 1);
115 switch (upb_fielddef_type(f)) {
116 case UPB_TYPE_INT32:
117 case UPB_TYPE_ENUM:
118 lupb_pushint32(L, upb_fielddef_defaultint32(f)); break;
119 case UPB_TYPE_INT64:
120 lupb_pushint64(L, upb_fielddef_defaultint64(f)); break;
121 case UPB_TYPE_UINT32:
122 lupb_pushuint32(L, upb_fielddef_defaultuint32(f)); break;
123 case UPB_TYPE_UINT64:
124 lupb_pushuint64(L, upb_fielddef_defaultuint64(f)); break;
125 case UPB_TYPE_DOUBLE:
126 lua_pushnumber(L, upb_fielddef_defaultdouble(f)); break;
127 case UPB_TYPE_FLOAT:
128 lua_pushnumber(L, upb_fielddef_defaultfloat(f)); break;
129 case UPB_TYPE_BOOL:
130 lua_pushboolean(L, upb_fielddef_defaultbool(f)); break;
131 case UPB_TYPE_STRING:
132 case UPB_TYPE_BYTES: {
133 size_t len;
134 const char *data = upb_fielddef_defaultstr(f, &len);
135 lua_pushlstring(L, data, len);
136 break;
137 }
138 case UPB_TYPE_MESSAGE:
139 return luaL_error(L, "Message fields do not have explicit defaults.");
140 }
141 return 1;
142 }
143
lupb_fielddef_descriptortype(lua_State * L)144 static int lupb_fielddef_descriptortype(lua_State *L) {
145 const upb_fielddef *f = lupb_fielddef_check(L, 1);
146 lua_pushnumber(L, upb_fielddef_descriptortype(f));
147 return 1;
148 }
149
lupb_fielddef_hassubdef(lua_State * L)150 static int lupb_fielddef_hassubdef(lua_State *L) {
151 const upb_fielddef *f = lupb_fielddef_check(L, 1);
152 lua_pushboolean(L, upb_fielddef_hassubdef(f));
153 return 1;
154 }
155
lupb_fielddef_index(lua_State * L)156 static int lupb_fielddef_index(lua_State *L) {
157 const upb_fielddef *f = lupb_fielddef_check(L, 1);
158 lua_pushinteger(L, upb_fielddef_index(f));
159 return 1;
160 }
161
lupb_fielddef_isextension(lua_State * L)162 static int lupb_fielddef_isextension(lua_State *L) {
163 const upb_fielddef *f = lupb_fielddef_check(L, 1);
164 lua_pushboolean(L, upb_fielddef_isextension(f));
165 return 1;
166 }
167
lupb_fielddef_label(lua_State * L)168 static int lupb_fielddef_label(lua_State *L) {
169 const upb_fielddef *f = lupb_fielddef_check(L, 1);
170 lua_pushinteger(L, upb_fielddef_label(f));
171 return 1;
172 }
173
lupb_fielddef_lazy(lua_State * L)174 static int lupb_fielddef_lazy(lua_State *L) {
175 const upb_fielddef *f = lupb_fielddef_check(L, 1);
176 lua_pushboolean(L, upb_fielddef_lazy(f));
177 return 1;
178 }
179
lupb_fielddef_name(lua_State * L)180 static int lupb_fielddef_name(lua_State *L) {
181 const upb_fielddef *f = lupb_fielddef_check(L, 1);
182 lua_pushstring(L, upb_fielddef_name(f));
183 return 1;
184 }
185
lupb_fielddef_number(lua_State * L)186 static int lupb_fielddef_number(lua_State *L) {
187 const upb_fielddef *f = lupb_fielddef_check(L, 1);
188 int32_t num = upb_fielddef_number(f);
189 if (num) {
190 lua_pushinteger(L, num);
191 } else {
192 lua_pushnil(L);
193 }
194 return 1;
195 }
196
lupb_fielddef_packed(lua_State * L)197 static int lupb_fielddef_packed(lua_State *L) {
198 const upb_fielddef *f = lupb_fielddef_check(L, 1);
199 lua_pushboolean(L, upb_fielddef_packed(f));
200 return 1;
201 }
202
lupb_fielddef_msgsubdef(lua_State * L)203 static int lupb_fielddef_msgsubdef(lua_State *L) {
204 const upb_fielddef *f = lupb_fielddef_check(L, 1);
205 const upb_msgdef *m = upb_fielddef_msgsubdef(f);
206 lupb_wrapper_pushwrapper(L, 1, m, LUPB_MSGDEF);
207 return 1;
208 }
209
lupb_fielddef_enumsubdef(lua_State * L)210 static int lupb_fielddef_enumsubdef(lua_State *L) {
211 const upb_fielddef *f = lupb_fielddef_check(L, 1);
212 const upb_enumdef *e = upb_fielddef_enumsubdef(f);
213 lupb_wrapper_pushwrapper(L, 1, e, LUPB_ENUMDEF);
214 return 1;
215 }
216
lupb_fielddef_type(lua_State * L)217 static int lupb_fielddef_type(lua_State *L) {
218 const upb_fielddef *f = lupb_fielddef_check(L, 1);
219 lua_pushinteger(L, upb_fielddef_type(f));
220 return 1;
221 }
222
223 static const struct luaL_Reg lupb_fielddef_m[] = {
224 {"containing_oneof", lupb_fielddef_containingoneof},
225 {"containing_type", lupb_fielddef_containingtype},
226 {"default", lupb_fielddef_default},
227 {"descriptor_type", lupb_fielddef_descriptortype},
228 {"has_subdef", lupb_fielddef_hassubdef},
229 {"index", lupb_fielddef_index},
230 {"is_extension", lupb_fielddef_isextension},
231 {"label", lupb_fielddef_label},
232 {"lazy", lupb_fielddef_lazy},
233 {"name", lupb_fielddef_name},
234 {"number", lupb_fielddef_number},
235 {"packed", lupb_fielddef_packed},
236 {"msgsubdef", lupb_fielddef_msgsubdef},
237 {"enumsubdef", lupb_fielddef_enumsubdef},
238 {"type", lupb_fielddef_type},
239 {NULL, NULL}
240 };
241
242 /* lupb_oneofdef **************************************************************/
243
lupb_oneofdef_check(lua_State * L,int narg)244 const upb_oneofdef *lupb_oneofdef_check(lua_State *L, int narg) {
245 return lupb_wrapper_check(L, narg, LUPB_ONEOFDEF);
246 }
247
lupb_oneofdef_containingtype(lua_State * L)248 static int lupb_oneofdef_containingtype(lua_State *L) {
249 const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
250 const upb_msgdef *m = upb_oneofdef_containingtype(o);
251 lupb_wrapper_pushwrapper(L, 1, m, LUPB_MSGDEF);
252 return 1;
253 }
254
lupb_oneofdef_field(lua_State * L)255 static int lupb_oneofdef_field(lua_State *L) {
256 const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
257 int32_t idx = lupb_checkint32(L, 2);
258 int count = upb_oneofdef_fieldcount(o);
259
260 if (idx < 0 || idx >= count) {
261 const char *msg = lua_pushfstring(L, "index %d exceeds field count %d",
262 idx, count);
263 return luaL_argerror(L, 2, msg);
264 }
265
266 lupb_wrapper_pushwrapper(L, 1, upb_oneofdef_field(o, idx), LUPB_FIELDDEF);
267 return 1;
268 }
269
lupb_oneofiter_next(lua_State * L)270 static int lupb_oneofiter_next(lua_State *L) {
271 const upb_oneofdef *o = lupb_oneofdef_check(L, lua_upvalueindex(1));
272 int *index = lua_touserdata(L, lua_upvalueindex(2));
273 const upb_fielddef *f;
274 if (*index == upb_oneofdef_fieldcount(o)) return 0;
275 f = upb_oneofdef_field(o, (*index)++);
276 lupb_wrapper_pushwrapper(L, lua_upvalueindex(1), f, LUPB_FIELDDEF);
277 return 1;
278 }
279
lupb_oneofdef_fields(lua_State * L)280 static int lupb_oneofdef_fields(lua_State *L) {
281 int *index = lua_newuserdata(L, sizeof(int));
282 lupb_oneofdef_check(L, 1);
283 *index = 0;
284
285 /* Closure upvalues are: oneofdef, index. */
286 lua_pushcclosure(L, &lupb_oneofiter_next, 2);
287 return 1;
288 }
289
lupb_oneofdef_len(lua_State * L)290 static int lupb_oneofdef_len(lua_State *L) {
291 const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
292 lua_pushinteger(L, upb_oneofdef_fieldcount(o));
293 return 1;
294 }
295
296 /* lupb_oneofdef_lookupfield()
297 *
298 * Handles:
299 * oneof.lookup_field(field_number)
300 * oneof.lookup_field(field_name)
301 */
lupb_oneofdef_lookupfield(lua_State * L)302 static int lupb_oneofdef_lookupfield(lua_State *L) {
303 const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
304 const upb_fielddef *f;
305
306 switch (lua_type(L, 2)) {
307 case LUA_TNUMBER:
308 f = upb_oneofdef_itof(o, lua_tointeger(L, 2));
309 break;
310 case LUA_TSTRING:
311 f = upb_oneofdef_ntofz(o, lua_tostring(L, 2));
312 break;
313 default: {
314 const char *msg = lua_pushfstring(L, "number or string expected, got %s",
315 luaL_typename(L, 2));
316 return luaL_argerror(L, 2, msg);
317 }
318 }
319
320 lupb_wrapper_pushwrapper(L, 1, f, LUPB_FIELDDEF);
321 return 1;
322 }
323
lupb_oneofdef_name(lua_State * L)324 static int lupb_oneofdef_name(lua_State *L) {
325 const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
326 lua_pushstring(L, upb_oneofdef_name(o));
327 return 1;
328 }
329
330 static const struct luaL_Reg lupb_oneofdef_m[] = {
331 {"containing_type", lupb_oneofdef_containingtype},
332 {"field", lupb_oneofdef_field},
333 {"fields", lupb_oneofdef_fields},
334 {"lookup_field", lupb_oneofdef_lookupfield},
335 {"name", lupb_oneofdef_name},
336 {NULL, NULL}
337 };
338
339 static const struct luaL_Reg lupb_oneofdef_mm[] = {
340 {"__len", lupb_oneofdef_len},
341 {NULL, NULL}
342 };
343
344
345 /* lupb_msgdef ****************************************************************/
346
347 typedef struct {
348 const upb_msgdef *md;
349 } lupb_msgdef;
350
lupb_msgdef_check(lua_State * L,int narg)351 const upb_msgdef *lupb_msgdef_check(lua_State *L, int narg) {
352 return lupb_wrapper_check(L, narg, LUPB_MSGDEF);
353 }
354
lupb_msgdef_fieldcount(lua_State * L)355 static int lupb_msgdef_fieldcount(lua_State *L) {
356 const upb_msgdef *m = lupb_msgdef_check(L, 1);
357 lua_pushinteger(L, upb_msgdef_fieldcount(m));
358 return 1;
359 }
360
lupb_msgdef_oneofcount(lua_State * L)361 static int lupb_msgdef_oneofcount(lua_State *L) {
362 const upb_msgdef *m = lupb_msgdef_check(L, 1);
363 lua_pushinteger(L, upb_msgdef_oneofcount(m));
364 return 1;
365 }
366
lupb_msgdef_pushnested(lua_State * L,int msgdef,int name)367 static bool lupb_msgdef_pushnested(lua_State *L, int msgdef, int name) {
368 const upb_msgdef *m = lupb_msgdef_check(L, msgdef);
369 lupb_wrapper_pushsymtab(L, msgdef);
370 upb_symtab *symtab = lupb_symtab_check(L, -1);
371 lua_pop(L, 1);
372
373 /* Construct full package.Message.SubMessage name. */
374 lua_pushstring(L, upb_msgdef_fullname(m));
375 lua_pushstring(L, ".");
376 lua_pushvalue(L, name);
377 lua_concat(L, 3);
378 const char *nested_name = lua_tostring(L, -1);
379
380 /* Try lookup. */
381 const upb_msgdef *nested = upb_symtab_lookupmsg(symtab, nested_name);
382 if (!nested) return false;
383 lupb_wrapper_pushwrapper(L, msgdef, nested, LUPB_MSGDEF);
384 return true;
385 }
386
387 /* lupb_msgdef_field()
388 *
389 * Handles:
390 * msg.field(field_number) -> fielddef
391 * msg.field(field_name) -> fielddef
392 */
lupb_msgdef_field(lua_State * L)393 static int lupb_msgdef_field(lua_State *L) {
394 const upb_msgdef *m = lupb_msgdef_check(L, 1);
395 const upb_fielddef *f;
396
397 switch (lua_type(L, 2)) {
398 case LUA_TNUMBER:
399 f = upb_msgdef_itof(m, lua_tointeger(L, 2));
400 break;
401 case LUA_TSTRING:
402 f = upb_msgdef_ntofz(m, lua_tostring(L, 2));
403 break;
404 default: {
405 const char *msg = lua_pushfstring(L, "number or string expected, got %s",
406 luaL_typename(L, 2));
407 return luaL_argerror(L, 2, msg);
408 }
409 }
410
411 lupb_wrapper_pushwrapper(L, 1, f, LUPB_FIELDDEF);
412 return 1;
413 }
414
415 /* lupb_msgdef_lookupname()
416 *
417 * Handles:
418 * msg.lookup_name(name) -> fielddef or oneofdef
419 */
lupb_msgdef_lookupname(lua_State * L)420 static int lupb_msgdef_lookupname(lua_State *L) {
421 const upb_msgdef *m = lupb_msgdef_check(L, 1);
422 const upb_fielddef *f;
423 const upb_oneofdef *o;
424
425 if (!upb_msgdef_lookupnamez(m, lua_tostring(L, 2), &f, &o)) {
426 lua_pushnil(L);
427 } else if (o) {
428 lupb_wrapper_pushwrapper(L, 1, o, LUPB_ONEOFDEF);
429 } else {
430 lupb_wrapper_pushwrapper(L, 1, f, LUPB_FIELDDEF);
431 }
432
433 return 1;
434 }
435
436 /* lupb_msgdef_name()
437 *
438 * Handles:
439 * msg.name() -> string
440 */
lupb_msgdef_name(lua_State * L)441 static int lupb_msgdef_name(lua_State *L) {
442 const upb_msgdef *m = lupb_msgdef_check(L, 1);
443 lua_pushstring(L, upb_msgdef_name(m));
444 return 1;
445 }
446
lupb_msgfielditer_next(lua_State * L)447 static int lupb_msgfielditer_next(lua_State *L) {
448 const upb_msgdef *m = lupb_msgdef_check(L, lua_upvalueindex(1));
449 int *index = lua_touserdata(L, lua_upvalueindex(2));
450 const upb_fielddef *f;
451 if (*index == upb_msgdef_fieldcount(m)) return 0;
452 f = upb_msgdef_field(m, (*index)++);
453 lupb_wrapper_pushwrapper(L, lua_upvalueindex(1), f, LUPB_FIELDDEF);
454 return 1;
455 }
456
lupb_msgdef_fields(lua_State * L)457 static int lupb_msgdef_fields(lua_State *L) {
458 int *index = lua_newuserdata(L, sizeof(int));
459 lupb_msgdef_check(L, 1);
460 *index = 0;
461
462 /* Closure upvalues are: msgdef, index. */
463 lua_pushcclosure(L, &lupb_msgfielditer_next, 2);
464 return 1;
465 }
466
lupb_msgdef_file(lua_State * L)467 static int lupb_msgdef_file(lua_State *L) {
468 const upb_msgdef *m = lupb_msgdef_check(L, 1);
469 const upb_filedef *file = upb_msgdef_file(m);
470 lupb_wrapper_pushwrapper(L, 1, file, LUPB_FILEDEF);
471 return 1;
472 }
473
lupb_msgdef_fullname(lua_State * L)474 static int lupb_msgdef_fullname(lua_State *L) {
475 const upb_msgdef *m = lupb_msgdef_check(L, 1);
476 lua_pushstring(L, upb_msgdef_fullname(m));
477 return 1;
478 }
479
lupb_msgdef_index(lua_State * L)480 static int lupb_msgdef_index(lua_State *L) {
481 if (!lupb_msgdef_pushnested(L, 1, 2)) {
482 luaL_error(L, "No such nested message");
483 }
484 return 1;
485 }
486
lupb_msgoneofiter_next(lua_State * L)487 static int lupb_msgoneofiter_next(lua_State *L) {
488 const upb_msgdef *m = lupb_msgdef_check(L, lua_upvalueindex(1));
489 int *index = lua_touserdata(L, lua_upvalueindex(2));
490 const upb_oneofdef *o;
491 if (*index == upb_msgdef_oneofcount(m)) return 0;
492 o = upb_msgdef_oneof(m, (*index)++);
493 lupb_wrapper_pushwrapper(L, lua_upvalueindex(1), o, LUPB_ONEOFDEF);
494 return 1;
495 }
496
lupb_msgdef_oneofs(lua_State * L)497 static int lupb_msgdef_oneofs(lua_State *L) {
498 int *index = lua_newuserdata(L, sizeof(int));
499 lupb_msgdef_check(L, 1);
500 *index = 0;
501
502 /* Closure upvalues are: msgdef, index. */
503 lua_pushcclosure(L, &lupb_msgoneofiter_next, 2);
504 return 1;
505 }
506
lupb_msgdef_mapentry(lua_State * L)507 static int lupb_msgdef_mapentry(lua_State *L) {
508 const upb_msgdef *m = lupb_msgdef_check(L, 1);
509 lua_pushboolean(L, upb_msgdef_mapentry(m));
510 return 1;
511 }
512
lupb_msgdef_syntax(lua_State * L)513 static int lupb_msgdef_syntax(lua_State *L) {
514 const upb_msgdef *m = lupb_msgdef_check(L, 1);
515 lua_pushinteger(L, upb_msgdef_syntax(m));
516 return 1;
517 }
518
lupb_msgdef_tostring(lua_State * L)519 static int lupb_msgdef_tostring(lua_State *L) {
520 const upb_msgdef *m = lupb_msgdef_check(L, 1);
521 lua_pushfstring(L, "<upb.MessageDef name=%s, field_count=%d>",
522 upb_msgdef_fullname(m), (int)upb_msgdef_numfields(m));
523 return 1;
524 }
525
526 static const struct luaL_Reg lupb_msgdef_mm[] = {
527 {"__call", lupb_msgdef_call},
528 {"__index", lupb_msgdef_index},
529 {"__len", lupb_msgdef_fieldcount},
530 {"__tostring", lupb_msgdef_tostring},
531 {NULL, NULL}
532 };
533
534 static const struct luaL_Reg lupb_msgdef_m[] = {
535 {"field", lupb_msgdef_field},
536 {"fields", lupb_msgdef_fields},
537 {"field_count", lupb_msgdef_fieldcount},
538 {"file", lupb_msgdef_file},
539 {"full_name", lupb_msgdef_fullname},
540 {"lookup_name", lupb_msgdef_lookupname},
541 {"name", lupb_msgdef_name},
542 {"oneof_count", lupb_msgdef_oneofcount},
543 {"oneofs", lupb_msgdef_oneofs},
544 {"syntax", lupb_msgdef_syntax},
545 {"_map_entry", lupb_msgdef_mapentry},
546 {NULL, NULL}
547 };
548
549
550 /* lupb_enumdef ***************************************************************/
551
lupb_enumdef_check(lua_State * L,int narg)552 const upb_enumdef *lupb_enumdef_check(lua_State *L, int narg) {
553 return lupb_wrapper_check(L, narg, LUPB_ENUMDEF);
554 }
555
lupb_enumdef_len(lua_State * L)556 static int lupb_enumdef_len(lua_State *L) {
557 const upb_enumdef *e = lupb_enumdef_check(L, 1);
558 lua_pushinteger(L, upb_enumdef_numvals(e));
559 return 1;
560 }
561
lupb_enumdef_file(lua_State * L)562 static int lupb_enumdef_file(lua_State *L) {
563 const upb_enumdef *e = lupb_enumdef_check(L, 1);
564 const upb_filedef *file = upb_enumdef_file(e);
565 lupb_wrapper_pushwrapper(L, 1, file, LUPB_FILEDEF);
566 return 1;
567 }
568
569 /* lupb_enumdef_value()
570 *
571 * Handles:
572 * enum.value(number) -> enumval
573 * enum.value(name) -> enumval
574 */
lupb_enumdef_value(lua_State * L)575 static int lupb_enumdef_value(lua_State *L) {
576 const upb_enumdef *e = lupb_enumdef_check(L, 1);
577 const upb_enumvaldef *ev;
578
579 switch (lua_type(L, 2)) {
580 case LUA_TNUMBER:
581 ev = upb_enumdef_lookupnum(e, lupb_checkint32(L, 2));
582 break;
583 case LUA_TSTRING:
584 ev = upb_enumdef_lookupnamez(e, lua_tostring(L, 2));
585 break;
586 default: {
587 const char *msg = lua_pushfstring(L, "number or string expected, got %s",
588 luaL_typename(L, 2));
589 return luaL_argerror(L, 2, msg);
590 }
591 }
592
593 lupb_wrapper_pushwrapper(L, 1, ev, LUPB_ENUMVALDEF);
594 return 1;
595 }
596
lupb_enumiter_next(lua_State * L)597 static int lupb_enumiter_next(lua_State *L) {
598 upb_enum_iter *i = lua_touserdata(L, lua_upvalueindex(1));
599 if (upb_enum_done(i)) return 0;
600 lua_pushstring(L, upb_enum_iter_name(i));
601 lua_pushinteger(L, upb_enum_iter_number(i));
602 upb_enum_next(i);
603 return 2;
604 }
605
lupb_enumdef_values(lua_State * L)606 static int lupb_enumdef_values(lua_State *L) {
607 const upb_enumdef *e = lupb_enumdef_check(L, 1);
608 upb_enum_iter *i = lua_newuserdata(L, sizeof(upb_enum_iter));
609 lupb_wrapper_pushsymtab(L, 1);
610 upb_enum_begin(i, e);
611
612 /* Closure upvalues are: iter, symtab. */
613 lua_pushcclosure(L, &lupb_enumiter_next, 2);
614 return 1;
615 }
616
617 static const struct luaL_Reg lupb_enumdef_mm[] = {
618 {"__len", lupb_enumdef_len},
619 {NULL, NULL}
620 };
621
622 static const struct luaL_Reg lupb_enumdef_m[] = {
623 {"file", lupb_enumdef_file},
624 {"value", lupb_enumdef_value},
625 {"values", lupb_enumdef_values},
626 {NULL, NULL}
627 };
628
629
630 /* lupb_enumvaldef ************************************************************/
631
lupb_enumvaldef_check(lua_State * L,int narg)632 const upb_enumvaldef *lupb_enumvaldef_check(lua_State *L, int narg) {
633 return lupb_wrapper_check(L, narg, LUPB_ENUMVALDEF);
634 }
635
lupb_enumvaldef_enum(lua_State * L)636 static int lupb_enumvaldef_enum(lua_State *L) {
637 const upb_enumvaldef *ev = lupb_enumvaldef_check(L, 1);
638 const upb_enumdef *e = upb_enumvaldef_enum(ev);
639 lupb_wrapper_pushwrapper(L, 1, e, LUPB_ENUMDEF);
640 return 1;
641 }
642
lupb_enumvaldef_fullname(lua_State * L)643 static int lupb_enumvaldef_fullname(lua_State *L) {
644 const upb_enumvaldef *ev = lupb_enumvaldef_check(L, 1);
645 lua_pushstring(L, upb_enumvaldef_fullname(ev));
646 return 1;
647 }
648
lupb_enumvaldef_name(lua_State * L)649 static int lupb_enumvaldef_name(lua_State *L) {
650 const upb_enumvaldef *ev = lupb_enumvaldef_check(L, 1);
651 lua_pushstring(L, upb_enumvaldef_name(ev));
652 return 1;
653 }
654
lupb_enumvaldef_number(lua_State * L)655 static int lupb_enumvaldef_number(lua_State *L) {
656 const upb_enumvaldef *ev = lupb_enumvaldef_check(L, 1);
657 lupb_pushint32(L, upb_enumvaldef_number(ev));
658 return 1;
659 }
660
661 static const struct luaL_Reg lupb_enumvaldef_m[] = {
662 {"enum", lupb_enumvaldef_enum},
663 {"full_name", lupb_enumvaldef_fullname},
664 {"name", lupb_enumvaldef_name},
665 {"number", lupb_enumvaldef_number},
666 {NULL, NULL}
667 };
668
669 /* lupb_filedef ***************************************************************/
670
lupb_filedef_check(lua_State * L,int narg)671 const upb_filedef *lupb_filedef_check(lua_State *L, int narg) {
672 return lupb_wrapper_check(L, narg, LUPB_FILEDEF);
673 }
674
lupb_filedef_dep(lua_State * L)675 static int lupb_filedef_dep(lua_State *L) {
676 const upb_filedef *f = lupb_filedef_check(L, 1);
677 int index = luaL_checkint(L, 2);
678 const upb_filedef *dep = upb_filedef_dep(f, index);
679 lupb_wrapper_pushwrapper(L, 1, dep, LUPB_FILEDEF);
680 return 1;
681 }
682
lupb_filedef_depcount(lua_State * L)683 static int lupb_filedef_depcount(lua_State *L) {
684 const upb_filedef *f = lupb_filedef_check(L, 1);
685 lua_pushnumber(L, upb_filedef_depcount(f));
686 return 1;
687 }
688
lupb_filedef_enum(lua_State * L)689 static int lupb_filedef_enum(lua_State *L) {
690 const upb_filedef *f = lupb_filedef_check(L, 1);
691 int index = luaL_checkint(L, 2);
692 const upb_enumdef *e = upb_filedef_enum(f, index);
693 lupb_wrapper_pushwrapper(L, 1, e, LUPB_ENUMDEF);
694 return 1;
695 }
696
lupb_filedef_enumcount(lua_State * L)697 static int lupb_filedef_enumcount(lua_State *L) {
698 const upb_filedef *f = lupb_filedef_check(L, 1);
699 lua_pushnumber(L, upb_filedef_enumcount(f));
700 return 1;
701 }
702
lupb_filedef_msg(lua_State * L)703 static int lupb_filedef_msg(lua_State *L) {
704 const upb_filedef *f = lupb_filedef_check(L, 1);
705 int index = luaL_checkint(L, 2);
706 const upb_msgdef *m = upb_filedef_msg(f, index);
707 lupb_wrapper_pushwrapper(L, 1, m, LUPB_MSGDEF);
708 return 1;
709 }
710
lupb_filedef_msgcount(lua_State * L)711 static int lupb_filedef_msgcount(lua_State *L) {
712 const upb_filedef *f = lupb_filedef_check(L, 1);
713 lua_pushnumber(L, upb_filedef_msgcount(f));
714 return 1;
715 }
716
lupb_filedef_name(lua_State * L)717 static int lupb_filedef_name(lua_State *L) {
718 const upb_filedef *f = lupb_filedef_check(L, 1);
719 lua_pushstring(L, upb_filedef_name(f));
720 return 1;
721 }
722
lupb_filedef_package(lua_State * L)723 static int lupb_filedef_package(lua_State *L) {
724 const upb_filedef *f = lupb_filedef_check(L, 1);
725 lua_pushstring(L, upb_filedef_package(f));
726 return 1;
727 }
728
lupb_filedef_symtab(lua_State * L)729 static int lupb_filedef_symtab(lua_State *L) {
730 const upb_filedef *f = lupb_filedef_check(L, 1);
731 const upb_symtab *symtab = upb_filedef_symtab(f);
732 lupb_wrapper_pushwrapper(L, 1, symtab, LUPB_SYMTAB);
733 return 1;
734 }
735
lupb_filedef_syntax(lua_State * L)736 static int lupb_filedef_syntax(lua_State *L) {
737 const upb_filedef *f = lupb_filedef_check(L, 1);
738 lua_pushnumber(L, upb_filedef_syntax(f));
739 return 1;
740 }
741
742 static const struct luaL_Reg lupb_filedef_m[] = {
743 {"dep", lupb_filedef_dep},
744 {"depcount", lupb_filedef_depcount},
745 {"enum", lupb_filedef_enum},
746 {"enumcount", lupb_filedef_enumcount},
747 {"msg", lupb_filedef_msg},
748 {"msgcount", lupb_filedef_msgcount},
749 {"name", lupb_filedef_name},
750 {"package", lupb_filedef_package},
751 {"symtab", lupb_filedef_symtab},
752 {"syntax", lupb_filedef_syntax},
753 {NULL, NULL}
754 };
755
756
757 /* lupb_symtab ****************************************************************/
758
759 /* The symtab owns all defs. Thus GC-rooting the symtab ensures that all
760 * underlying defs stay alive.
761 *
762 * The symtab's userval is a cache of def* -> object. */
763
764 #define LUPB_CACHE_INDEX 1
765
766 typedef struct {
767 upb_symtab *symtab;
768 } lupb_symtab;
769
lupb_symtab_check(lua_State * L,int narg)770 upb_symtab *lupb_symtab_check(lua_State *L, int narg) {
771 lupb_symtab *lsymtab = luaL_checkudata(L, narg, LUPB_SYMTAB);
772 if (!lsymtab->symtab) {
773 luaL_error(L, "called into dead object");
774 }
775 return lsymtab->symtab;
776 }
777
lupb_symtab_pushwrapper(lua_State * L,int narg,const void * def,const char * type)778 void lupb_symtab_pushwrapper(lua_State *L, int narg, const void *def,
779 const char *type) {
780 narg = lua_absindex(L, narg);
781 assert(luaL_testudata(L, narg, LUPB_SYMTAB));
782
783 if (def == NULL) {
784 lua_pushnil(L);
785 return;
786 }
787
788 lua_getiuservalue(L, narg, LUPB_CACHE_INDEX); /* Get cache. */
789
790 /* Index by "def" pointer. */
791 lua_rawgetp(L, -1, def);
792
793 /* Stack is now: cache, cached value. */
794 if (lua_isnil(L, -1)) {
795 /* Create new wrapper. */
796 lupb_wrapper *w = lupb_newuserdata(L, sizeof(*w), 1, type);
797 w->def = def;
798 lua_replace(L, -2); /* Replace nil */
799
800 /* Set symtab as userval. */
801 lua_pushvalue(L, narg);
802 lua_setiuservalue(L, -2, LUPB_SYMTAB_INDEX);
803
804 /* Add wrapper to the the cache. */
805 lua_pushvalue(L, -1);
806 lua_rawsetp(L, -3, def);
807 }
808
809 lua_replace(L, -2); /* Remove cache, leaving only the wrapper. */
810 }
811
812 /* upb_symtab_new()
813 *
814 * Handles:
815 * upb.SymbolTable() -> <new instance>
816 */
lupb_symtab_new(lua_State * L)817 static int lupb_symtab_new(lua_State *L) {
818 lupb_symtab *lsymtab = lupb_newuserdata(L, sizeof(*lsymtab), 1, LUPB_SYMTAB);
819 lsymtab->symtab = upb_symtab_new();
820
821 /* Create our object cache. */
822 lua_newtable(L);
823
824 /* Cache metatable: specifies that values are weak. */
825 lua_createtable(L, 0, 1);
826 lua_pushstring(L, "v");
827 lua_setfield(L, -2, "__mode");
828 lua_setmetatable(L, -2);
829
830 /* Put the symtab itself in the cache metatable. */
831 lua_pushvalue(L, -2);
832 lua_rawsetp(L, -2, lsymtab->symtab);
833
834 /* Set the cache as our userval. */
835 lua_setiuservalue(L, -2, LUPB_CACHE_INDEX);
836
837 return 1;
838 }
839
lupb_symtab_gc(lua_State * L)840 static int lupb_symtab_gc(lua_State *L) {
841 lupb_symtab *lsymtab = luaL_checkudata(L, 1, LUPB_SYMTAB);
842 upb_symtab_free(lsymtab->symtab);
843 lsymtab->symtab = NULL;
844 return 0;
845 }
846
lupb_symtab_addfile(lua_State * L)847 static int lupb_symtab_addfile(lua_State *L) {
848 size_t len;
849 upb_symtab *s = lupb_symtab_check(L, 1);
850 const char *str = luaL_checklstring(L, 2, &len);
851 upb_arena *arena = lupb_arena_pushnew(L);
852 const google_protobuf_FileDescriptorProto *file;
853 const upb_filedef *file_def;
854 upb_status status;
855
856 upb_status_clear(&status);
857 file = google_protobuf_FileDescriptorProto_parse(str, len, arena);
858
859 if (!file) {
860 luaL_argerror(L, 2, "failed to parse descriptor");
861 }
862
863 file_def = upb_symtab_addfile(s, file, &status);
864 lupb_checkstatus(L, &status);
865
866 lupb_symtab_pushwrapper(L, 1, file_def, LUPB_FILEDEF);
867
868 return 1;
869 }
870
lupb_symtab_addset(lua_State * L)871 static int lupb_symtab_addset(lua_State *L) {
872 size_t i, n, len;
873 const google_protobuf_FileDescriptorProto *const *files;
874 google_protobuf_FileDescriptorSet *set;
875 upb_symtab *s = lupb_symtab_check(L, 1);
876 const char *str = luaL_checklstring(L, 2, &len);
877 upb_arena *arena = lupb_arena_pushnew(L);
878 upb_status status;
879
880 upb_status_clear(&status);
881 set = google_protobuf_FileDescriptorSet_parse(str, len, arena);
882
883 if (!set) {
884 luaL_argerror(L, 2, "failed to parse descriptor");
885 }
886
887 files = google_protobuf_FileDescriptorSet_file(set, &n);
888 for (i = 0; i < n; i++) {
889 upb_symtab_addfile(s, files[i], &status);
890 lupb_checkstatus(L, &status);
891 }
892
893 return 0;
894 }
895
lupb_symtab_lookupmsg(lua_State * L)896 static int lupb_symtab_lookupmsg(lua_State *L) {
897 const upb_symtab *s = lupb_symtab_check(L, 1);
898 const upb_msgdef *m = upb_symtab_lookupmsg(s, luaL_checkstring(L, 2));
899 lupb_symtab_pushwrapper(L, 1, m, LUPB_MSGDEF);
900 return 1;
901 }
902
lupb_symtab_lookupenum(lua_State * L)903 static int lupb_symtab_lookupenum(lua_State *L) {
904 const upb_symtab *s = lupb_symtab_check(L, 1);
905 const upb_enumdef *e = upb_symtab_lookupenum(s, luaL_checkstring(L, 2));
906 lupb_symtab_pushwrapper(L, 1, e, LUPB_ENUMDEF);
907 return 1;
908 }
909
lupb_symtab_lookupenumval(lua_State * L)910 static int lupb_symtab_lookupenumval(lua_State *L) {
911 const upb_symtab *s = lupb_symtab_check(L, 1);
912 const upb_enumvaldef *e = upb_symtab_lookupenumval(s, luaL_checkstring(L, 2));
913 lupb_symtab_pushwrapper(L, 1, e, LUPB_ENUMVALDEF);
914 return 1;
915 }
916
lupb_symtab_tostring(lua_State * L)917 static int lupb_symtab_tostring(lua_State *L) {
918 const upb_symtab *s = lupb_symtab_check(L, 1);
919 lua_pushfstring(L, "<upb.SymbolTable file_count=%d>",
920 (int)upb_symtab_filecount(s));
921 return 1;
922 }
923
924 static const struct luaL_Reg lupb_symtab_m[] = {
925 {"add_file", lupb_symtab_addfile},
926 {"add_set", lupb_symtab_addset},
927 {"lookup_msg", lupb_symtab_lookupmsg},
928 {"lookup_enum", lupb_symtab_lookupenum},
929 {"lookup_enumval", lupb_symtab_lookupenumval},
930 {NULL, NULL}
931 };
932
933 static const struct luaL_Reg lupb_symtab_mm[] = {
934 {"__gc", lupb_symtab_gc},
935 {"__tostring", lupb_symtab_tostring},
936 {NULL, NULL}
937 };
938
939 /* lupb toplevel **************************************************************/
940
lupb_setfieldi(lua_State * L,const char * field,int i)941 static void lupb_setfieldi(lua_State *L, const char *field, int i) {
942 lua_pushinteger(L, i);
943 lua_setfield(L, -2, field);
944 }
945
946 static const struct luaL_Reg lupbdef_toplevel_m[] = {
947 {"SymbolTable", lupb_symtab_new},
948 {NULL, NULL}
949 };
950
lupb_def_registertypes(lua_State * L)951 void lupb_def_registertypes(lua_State *L) {
952 lupb_setfuncs(L, lupbdef_toplevel_m);
953
954 /* Register types. */
955 lupb_register_type(L, LUPB_ENUMDEF, lupb_enumdef_m, lupb_enumdef_mm);
956 lupb_register_type(L, LUPB_ENUMVALDEF, lupb_enumvaldef_m, NULL);
957 lupb_register_type(L, LUPB_FIELDDEF, lupb_fielddef_m, NULL);
958 lupb_register_type(L, LUPB_FILEDEF, lupb_filedef_m, NULL);
959 lupb_register_type(L, LUPB_MSGDEF, lupb_msgdef_m, lupb_msgdef_mm);
960 lupb_register_type(L, LUPB_ONEOFDEF, lupb_oneofdef_m, lupb_oneofdef_mm);
961 lupb_register_type(L, LUPB_SYMTAB, lupb_symtab_m, lupb_symtab_mm);
962
963 /* Register constants. */
964 lupb_setfieldi(L, "LABEL_OPTIONAL", UPB_LABEL_OPTIONAL);
965 lupb_setfieldi(L, "LABEL_REQUIRED", UPB_LABEL_REQUIRED);
966 lupb_setfieldi(L, "LABEL_REPEATED", UPB_LABEL_REPEATED);
967
968 lupb_setfieldi(L, "TYPE_DOUBLE", UPB_TYPE_DOUBLE);
969 lupb_setfieldi(L, "TYPE_FLOAT", UPB_TYPE_FLOAT);
970 lupb_setfieldi(L, "TYPE_INT64", UPB_TYPE_INT64);
971 lupb_setfieldi(L, "TYPE_UINT64", UPB_TYPE_UINT64);
972 lupb_setfieldi(L, "TYPE_INT32", UPB_TYPE_INT32);
973 lupb_setfieldi(L, "TYPE_BOOL", UPB_TYPE_BOOL);
974 lupb_setfieldi(L, "TYPE_STRING", UPB_TYPE_STRING);
975 lupb_setfieldi(L, "TYPE_MESSAGE", UPB_TYPE_MESSAGE);
976 lupb_setfieldi(L, "TYPE_BYTES", UPB_TYPE_BYTES);
977 lupb_setfieldi(L, "TYPE_UINT32", UPB_TYPE_UINT32);
978 lupb_setfieldi(L, "TYPE_ENUM", UPB_TYPE_ENUM);
979
980 lupb_setfieldi(L, "DESCRIPTOR_TYPE_DOUBLE", UPB_DESCRIPTOR_TYPE_DOUBLE);
981 lupb_setfieldi(L, "DESCRIPTOR_TYPE_FLOAT", UPB_DESCRIPTOR_TYPE_FLOAT);
982 lupb_setfieldi(L, "DESCRIPTOR_TYPE_INT64", UPB_DESCRIPTOR_TYPE_INT64);
983 lupb_setfieldi(L, "DESCRIPTOR_TYPE_UINT64", UPB_DESCRIPTOR_TYPE_UINT64);
984 lupb_setfieldi(L, "DESCRIPTOR_TYPE_INT32", UPB_DESCRIPTOR_TYPE_INT32);
985 lupb_setfieldi(L, "DESCRIPTOR_TYPE_FIXED64", UPB_DESCRIPTOR_TYPE_FIXED64);
986 lupb_setfieldi(L, "DESCRIPTOR_TYPE_FIXED32", UPB_DESCRIPTOR_TYPE_FIXED32);
987 lupb_setfieldi(L, "DESCRIPTOR_TYPE_BOOL", UPB_DESCRIPTOR_TYPE_BOOL);
988 lupb_setfieldi(L, "DESCRIPTOR_TYPE_STRING", UPB_DESCRIPTOR_TYPE_STRING);
989 lupb_setfieldi(L, "DESCRIPTOR_TYPE_GROUP", UPB_DESCRIPTOR_TYPE_GROUP);
990 lupb_setfieldi(L, "DESCRIPTOR_TYPE_MESSAGE", UPB_DESCRIPTOR_TYPE_MESSAGE);
991 lupb_setfieldi(L, "DESCRIPTOR_TYPE_BYTES", UPB_DESCRIPTOR_TYPE_BYTES);
992 lupb_setfieldi(L, "DESCRIPTOR_TYPE_UINT32", UPB_DESCRIPTOR_TYPE_UINT32);
993 lupb_setfieldi(L, "DESCRIPTOR_TYPE_ENUM", UPB_DESCRIPTOR_TYPE_ENUM);
994 lupb_setfieldi(L, "DESCRIPTOR_TYPE_SFIXED32", UPB_DESCRIPTOR_TYPE_SFIXED32);
995 lupb_setfieldi(L, "DESCRIPTOR_TYPE_SFIXED64", UPB_DESCRIPTOR_TYPE_SFIXED64);
996 lupb_setfieldi(L, "DESCRIPTOR_TYPE_SINT32", UPB_DESCRIPTOR_TYPE_SINT32);
997 lupb_setfieldi(L, "DESCRIPTOR_TYPE_SINT64", UPB_DESCRIPTOR_TYPE_SINT64);
998
999 lupb_setfieldi(L, "SYNTAX_PROTO2", UPB_SYNTAX_PROTO2);
1000 lupb_setfieldi(L, "SYNTAX_PROTO3", UPB_SYNTAX_PROTO3);
1001 }
1002