blob: 1f9ee1217b6c35d8cbd139efbd38cb7c47c800b4 [file] [log] [blame]
Adam Cozzette501ecec2023-09-26 14:36:20 -07001// Protocol Buffers - Google's data interchange format
2// Copyright 2023 Google LLC. All rights reserved.
Adam Cozzette501ecec2023-09-26 14:36:20 -07003//
Hong Shin26dcf402023-11-15 17:15:11 -08004// 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
Adam Cozzette501ecec2023-09-26 14:36:20 -07007
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
28static 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
38typedef struct {
39 const void* def; /* upb_MessageDef, upb_EnumDef, upb_OneofDef, etc. */
40} lupb_wrapper;
41
42static 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
48static 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. */
56static 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 */
69void 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
78const upb_FieldDef* lupb_FieldDef_check(lua_State* L, int narg) {
79 return lupb_wrapper_check(L, narg, LUPB_FIELDDEF);
80}
81
82static 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
89static 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
96static 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
106static 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
112static 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
118static 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
124static 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
130static 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
136static 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
142static 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
153static 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
159static 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
166static 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
173static 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
179static 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
198const upb_OneofDef* lupb_OneofDef_check(lua_State* L, int narg) {
199 return lupb_wrapper_check(L, narg, LUPB_ONEOFDEF);
200}
201
202static 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
209static 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
224static 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
234static 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
244static 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 */
256static 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
278static 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
284static 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
292static const struct luaL_Reg lupb_OneofDef_mm[] = {{"__len", lupb_OneofDef_len},
293 {NULL, NULL}};
294
295/* lupb_MessageDef
296 * ****************************************************************/
297
298typedef struct {
299 const upb_MessageDef* md;
300} lupb_MessageDef;
301
302const upb_MessageDef* lupb_MessageDef_check(lua_State* L, int narg) {
303 return lupb_wrapper_check(L, narg, LUPB_MSGDEF);
304}
305
306static 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
312static 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
318static 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 */
345static 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 */
372static 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 */
393static 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
399static 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
409static 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
419static 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
426static 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
432static 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
439static 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
449static 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
459static 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
465static 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
471static 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
479static 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
486static 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
502const upb_EnumDef* lupb_EnumDef_check(lua_State* L, int narg) {
503 return lupb_wrapper_check(L, narg, LUPB_ENUMDEF);
504}
505
506static 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
512static 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 */
525static 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
547static const struct luaL_Reg lupb_EnumDef_mm[] = {{"__len", lupb_EnumDef_len},
548 {NULL, NULL}};
549
550static const struct luaL_Reg lupb_EnumDef_m[] = {
551 {"file", lupb_EnumDef_File}, {"value", lupb_EnumDef_Value}, {NULL, NULL}};
552
553/* lupb_EnumValueDef
554 * ************************************************************/
555
556const upb_EnumValueDef* lupb_enumvaldef_check(lua_State* L, int narg) {
557 return lupb_wrapper_check(L, narg, LUPB_ENUMVALDEF);
558}
559
560static 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
567static 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
573static 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
579static 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
585static 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
594const upb_FileDef* lupb_FileDef_check(lua_State* L, int narg) {
595 return lupb_wrapper_check(L, narg, LUPB_FILEDEF);
596}
597
598static 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
606static 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
612static 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
620static 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
626static 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
634static 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
640static 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
646static 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
652static 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
659static 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
665static 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
688typedef struct {
689 upb_DefPool* defpool;
690} lupb_DefPool;
691
692upb_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
700void 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 */
739static 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
763static 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
770static 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
794static 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
819static 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
827static 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
834static 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
842static int lupb_DefPool_tostring(lua_State* L) {
843 lua_pushfstring(L, "<upb.DefPool>");
844 return 1;
845}
846
847static 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
855static 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
862static void lupb_setfieldi(lua_State* L, const char* field, int i) {
863 lua_pushinteger(L, i);
864 lua_setfield(L, -2, field);
865}
866
867static const struct luaL_Reg lupbdef_toplevel_m[] = {
868 {"DefPool", lupb_DefPool_New}, {NULL, NULL}};
869
870void 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}