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