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"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20  * 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 "upb/reflection/def.h"
29 
30 #include <float.h>
31 #include <math.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #include "lauxlib.h"
36 #include "lua/upb.h"
37 #include "upb/reflection.h"
38 
39 #define LUPB_ENUMDEF "lupb.enumdef"
40 #define LUPB_ENUMVALDEF "lupb.enumvaldef"
41 #define LUPB_FIELDDEF "lupb.fielddef"
42 #define LUPB_FILEDEF "lupb.filedef"
43 #define LUPB_MSGDEF "lupb.msgdef"
44 #define LUPB_ONEOFDEF "lupb.oneof"
45 #define LUPB_SYMTAB "lupb.defpool"
46 #define LUPB_OBJCACHE "lupb.objcache"
47 
48 static void lupb_DefPool_pushwrapper(lua_State* L, int narg, const void* def,
49                                      const char* type);
50 
51 /* lupb_wrapper ***************************************************************/
52 
53 /* Wrappers around upb def objects.  The userval contains a reference to the
54  * defpool. */
55 
56 #define LUPB_SYMTAB_INDEX 1
57 
58 typedef struct {
59   const void* def; /* upb_MessageDef, upb_EnumDef, upb_OneofDef, etc. */
60 } lupb_wrapper;
61 
lupb_wrapper_check(lua_State * L,int narg,const char * type)62 static const void* lupb_wrapper_check(lua_State* L, int narg,
63                                       const char* type) {
64   lupb_wrapper* w = luaL_checkudata(L, narg, type);
65   return w->def;
66 }
67 
lupb_wrapper_pushdefpool(lua_State * L,int narg)68 static void lupb_wrapper_pushdefpool(lua_State* L, int narg) {
69   lua_getiuservalue(L, narg, LUPB_SYMTAB_INDEX);
70 }
71 
72 /* lupb_wrapper_pushwrapper()
73  *
74  * For a given def wrapper at index |narg|, pushes a wrapper for the given |def|
75  * and the given |type|.  The new wrapper will be part of the same defpool. */
lupb_wrapper_pushwrapper(lua_State * L,int narg,const void * def,const char * type)76 static void lupb_wrapper_pushwrapper(lua_State* L, int narg, const void* def,
77                                      const char* type) {
78   lupb_wrapper_pushdefpool(L, narg);
79   lupb_DefPool_pushwrapper(L, -1, def, type);
80   lua_replace(L, -2); /* Remove defpool from stack. */
81 }
82 
83 /* lupb_MessageDef_pushsubmsgdef()
84  *
85  * Pops the msgdef wrapper at the top of the stack and replaces it with a msgdef
86  * wrapper for field |f| of this msgdef (submsg may not be direct, for example
87  * it may be the submessage of the map value).
88  */
lupb_MessageDef_pushsubmsgdef(lua_State * L,const upb_FieldDef * f)89 void lupb_MessageDef_pushsubmsgdef(lua_State* L, const upb_FieldDef* f) {
90   const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f);
91   assert(m);
92   lupb_wrapper_pushwrapper(L, -1, m, LUPB_MSGDEF);
93   lua_replace(L, -2); /* Replace msgdef with submsgdef. */
94 }
95 
96 /* lupb_FieldDef **************************************************************/
97 
lupb_FieldDef_check(lua_State * L,int narg)98 const upb_FieldDef* lupb_FieldDef_check(lua_State* L, int narg) {
99   return lupb_wrapper_check(L, narg, LUPB_FIELDDEF);
100 }
101 
lupb_FieldDef_ContainingOneof(lua_State * L)102 static int lupb_FieldDef_ContainingOneof(lua_State* L) {
103   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
104   const upb_OneofDef* o = upb_FieldDef_ContainingOneof(f);
105   lupb_wrapper_pushwrapper(L, 1, o, LUPB_ONEOFDEF);
106   return 1;
107 }
108 
lupb_FieldDef_ContainingType(lua_State * L)109 static int lupb_FieldDef_ContainingType(lua_State* L) {
110   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
111   const upb_MessageDef* m = upb_FieldDef_ContainingType(f);
112   lupb_wrapper_pushwrapper(L, 1, m, LUPB_MSGDEF);
113   return 1;
114 }
115 
lupb_FieldDef_Default(lua_State * L)116 static int lupb_FieldDef_Default(lua_State* L) {
117   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
118   upb_CType type = upb_FieldDef_CType(f);
119   if (type == kUpb_CType_Message) {
120     return luaL_error(L, "Message fields do not have explicit defaults.");
121   }
122   lupb_pushmsgval(L, 0, type, upb_FieldDef_Default(f));
123   return 1;
124 }
125 
lupb_FieldDef_Type(lua_State * L)126 static int lupb_FieldDef_Type(lua_State* L) {
127   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
128   lua_pushnumber(L, upb_FieldDef_Type(f));
129   return 1;
130 }
131 
lupb_FieldDef_HasSubDef(lua_State * L)132 static int lupb_FieldDef_HasSubDef(lua_State* L) {
133   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
134   lua_pushboolean(L, upb_FieldDef_HasSubDef(f));
135   return 1;
136 }
137 
lupb_FieldDef_Index(lua_State * L)138 static int lupb_FieldDef_Index(lua_State* L) {
139   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
140   lua_pushinteger(L, upb_FieldDef_Index(f));
141   return 1;
142 }
143 
lupb_FieldDef_IsExtension(lua_State * L)144 static int lupb_FieldDef_IsExtension(lua_State* L) {
145   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
146   lua_pushboolean(L, upb_FieldDef_IsExtension(f));
147   return 1;
148 }
149 
lupb_FieldDef_Label(lua_State * L)150 static int lupb_FieldDef_Label(lua_State* L) {
151   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
152   lua_pushinteger(L, upb_FieldDef_Label(f));
153   return 1;
154 }
155 
lupb_FieldDef_Name(lua_State * L)156 static int lupb_FieldDef_Name(lua_State* L) {
157   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
158   lua_pushstring(L, upb_FieldDef_Name(f));
159   return 1;
160 }
161 
lupb_FieldDef_Number(lua_State * L)162 static int lupb_FieldDef_Number(lua_State* L) {
163   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
164   int32_t num = upb_FieldDef_Number(f);
165   if (num) {
166     lua_pushinteger(L, num);
167   } else {
168     lua_pushnil(L);
169   }
170   return 1;
171 }
172 
lupb_FieldDef_IsPacked(lua_State * L)173 static int lupb_FieldDef_IsPacked(lua_State* L) {
174   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
175   lua_pushboolean(L, upb_FieldDef_IsPacked(f));
176   return 1;
177 }
178 
lupb_FieldDef_MessageSubDef(lua_State * L)179 static int lupb_FieldDef_MessageSubDef(lua_State* L) {
180   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
181   const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f);
182   lupb_wrapper_pushwrapper(L, 1, m, LUPB_MSGDEF);
183   return 1;
184 }
185 
lupb_FieldDef_EnumSubDef(lua_State * L)186 static int lupb_FieldDef_EnumSubDef(lua_State* L) {
187   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
188   const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f);
189   lupb_wrapper_pushwrapper(L, 1, e, LUPB_ENUMDEF);
190   return 1;
191 }
192 
lupb_FieldDef_CType(lua_State * L)193 static int lupb_FieldDef_CType(lua_State* L) {
194   const upb_FieldDef* f = lupb_FieldDef_check(L, 1);
195   lua_pushinteger(L, upb_FieldDef_CType(f));
196   return 1;
197 }
198 
199 static const struct luaL_Reg lupb_FieldDef_m[] = {
200     {"containing_oneof", lupb_FieldDef_ContainingOneof},
201     {"containing_type", lupb_FieldDef_ContainingType},
202     {"default", lupb_FieldDef_Default},
203     {"descriptor_type", lupb_FieldDef_Type},
204     {"has_subdef", lupb_FieldDef_HasSubDef},
205     {"index", lupb_FieldDef_Index},
206     {"is_extension", lupb_FieldDef_IsExtension},
207     {"label", lupb_FieldDef_Label},
208     {"name", lupb_FieldDef_Name},
209     {"number", lupb_FieldDef_Number},
210     {"packed", lupb_FieldDef_IsPacked},
211     {"msgsubdef", lupb_FieldDef_MessageSubDef},
212     {"enumsubdef", lupb_FieldDef_EnumSubDef},
213     {"type", lupb_FieldDef_CType},
214     {NULL, NULL}};
215 
216 /* lupb_OneofDef **************************************************************/
217 
lupb_OneofDef_check(lua_State * L,int narg)218 const upb_OneofDef* lupb_OneofDef_check(lua_State* L, int narg) {
219   return lupb_wrapper_check(L, narg, LUPB_ONEOFDEF);
220 }
221 
lupb_OneofDef_ContainingType(lua_State * L)222 static int lupb_OneofDef_ContainingType(lua_State* L) {
223   const upb_OneofDef* o = lupb_OneofDef_check(L, 1);
224   const upb_MessageDef* m = upb_OneofDef_ContainingType(o);
225   lupb_wrapper_pushwrapper(L, 1, m, LUPB_MSGDEF);
226   return 1;
227 }
228 
lupb_OneofDef_Field(lua_State * L)229 static int lupb_OneofDef_Field(lua_State* L) {
230   const upb_OneofDef* o = lupb_OneofDef_check(L, 1);
231   int32_t idx = lupb_checkint32(L, 2);
232   int count = upb_OneofDef_FieldCount(o);
233 
234   if (idx < 0 || idx >= count) {
235     const char* msg =
236         lua_pushfstring(L, "index %d exceeds field count %d", idx, count);
237     return luaL_argerror(L, 2, msg);
238   }
239 
240   lupb_wrapper_pushwrapper(L, 1, upb_OneofDef_Field(o, idx), LUPB_FIELDDEF);
241   return 1;
242 }
243 
lupb_oneofiter_next(lua_State * L)244 static int lupb_oneofiter_next(lua_State* L) {
245   const upb_OneofDef* o = lupb_OneofDef_check(L, lua_upvalueindex(1));
246   int* index = lua_touserdata(L, lua_upvalueindex(2));
247   const upb_FieldDef* f;
248   if (*index == upb_OneofDef_FieldCount(o)) return 0;
249   f = upb_OneofDef_Field(o, (*index)++);
250   lupb_wrapper_pushwrapper(L, lua_upvalueindex(1), f, LUPB_FIELDDEF);
251   return 1;
252 }
253 
lupb_OneofDef_Fields(lua_State * L)254 static int lupb_OneofDef_Fields(lua_State* L) {
255   int* index = lua_newuserdata(L, sizeof(int));
256   lupb_OneofDef_check(L, 1);
257   *index = 0;
258 
259   /* Closure upvalues are: oneofdef, index. */
260   lua_pushcclosure(L, &lupb_oneofiter_next, 2);
261   return 1;
262 }
263 
lupb_OneofDef_len(lua_State * L)264 static int lupb_OneofDef_len(lua_State* L) {
265   const upb_OneofDef* o = lupb_OneofDef_check(L, 1);
266   lua_pushinteger(L, upb_OneofDef_FieldCount(o));
267   return 1;
268 }
269 
270 /* lupb_OneofDef_lookupfield()
271  *
272  * Handles:
273  *   oneof.lookup_field(field_number)
274  *   oneof.lookup_field(field_name)
275  */
lupb_OneofDef_lookupfield(lua_State * L)276 static int lupb_OneofDef_lookupfield(lua_State* L) {
277   const upb_OneofDef* o = lupb_OneofDef_check(L, 1);
278   const upb_FieldDef* f;
279 
280   switch (lua_type(L, 2)) {
281     case LUA_TNUMBER:
282       f = upb_OneofDef_LookupNumber(o, lua_tointeger(L, 2));
283       break;
284     case LUA_TSTRING:
285       f = upb_OneofDef_LookupName(o, lua_tostring(L, 2));
286       break;
287     default: {
288       const char* msg = lua_pushfstring(L, "number or string expected, got %s",
289                                         luaL_typename(L, 2));
290       return luaL_argerror(L, 2, msg);
291     }
292   }
293 
294   lupb_wrapper_pushwrapper(L, 1, f, LUPB_FIELDDEF);
295   return 1;
296 }
297 
lupb_OneofDef_Name(lua_State * L)298 static int lupb_OneofDef_Name(lua_State* L) {
299   const upb_OneofDef* o = lupb_OneofDef_check(L, 1);
300   lua_pushstring(L, upb_OneofDef_Name(o));
301   return 1;
302 }
303 
304 static const struct luaL_Reg lupb_OneofDef_m[] = {
305     {"containing_type", lupb_OneofDef_ContainingType},
306     {"field", lupb_OneofDef_Field},
307     {"fields", lupb_OneofDef_Fields},
308     {"lookup_field", lupb_OneofDef_lookupfield},
309     {"name", lupb_OneofDef_Name},
310     {NULL, NULL}};
311 
312 static const struct luaL_Reg lupb_OneofDef_mm[] = {{"__len", lupb_OneofDef_len},
313                                                    {NULL, NULL}};
314 
315 /* lupb_MessageDef
316  * ****************************************************************/
317 
318 typedef struct {
319   const upb_MessageDef* md;
320 } lupb_MessageDef;
321 
lupb_MessageDef_check(lua_State * L,int narg)322 const upb_MessageDef* lupb_MessageDef_check(lua_State* L, int narg) {
323   return lupb_wrapper_check(L, narg, LUPB_MSGDEF);
324 }
325 
lupb_MessageDef_FieldCount(lua_State * L)326 static int lupb_MessageDef_FieldCount(lua_State* L) {
327   const upb_MessageDef* m = lupb_MessageDef_check(L, 1);
328   lua_pushinteger(L, upb_MessageDef_FieldCount(m));
329   return 1;
330 }
331 
lupb_MessageDef_OneofCount(lua_State * L)332 static int lupb_MessageDef_OneofCount(lua_State* L) {
333   const upb_MessageDef* m = lupb_MessageDef_check(L, 1);
334   lua_pushinteger(L, upb_MessageDef_OneofCount(m));
335   return 1;
336 }
337 
lupb_MessageDef_pushnested(lua_State * L,int msgdef,int name)338 static bool lupb_MessageDef_pushnested(lua_State* L, int msgdef, int name) {
339   const upb_MessageDef* m = lupb_MessageDef_check(L, msgdef);
340   lupb_wrapper_pushdefpool(L, msgdef);
341   upb_DefPool* defpool = lupb_DefPool_check(L, -1);
342   lua_pop(L, 1);
343 
344   /* Construct full package.Message.SubMessage name. */
345   lua_pushstring(L, upb_MessageDef_FullName(m));
346   lua_pushstring(L, ".");
347   lua_pushvalue(L, name);
348   lua_concat(L, 3);
349   const char* nested_name = lua_tostring(L, -1);
350 
351   /* Try lookup. */
352   const upb_MessageDef* nested =
353       upb_DefPool_FindMessageByName(defpool, nested_name);
354   if (!nested) return false;
355   lupb_wrapper_pushwrapper(L, msgdef, nested, LUPB_MSGDEF);
356   return true;
357 }
358 
359 /* lupb_MessageDef_Field()
360  *
361  * Handles:
362  *   msg.field(field_number) -> fielddef
363  *   msg.field(field_name) -> fielddef
364  */
lupb_MessageDef_Field(lua_State * L)365 static int lupb_MessageDef_Field(lua_State* L) {
366   const upb_MessageDef* m = lupb_MessageDef_check(L, 1);
367   const upb_FieldDef* f;
368 
369   switch (lua_type(L, 2)) {
370     case LUA_TNUMBER:
371       f = upb_MessageDef_FindFieldByNumber(m, lua_tointeger(L, 2));
372       break;
373     case LUA_TSTRING:
374       f = upb_MessageDef_FindFieldByName(m, lua_tostring(L, 2));
375       break;
376     default: {
377       const char* msg = lua_pushfstring(L, "number or string expected, got %s",
378                                         luaL_typename(L, 2));
379       return luaL_argerror(L, 2, msg);
380     }
381   }
382 
383   lupb_wrapper_pushwrapper(L, 1, f, LUPB_FIELDDEF);
384   return 1;
385 }
386 
387 /* lupb_MessageDef_FindByNameWithSize()
388  *
389  * Handles:
390  *   msg.lookup_name(name) -> fielddef or oneofdef
391  */
lupb_MessageDef_FindByNameWithSize(lua_State * L)392 static int lupb_MessageDef_FindByNameWithSize(lua_State* L) {
393   const upb_MessageDef* m = lupb_MessageDef_check(L, 1);
394   const upb_FieldDef* f;
395   const upb_OneofDef* o;
396 
397   if (!upb_MessageDef_FindByName(m, lua_tostring(L, 2), &f, &o)) {
398     lua_pushnil(L);
399   } else if (o) {
400     lupb_wrapper_pushwrapper(L, 1, o, LUPB_ONEOFDEF);
401   } else {
402     lupb_wrapper_pushwrapper(L, 1, f, LUPB_FIELDDEF);
403   }
404 
405   return 1;
406 }
407 
408 /* lupb_MessageDef_Name()
409  *
410  * Handles:
411  *   msg.name() -> string
412  */
lupb_MessageDef_Name(lua_State * L)413 static int lupb_MessageDef_Name(lua_State* L) {
414   const upb_MessageDef* m = lupb_MessageDef_check(L, 1);
415   lua_pushstring(L, upb_MessageDef_Name(m));
416   return 1;
417 }
418 
lupb_msgfielditer_next(lua_State * L)419 static int lupb_msgfielditer_next(lua_State* L) {
420   const upb_MessageDef* m = lupb_MessageDef_check(L, lua_upvalueindex(1));
421   int* index = lua_touserdata(L, lua_upvalueindex(2));
422   const upb_FieldDef* f;
423   if (*index == upb_MessageDef_FieldCount(m)) return 0;
424   f = upb_MessageDef_Field(m, (*index)++);
425   lupb_wrapper_pushwrapper(L, lua_upvalueindex(1), f, LUPB_FIELDDEF);
426   return 1;
427 }
428 
lupb_MessageDef_Fields(lua_State * L)429 static int lupb_MessageDef_Fields(lua_State* L) {
430   int* index = lua_newuserdata(L, sizeof(int));
431   lupb_MessageDef_check(L, 1);
432   *index = 0;
433 
434   /* Closure upvalues are: msgdef, index. */
435   lua_pushcclosure(L, &lupb_msgfielditer_next, 2);
436   return 1;
437 }
438 
lupb_MessageDef_File(lua_State * L)439 static int lupb_MessageDef_File(lua_State* L) {
440   const upb_MessageDef* m = lupb_MessageDef_check(L, 1);
441   const upb_FileDef* file = upb_MessageDef_File(m);
442   lupb_wrapper_pushwrapper(L, 1, file, LUPB_FILEDEF);
443   return 1;
444 }
445 
lupb_MessageDef_FullName(lua_State * L)446 static int lupb_MessageDef_FullName(lua_State* L) {
447   const upb_MessageDef* m = lupb_MessageDef_check(L, 1);
448   lua_pushstring(L, upb_MessageDef_FullName(m));
449   return 1;
450 }
451 
lupb_MessageDef_index(lua_State * L)452 static int lupb_MessageDef_index(lua_State* L) {
453   if (!lupb_MessageDef_pushnested(L, 1, 2)) {
454     luaL_error(L, "No such nested message");
455   }
456   return 1;
457 }
458 
lupb_msgoneofiter_next(lua_State * L)459 static int lupb_msgoneofiter_next(lua_State* L) {
460   const upb_MessageDef* m = lupb_MessageDef_check(L, lua_upvalueindex(1));
461   int* index = lua_touserdata(L, lua_upvalueindex(2));
462   const upb_OneofDef* o;
463   if (*index == upb_MessageDef_OneofCount(m)) return 0;
464   o = upb_MessageDef_Oneof(m, (*index)++);
465   lupb_wrapper_pushwrapper(L, lua_upvalueindex(1), o, LUPB_ONEOFDEF);
466   return 1;
467 }
468 
lupb_MessageDef_Oneofs(lua_State * L)469 static int lupb_MessageDef_Oneofs(lua_State* L) {
470   int* index = lua_newuserdata(L, sizeof(int));
471   lupb_MessageDef_check(L, 1);
472   *index = 0;
473 
474   /* Closure upvalues are: msgdef, index. */
475   lua_pushcclosure(L, &lupb_msgoneofiter_next, 2);
476   return 1;
477 }
478 
lupb_MessageDef_IsMapEntry(lua_State * L)479 static int lupb_MessageDef_IsMapEntry(lua_State* L) {
480   const upb_MessageDef* m = lupb_MessageDef_check(L, 1);
481   lua_pushboolean(L, upb_MessageDef_IsMapEntry(m));
482   return 1;
483 }
484 
lupb_MessageDef_Syntax(lua_State * L)485 static int lupb_MessageDef_Syntax(lua_State* L) {
486   const upb_MessageDef* m = lupb_MessageDef_check(L, 1);
487   lua_pushinteger(L, upb_MessageDef_Syntax(m));
488   return 1;
489 }
490 
lupb_MessageDef_tostring(lua_State * L)491 static int lupb_MessageDef_tostring(lua_State* L) {
492   const upb_MessageDef* m = lupb_MessageDef_check(L, 1);
493   lua_pushfstring(L, "<upb.MessageDef name=%s, field_count=%d>",
494                   upb_MessageDef_FullName(m),
495                   (int)upb_MessageDef_FieldCount(m));
496   return 1;
497 }
498 
499 static const struct luaL_Reg lupb_MessageDef_mm[] = {
500     {"__call", lupb_MessageDef_call},
501     {"__index", lupb_MessageDef_index},
502     {"__len", lupb_MessageDef_FieldCount},
503     {"__tostring", lupb_MessageDef_tostring},
504     {NULL, NULL}};
505 
506 static const struct luaL_Reg lupb_MessageDef_m[] = {
507     {"field", lupb_MessageDef_Field},
508     {"fields", lupb_MessageDef_Fields},
509     {"field_count", lupb_MessageDef_FieldCount},
510     {"file", lupb_MessageDef_File},
511     {"full_name", lupb_MessageDef_FullName},
512     {"lookup_name", lupb_MessageDef_FindByNameWithSize},
513     {"name", lupb_MessageDef_Name},
514     {"oneof_count", lupb_MessageDef_OneofCount},
515     {"oneofs", lupb_MessageDef_Oneofs},
516     {"syntax", lupb_MessageDef_Syntax},
517     {"_map_entry", lupb_MessageDef_IsMapEntry},
518     {NULL, NULL}};
519 
520 /* lupb_EnumDef ***************************************************************/
521 
lupb_EnumDef_check(lua_State * L,int narg)522 const upb_EnumDef* lupb_EnumDef_check(lua_State* L, int narg) {
523   return lupb_wrapper_check(L, narg, LUPB_ENUMDEF);
524 }
525 
lupb_EnumDef_len(lua_State * L)526 static int lupb_EnumDef_len(lua_State* L) {
527   const upb_EnumDef* e = lupb_EnumDef_check(L, 1);
528   lua_pushinteger(L, upb_EnumDef_ValueCount(e));
529   return 1;
530 }
531 
lupb_EnumDef_File(lua_State * L)532 static int lupb_EnumDef_File(lua_State* L) {
533   const upb_EnumDef* e = lupb_EnumDef_check(L, 1);
534   const upb_FileDef* file = upb_EnumDef_File(e);
535   lupb_wrapper_pushwrapper(L, 1, file, LUPB_FILEDEF);
536   return 1;
537 }
538 
539 /* lupb_EnumDef_Value()
540  *
541  * Handles:
542  *   enum.value(number) -> enumval
543  *   enum.value(name) -> enumval
544  */
lupb_EnumDef_Value(lua_State * L)545 static int lupb_EnumDef_Value(lua_State* L) {
546   const upb_EnumDef* e = lupb_EnumDef_check(L, 1);
547   const upb_EnumValueDef* ev;
548 
549   switch (lua_type(L, 2)) {
550     case LUA_TNUMBER:
551       ev = upb_EnumDef_FindValueByNumber(e, lupb_checkint32(L, 2));
552       break;
553     case LUA_TSTRING:
554       ev = upb_EnumDef_FindValueByName(e, lua_tostring(L, 2));
555       break;
556     default: {
557       const char* msg = lua_pushfstring(L, "number or string expected, got %s",
558                                         luaL_typename(L, 2));
559       return luaL_argerror(L, 2, msg);
560     }
561   }
562 
563   lupb_wrapper_pushwrapper(L, 1, ev, LUPB_ENUMVALDEF);
564   return 1;
565 }
566 
567 static const struct luaL_Reg lupb_EnumDef_mm[] = {{"__len", lupb_EnumDef_len},
568                                                   {NULL, NULL}};
569 
570 static const struct luaL_Reg lupb_EnumDef_m[] = {
571     {"file", lupb_EnumDef_File}, {"value", lupb_EnumDef_Value}, {NULL, NULL}};
572 
573 /* lupb_EnumValueDef
574  * ************************************************************/
575 
lupb_enumvaldef_check(lua_State * L,int narg)576 const upb_EnumValueDef* lupb_enumvaldef_check(lua_State* L, int narg) {
577   return lupb_wrapper_check(L, narg, LUPB_ENUMVALDEF);
578 }
579 
lupb_EnumValueDef_Enum(lua_State * L)580 static int lupb_EnumValueDef_Enum(lua_State* L) {
581   const upb_EnumValueDef* ev = lupb_enumvaldef_check(L, 1);
582   const upb_EnumDef* e = upb_EnumValueDef_Enum(ev);
583   lupb_wrapper_pushwrapper(L, 1, e, LUPB_ENUMDEF);
584   return 1;
585 }
586 
lupb_EnumValueDef_FullName(lua_State * L)587 static int lupb_EnumValueDef_FullName(lua_State* L) {
588   const upb_EnumValueDef* ev = lupb_enumvaldef_check(L, 1);
589   lua_pushstring(L, upb_EnumValueDef_FullName(ev));
590   return 1;
591 }
592 
lupb_EnumValueDef_Name(lua_State * L)593 static int lupb_EnumValueDef_Name(lua_State* L) {
594   const upb_EnumValueDef* ev = lupb_enumvaldef_check(L, 1);
595   lua_pushstring(L, upb_EnumValueDef_Name(ev));
596   return 1;
597 }
598 
lupb_EnumValueDef_Number(lua_State * L)599 static int lupb_EnumValueDef_Number(lua_State* L) {
600   const upb_EnumValueDef* ev = lupb_enumvaldef_check(L, 1);
601   lupb_pushint32(L, upb_EnumValueDef_Number(ev));
602   return 1;
603 }
604 
605 static const struct luaL_Reg lupb_enumvaldef_m[] = {
606     {"enum", lupb_EnumValueDef_Enum},
607     {"full_name", lupb_EnumValueDef_FullName},
608     {"name", lupb_EnumValueDef_Name},
609     {"number", lupb_EnumValueDef_Number},
610     {NULL, NULL}};
611 
612 /* lupb_FileDef ***************************************************************/
613 
lupb_FileDef_check(lua_State * L,int narg)614 const upb_FileDef* lupb_FileDef_check(lua_State* L, int narg) {
615   return lupb_wrapper_check(L, narg, LUPB_FILEDEF);
616 }
617 
lupb_FileDef_Dependency(lua_State * L)618 static int lupb_FileDef_Dependency(lua_State* L) {
619   const upb_FileDef* f = lupb_FileDef_check(L, 1);
620   int index = luaL_checkint(L, 2);
621   const upb_FileDef* dep = upb_FileDef_Dependency(f, index);
622   lupb_wrapper_pushwrapper(L, 1, dep, LUPB_FILEDEF);
623   return 1;
624 }
625 
lupb_FileDef_DependencyCount(lua_State * L)626 static int lupb_FileDef_DependencyCount(lua_State* L) {
627   const upb_FileDef* f = lupb_FileDef_check(L, 1);
628   lua_pushnumber(L, upb_FileDef_DependencyCount(f));
629   return 1;
630 }
631 
lupb_FileDef_enum(lua_State * L)632 static int lupb_FileDef_enum(lua_State* L) {
633   const upb_FileDef* f = lupb_FileDef_check(L, 1);
634   int index = luaL_checkint(L, 2);
635   const upb_EnumDef* e = upb_FileDef_TopLevelEnum(f, index);
636   lupb_wrapper_pushwrapper(L, 1, e, LUPB_ENUMDEF);
637   return 1;
638 }
639 
lupb_FileDef_enumcount(lua_State * L)640 static int lupb_FileDef_enumcount(lua_State* L) {
641   const upb_FileDef* f = lupb_FileDef_check(L, 1);
642   lua_pushnumber(L, upb_FileDef_TopLevelEnumCount(f));
643   return 1;
644 }
645 
lupb_FileDef_msg(lua_State * L)646 static int lupb_FileDef_msg(lua_State* L) {
647   const upb_FileDef* f = lupb_FileDef_check(L, 1);
648   int index = luaL_checkint(L, 2);
649   const upb_MessageDef* m = upb_FileDef_TopLevelMessage(f, index);
650   lupb_wrapper_pushwrapper(L, 1, m, LUPB_MSGDEF);
651   return 1;
652 }
653 
lupb_FileDef_msgcount(lua_State * L)654 static int lupb_FileDef_msgcount(lua_State* L) {
655   const upb_FileDef* f = lupb_FileDef_check(L, 1);
656   lua_pushnumber(L, upb_FileDef_TopLevelMessageCount(f));
657   return 1;
658 }
659 
lupb_FileDef_Name(lua_State * L)660 static int lupb_FileDef_Name(lua_State* L) {
661   const upb_FileDef* f = lupb_FileDef_check(L, 1);
662   lua_pushstring(L, upb_FileDef_Name(f));
663   return 1;
664 }
665 
lupb_FileDef_Package(lua_State * L)666 static int lupb_FileDef_Package(lua_State* L) {
667   const upb_FileDef* f = lupb_FileDef_check(L, 1);
668   lua_pushstring(L, upb_FileDef_Package(f));
669   return 1;
670 }
671 
lupb_FileDef_Pool(lua_State * L)672 static int lupb_FileDef_Pool(lua_State* L) {
673   const upb_FileDef* f = lupb_FileDef_check(L, 1);
674   const upb_DefPool* defpool = upb_FileDef_Pool(f);
675   lupb_wrapper_pushwrapper(L, 1, defpool, LUPB_SYMTAB);
676   return 1;
677 }
678 
lupb_FileDef_Syntax(lua_State * L)679 static int lupb_FileDef_Syntax(lua_State* L) {
680   const upb_FileDef* f = lupb_FileDef_check(L, 1);
681   lua_pushnumber(L, upb_FileDef_Syntax(f));
682   return 1;
683 }
684 
685 static const struct luaL_Reg lupb_FileDef_m[] = {
686     {"dep", lupb_FileDef_Dependency},
687     {"depcount", lupb_FileDef_DependencyCount},
688     {"enum", lupb_FileDef_enum},
689     {"enumcount", lupb_FileDef_enumcount},
690     {"msg", lupb_FileDef_msg},
691     {"msgcount", lupb_FileDef_msgcount},
692     {"name", lupb_FileDef_Name},
693     {"package", lupb_FileDef_Package},
694     {"defpool", lupb_FileDef_Pool},
695     {"syntax", lupb_FileDef_Syntax},
696     {NULL, NULL}};
697 
698 /* lupb_DefPool
699  * ****************************************************************/
700 
701 /* The defpool owns all defs.  Thus GC-rooting the defpool ensures that all
702  * underlying defs stay alive.
703  *
704  * The defpool's userval is a cache of def* -> object. */
705 
706 #define LUPB_CACHE_INDEX 1
707 
708 typedef struct {
709   upb_DefPool* defpool;
710 } lupb_DefPool;
711 
lupb_DefPool_check(lua_State * L,int narg)712 upb_DefPool* lupb_DefPool_check(lua_State* L, int narg) {
713   lupb_DefPool* ldefpool = luaL_checkudata(L, narg, LUPB_SYMTAB);
714   if (!ldefpool->defpool) {
715     luaL_error(L, "called into dead object");
716   }
717   return ldefpool->defpool;
718 }
719 
lupb_DefPool_pushwrapper(lua_State * L,int narg,const void * def,const char * type)720 void lupb_DefPool_pushwrapper(lua_State* L, int narg, const void* def,
721                               const char* type) {
722   narg = lua_absindex(L, narg);
723   assert(luaL_testudata(L, narg, LUPB_SYMTAB));
724 
725   if (def == NULL) {
726     lua_pushnil(L);
727     return;
728   }
729 
730   lua_getiuservalue(L, narg, LUPB_CACHE_INDEX); /* Get cache. */
731 
732   /* Index by "def" pointer. */
733   lua_rawgetp(L, -1, def);
734 
735   /* Stack is now: cache, cached value. */
736   if (lua_isnil(L, -1)) {
737     /* Create new wrapper. */
738     lupb_wrapper* w = lupb_newuserdata(L, sizeof(*w), 1, type);
739     w->def = def;
740     lua_replace(L, -2); /* Replace nil */
741 
742     /* Set defpool as userval. */
743     lua_pushvalue(L, narg);
744     lua_setiuservalue(L, -2, LUPB_SYMTAB_INDEX);
745 
746     /* Add wrapper to the the cache. */
747     lua_pushvalue(L, -1);
748     lua_rawsetp(L, -3, def);
749   }
750 
751   lua_replace(L, -2); /* Remove cache, leaving only the wrapper. */
752 }
753 
754 /* upb_DefPool_New()
755  *
756  * Handles:
757  *   upb.DefPool() -> <new instance>
758  */
lupb_DefPool_New(lua_State * L)759 static int lupb_DefPool_New(lua_State* L) {
760   lupb_DefPool* ldefpool =
761       lupb_newuserdata(L, sizeof(*ldefpool), 1, LUPB_SYMTAB);
762   ldefpool->defpool = upb_DefPool_New();
763 
764   /* Create our object cache. */
765   lua_newtable(L);
766 
767   /* Cache metatable: specifies that values are weak. */
768   lua_createtable(L, 0, 1);
769   lua_pushstring(L, "v");
770   lua_setfield(L, -2, "__mode");
771   lua_setmetatable(L, -2);
772 
773   /* Put the defpool itself in the cache metatable. */
774   lua_pushvalue(L, -2);
775   lua_rawsetp(L, -2, ldefpool->defpool);
776 
777   /* Set the cache as our userval. */
778   lua_setiuservalue(L, -2, LUPB_CACHE_INDEX);
779 
780   return 1;
781 }
782 
lupb_DefPool_gc(lua_State * L)783 static int lupb_DefPool_gc(lua_State* L) {
784   lupb_DefPool* ldefpool = luaL_checkudata(L, 1, LUPB_SYMTAB);
785   upb_DefPool_Free(ldefpool->defpool);
786   ldefpool->defpool = NULL;
787   return 0;
788 }
789 
lupb_DefPool_AddFile(lua_State * L)790 static int lupb_DefPool_AddFile(lua_State* L) {
791   size_t len;
792   upb_DefPool* s = lupb_DefPool_check(L, 1);
793   const char* str = luaL_checklstring(L, 2, &len);
794   upb_Arena* arena = lupb_Arena_pushnew(L);
795   const google_protobuf_FileDescriptorProto* file;
796   const upb_FileDef* file_def;
797   upb_Status status;
798 
799   upb_Status_Clear(&status);
800   file = google_protobuf_FileDescriptorProto_parse(str, len, arena);
801 
802   if (!file) {
803     luaL_argerror(L, 2, "failed to parse descriptor");
804   }
805 
806   file_def = upb_DefPool_AddFile(s, file, &status);
807   lupb_checkstatus(L, &status);
808 
809   lupb_DefPool_pushwrapper(L, 1, file_def, LUPB_FILEDEF);
810 
811   return 1;
812 }
813 
lupb_DefPool_addset(lua_State * L)814 static int lupb_DefPool_addset(lua_State* L) {
815   size_t i, n, len;
816   const google_protobuf_FileDescriptorProto* const* files;
817   google_protobuf_FileDescriptorSet* set;
818   upb_DefPool* s = lupb_DefPool_check(L, 1);
819   const char* str = luaL_checklstring(L, 2, &len);
820   upb_Arena* arena = lupb_Arena_pushnew(L);
821   upb_Status status;
822 
823   upb_Status_Clear(&status);
824   set = google_protobuf_FileDescriptorSet_parse(str, len, arena);
825 
826   if (!set) {
827     luaL_argerror(L, 2, "failed to parse descriptor");
828   }
829 
830   files = google_protobuf_FileDescriptorSet_file(set, &n);
831   for (i = 0; i < n; i++) {
832     upb_DefPool_AddFile(s, files[i], &status);
833     lupb_checkstatus(L, &status);
834   }
835 
836   return 0;
837 }
838 
lupb_DefPool_FindMessageByName(lua_State * L)839 static int lupb_DefPool_FindMessageByName(lua_State* L) {
840   const upb_DefPool* s = lupb_DefPool_check(L, 1);
841   const upb_MessageDef* m =
842       upb_DefPool_FindMessageByName(s, luaL_checkstring(L, 2));
843   lupb_DefPool_pushwrapper(L, 1, m, LUPB_MSGDEF);
844   return 1;
845 }
846 
lupb_DefPool_FindEnumByName(lua_State * L)847 static int lupb_DefPool_FindEnumByName(lua_State* L) {
848   const upb_DefPool* s = lupb_DefPool_check(L, 1);
849   const upb_EnumDef* e = upb_DefPool_FindEnumByName(s, luaL_checkstring(L, 2));
850   lupb_DefPool_pushwrapper(L, 1, e, LUPB_ENUMDEF);
851   return 1;
852 }
853 
lupb_DefPool_FindEnumByNameval(lua_State * L)854 static int lupb_DefPool_FindEnumByNameval(lua_State* L) {
855   const upb_DefPool* s = lupb_DefPool_check(L, 1);
856   const upb_EnumValueDef* e =
857       upb_DefPool_FindEnumByNameval(s, luaL_checkstring(L, 2));
858   lupb_DefPool_pushwrapper(L, 1, e, LUPB_ENUMVALDEF);
859   return 1;
860 }
861 
lupb_DefPool_tostring(lua_State * L)862 static int lupb_DefPool_tostring(lua_State* L) {
863   lua_pushfstring(L, "<upb.DefPool>");
864   return 1;
865 }
866 
867 static const struct luaL_Reg lupb_DefPool_m[] = {
868     {"add_file", lupb_DefPool_AddFile},
869     {"add_set", lupb_DefPool_addset},
870     {"lookup_msg", lupb_DefPool_FindMessageByName},
871     {"lookup_enum", lupb_DefPool_FindEnumByName},
872     {"lookup_enumval", lupb_DefPool_FindEnumByNameval},
873     {NULL, NULL}};
874 
875 static const struct luaL_Reg lupb_DefPool_mm[] = {
876     {"__gc", lupb_DefPool_gc},
877     {"__tostring", lupb_DefPool_tostring},
878     {NULL, NULL}};
879 
880 /* lupb toplevel **************************************************************/
881 
lupb_setfieldi(lua_State * L,const char * field,int i)882 static void lupb_setfieldi(lua_State* L, const char* field, int i) {
883   lua_pushinteger(L, i);
884   lua_setfield(L, -2, field);
885 }
886 
887 static const struct luaL_Reg lupbdef_toplevel_m[] = {
888     {"DefPool", lupb_DefPool_New}, {NULL, NULL}};
889 
lupb_def_registertypes(lua_State * L)890 void lupb_def_registertypes(lua_State* L) {
891   lupb_setfuncs(L, lupbdef_toplevel_m);
892 
893   /* Register types. */
894   lupb_register_type(L, LUPB_ENUMDEF, lupb_EnumDef_m, lupb_EnumDef_mm);
895   lupb_register_type(L, LUPB_ENUMVALDEF, lupb_enumvaldef_m, NULL);
896   lupb_register_type(L, LUPB_FIELDDEF, lupb_FieldDef_m, NULL);
897   lupb_register_type(L, LUPB_FILEDEF, lupb_FileDef_m, NULL);
898   lupb_register_type(L, LUPB_MSGDEF, lupb_MessageDef_m, lupb_MessageDef_mm);
899   lupb_register_type(L, LUPB_ONEOFDEF, lupb_OneofDef_m, lupb_OneofDef_mm);
900   lupb_register_type(L, LUPB_SYMTAB, lupb_DefPool_m, lupb_DefPool_mm);
901 
902   /* Register constants. */
903   lupb_setfieldi(L, "LABEL_OPTIONAL", kUpb_Label_Optional);
904   lupb_setfieldi(L, "LABEL_REQUIRED", kUpb_Label_Required);
905   lupb_setfieldi(L, "LABEL_REPEATED", kUpb_Label_Repeated);
906 
907   lupb_setfieldi(L, "TYPE_DOUBLE", kUpb_CType_Double);
908   lupb_setfieldi(L, "TYPE_FLOAT", kUpb_CType_Float);
909   lupb_setfieldi(L, "TYPE_INT64", kUpb_CType_Int64);
910   lupb_setfieldi(L, "TYPE_UINT64", kUpb_CType_UInt64);
911   lupb_setfieldi(L, "TYPE_INT32", kUpb_CType_Int32);
912   lupb_setfieldi(L, "TYPE_BOOL", kUpb_CType_Bool);
913   lupb_setfieldi(L, "TYPE_STRING", kUpb_CType_String);
914   lupb_setfieldi(L, "TYPE_MESSAGE", kUpb_CType_Message);
915   lupb_setfieldi(L, "TYPE_BYTES", kUpb_CType_Bytes);
916   lupb_setfieldi(L, "TYPE_UINT32", kUpb_CType_UInt32);
917   lupb_setfieldi(L, "TYPE_ENUM", kUpb_CType_Enum);
918 
919   lupb_setfieldi(L, "DESCRIPTOR_TYPE_DOUBLE", kUpb_FieldType_Double);
920   lupb_setfieldi(L, "DESCRIPTOR_TYPE_FLOAT", kUpb_FieldType_Float);
921   lupb_setfieldi(L, "DESCRIPTOR_TYPE_INT64", kUpb_FieldType_Int64);
922   lupb_setfieldi(L, "DESCRIPTOR_TYPE_UINT64", kUpb_FieldType_UInt64);
923   lupb_setfieldi(L, "DESCRIPTOR_TYPE_INT32", kUpb_FieldType_Int32);
924   lupb_setfieldi(L, "DESCRIPTOR_TYPE_FIXED64", kUpb_FieldType_Fixed64);
925   lupb_setfieldi(L, "DESCRIPTOR_TYPE_FIXED32", kUpb_FieldType_Fixed32);
926   lupb_setfieldi(L, "DESCRIPTOR_TYPE_BOOL", kUpb_FieldType_Bool);
927   lupb_setfieldi(L, "DESCRIPTOR_TYPE_STRING", kUpb_FieldType_String);
928   lupb_setfieldi(L, "DESCRIPTOR_TYPE_GROUP", kUpb_FieldType_Group);
929   lupb_setfieldi(L, "DESCRIPTOR_TYPE_MESSAGE", kUpb_FieldType_Message);
930   lupb_setfieldi(L, "DESCRIPTOR_TYPE_BYTES", kUpb_FieldType_Bytes);
931   lupb_setfieldi(L, "DESCRIPTOR_TYPE_UINT32", kUpb_FieldType_UInt32);
932   lupb_setfieldi(L, "DESCRIPTOR_TYPE_ENUM", kUpb_FieldType_Enum);
933   lupb_setfieldi(L, "DESCRIPTOR_TYPE_SFIXED32", kUpb_FieldType_SFixed32);
934   lupb_setfieldi(L, "DESCRIPTOR_TYPE_SFIXED64", kUpb_FieldType_SFixed64);
935   lupb_setfieldi(L, "DESCRIPTOR_TYPE_SINT32", kUpb_FieldType_SInt32);
936   lupb_setfieldi(L, "DESCRIPTOR_TYPE_SINT64", kUpb_FieldType_SInt64);
937 
938   lupb_setfieldi(L, "SYNTAX_PROTO2", kUpb_Syntax_Proto2);
939   lupb_setfieldi(L, "SYNTAX_PROTO3", kUpb_Syntax_Proto3);
940 }
941