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