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