1 /*
2 ** TODO(haberman): it's unclear whether a lot of the consistency checks should
3 ** UPB_ASSERT() or return false.
4 */
5
6 #include "upb/handlers.h"
7
8 #include <string.h>
9
10 #include "upb/sink.h"
11
12 #include "upb/port_def.inc"
13
14 struct upb_handlers {
15 upb_handlercache *cache;
16 const upb_msgdef *msg;
17 const upb_handlers **sub;
18 const void *top_closure_type;
19 upb_handlers_tabent table[1]; /* Dynamically-sized field handler array. */
20 };
21
upb_calloc(upb_arena * arena,size_t size)22 static void *upb_calloc(upb_arena *arena, size_t size) {
23 void *mem = upb_malloc(upb_arena_alloc(arena), size);
24 if (mem) {
25 memset(mem, 0, size);
26 }
27 return mem;
28 }
29
30 /* Defined for the sole purpose of having a unique pointer value for
31 * UPB_NO_CLOSURE. */
32 char _upb_noclosure;
33
34 /* Given a selector for a STARTSUBMSG handler, resolves to a pointer to the
35 * subhandlers for this submessage field. */
36 #define SUBH(h, selector) (h->sub[selector])
37
38 /* The selector for a submessage field is the field index. */
39 #define SUBH_F(h, f) SUBH(h, upb_fielddef_index(f))
40
trygetsel(upb_handlers * h,const upb_fielddef * f,upb_handlertype_t type)41 static int32_t trygetsel(upb_handlers *h, const upb_fielddef *f,
42 upb_handlertype_t type) {
43 upb_selector_t sel;
44 bool ok;
45
46 ok = upb_handlers_getselector(f, type, &sel);
47
48 UPB_ASSERT(upb_handlers_msgdef(h) == upb_fielddef_containingtype(f));
49 UPB_ASSERT(ok);
50
51 return sel;
52 }
53
handlers_getsel(upb_handlers * h,const upb_fielddef * f,upb_handlertype_t type)54 static upb_selector_t handlers_getsel(upb_handlers *h, const upb_fielddef *f,
55 upb_handlertype_t type) {
56 int32_t sel = trygetsel(h, f, type);
57 UPB_ASSERT(sel >= 0);
58 return sel;
59 }
60
returntype(upb_handlers * h,const upb_fielddef * f,upb_handlertype_t type)61 static const void **returntype(upb_handlers *h, const upb_fielddef *f,
62 upb_handlertype_t type) {
63 return &h->table[handlers_getsel(h, f, type)].attr.return_closure_type;
64 }
65
doset(upb_handlers * h,int32_t sel,const upb_fielddef * f,upb_handlertype_t type,upb_func * func,const upb_handlerattr * attr)66 static bool doset(upb_handlers *h, int32_t sel, const upb_fielddef *f,
67 upb_handlertype_t type, upb_func *func,
68 const upb_handlerattr *attr) {
69 upb_handlerattr set_attr = UPB_HANDLERATTR_INIT;
70 const void *closure_type;
71 const void **context_closure_type;
72
73 UPB_ASSERT(!h->table[sel].func);
74
75 if (attr) {
76 set_attr = *attr;
77 }
78
79 /* Check that the given closure type matches the closure type that has been
80 * established for this context (if any). */
81 closure_type = set_attr.closure_type;
82
83 if (type == UPB_HANDLER_STRING) {
84 context_closure_type = returntype(h, f, UPB_HANDLER_STARTSTR);
85 } else if (f && upb_fielddef_isseq(f) &&
86 type != UPB_HANDLER_STARTSEQ &&
87 type != UPB_HANDLER_ENDSEQ) {
88 context_closure_type = returntype(h, f, UPB_HANDLER_STARTSEQ);
89 } else {
90 context_closure_type = &h->top_closure_type;
91 }
92
93 if (closure_type && *context_closure_type &&
94 closure_type != *context_closure_type) {
95 return false;
96 }
97
98 if (closure_type)
99 *context_closure_type = closure_type;
100
101 /* If this is a STARTSEQ or STARTSTR handler, check that the returned pointer
102 * matches any pre-existing expectations about what type is expected. */
103 if (type == UPB_HANDLER_STARTSEQ || type == UPB_HANDLER_STARTSTR) {
104 const void *return_type = set_attr.return_closure_type;
105 const void *table_return_type = h->table[sel].attr.return_closure_type;
106 if (return_type && table_return_type && return_type != table_return_type) {
107 return false;
108 }
109
110 if (table_return_type && !return_type) {
111 set_attr.return_closure_type = table_return_type;
112 }
113 }
114
115 h->table[sel].func = (upb_func*)func;
116 h->table[sel].attr = set_attr;
117 return true;
118 }
119
120 /* Returns the effective closure type for this handler (which will propagate
121 * from outer frames if this frame has no START* handler). Not implemented for
122 * UPB_HANDLER_STRING at the moment since this is not needed. Returns NULL is
123 * the effective closure type is unspecified (either no handler was registered
124 * to specify it or the handler that was registered did not specify the closure
125 * type). */
effective_closure_type(upb_handlers * h,const upb_fielddef * f,upb_handlertype_t type)126 const void *effective_closure_type(upb_handlers *h, const upb_fielddef *f,
127 upb_handlertype_t type) {
128 const void *ret;
129 upb_selector_t sel;
130
131 UPB_ASSERT(type != UPB_HANDLER_STRING);
132 ret = h->top_closure_type;
133
134 if (upb_fielddef_isseq(f) &&
135 type != UPB_HANDLER_STARTSEQ &&
136 type != UPB_HANDLER_ENDSEQ &&
137 h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSEQ)].func) {
138 ret = h->table[sel].attr.return_closure_type;
139 }
140
141 if (type == UPB_HANDLER_STRING &&
142 h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSTR)].func) {
143 ret = h->table[sel].attr.return_closure_type;
144 }
145
146 /* The effective type of the submessage; not used yet.
147 * if (type == SUBMESSAGE &&
148 * h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSUBMSG)].func) {
149 * ret = h->table[sel].attr.return_closure_type;
150 * } */
151
152 return ret;
153 }
154
upb_handlers_new(const upb_msgdef * md,upb_handlercache * cache,upb_arena * arena)155 static upb_handlers *upb_handlers_new(const upb_msgdef *md,
156 upb_handlercache *cache,
157 upb_arena *arena) {
158 int extra;
159 upb_handlers *h;
160
161 extra =
162 (int)(sizeof(upb_handlers_tabent) * (upb_msgdef_selectorcount(md) - 1));
163 h = upb_calloc(arena, sizeof(*h) + extra);
164 if (!h) return NULL;
165
166 h->cache = cache;
167 h->msg = md;
168
169 if (upb_msgdef_submsgfieldcount(md) > 0) {
170 size_t bytes = upb_msgdef_submsgfieldcount(md) * sizeof(*h->sub);
171 h->sub = upb_calloc(arena, bytes);
172 if (!h->sub) return NULL;
173 } else {
174 h->sub = 0;
175 }
176
177 /* calloc() above initialized all handlers to NULL. */
178 return h;
179 }
180
181 /* Public interface ***********************************************************/
182
183 #define SETTER(name, handlerctype, handlertype) \
184 bool upb_handlers_set##name(upb_handlers *h, const upb_fielddef *f, \
185 handlerctype func, \
186 const upb_handlerattr *attr) { \
187 int32_t sel = trygetsel(h, f, handlertype); \
188 return doset(h, sel, f, handlertype, (upb_func *)func, attr); \
189 }
190
SETTER(int32,upb_int32_handlerfunc *,UPB_HANDLER_INT32)191 SETTER(int32, upb_int32_handlerfunc*, UPB_HANDLER_INT32)
192 SETTER(int64, upb_int64_handlerfunc*, UPB_HANDLER_INT64)
193 SETTER(uint32, upb_uint32_handlerfunc*, UPB_HANDLER_UINT32)
194 SETTER(uint64, upb_uint64_handlerfunc*, UPB_HANDLER_UINT64)
195 SETTER(float, upb_float_handlerfunc*, UPB_HANDLER_FLOAT)
196 SETTER(double, upb_double_handlerfunc*, UPB_HANDLER_DOUBLE)
197 SETTER(bool, upb_bool_handlerfunc*, UPB_HANDLER_BOOL)
198 SETTER(startstr, upb_startstr_handlerfunc*, UPB_HANDLER_STARTSTR)
199 SETTER(string, upb_string_handlerfunc*, UPB_HANDLER_STRING)
200 SETTER(endstr, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSTR)
201 SETTER(startseq, upb_startfield_handlerfunc*, UPB_HANDLER_STARTSEQ)
202 SETTER(startsubmsg, upb_startfield_handlerfunc*, UPB_HANDLER_STARTSUBMSG)
203 SETTER(endsubmsg, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSUBMSG)
204 SETTER(endseq, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSEQ)
205
206 #undef SETTER
207
208 bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func,
209 const upb_handlerattr *attr) {
210 return doset(h, UPB_UNKNOWN_SELECTOR, NULL, UPB_HANDLER_INT32,
211 (upb_func *)func, attr);
212 }
213
upb_handlers_setstartmsg(upb_handlers * h,upb_startmsg_handlerfunc * func,const upb_handlerattr * attr)214 bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
215 const upb_handlerattr *attr) {
216 return doset(h, UPB_STARTMSG_SELECTOR, NULL, UPB_HANDLER_INT32,
217 (upb_func *)func, attr);
218 }
219
upb_handlers_setendmsg(upb_handlers * h,upb_endmsg_handlerfunc * func,const upb_handlerattr * attr)220 bool upb_handlers_setendmsg(upb_handlers *h, upb_endmsg_handlerfunc *func,
221 const upb_handlerattr *attr) {
222 return doset(h, UPB_ENDMSG_SELECTOR, NULL, UPB_HANDLER_INT32,
223 (upb_func *)func, attr);
224 }
225
upb_handlers_setsubhandlers(upb_handlers * h,const upb_fielddef * f,const upb_handlers * sub)226 bool upb_handlers_setsubhandlers(upb_handlers *h, const upb_fielddef *f,
227 const upb_handlers *sub) {
228 UPB_ASSERT(sub);
229 UPB_ASSERT(upb_fielddef_issubmsg(f));
230 if (SUBH_F(h, f)) return false; /* Can't reset. */
231 if (upb_handlers_msgdef(sub) != upb_fielddef_msgsubdef(f)) {
232 return false;
233 }
234 SUBH_F(h, f) = sub;
235 return true;
236 }
237
upb_handlers_getsubhandlers(const upb_handlers * h,const upb_fielddef * f)238 const upb_handlers *upb_handlers_getsubhandlers(const upb_handlers *h,
239 const upb_fielddef *f) {
240 UPB_ASSERT(upb_fielddef_issubmsg(f));
241 return SUBH_F(h, f);
242 }
243
upb_handlers_gethandler(const upb_handlers * h,upb_selector_t s,const void ** handler_data)244 upb_func *upb_handlers_gethandler(const upb_handlers *h, upb_selector_t s,
245 const void **handler_data) {
246 upb_func *ret = (upb_func *)h->table[s].func;
247 if (ret && handler_data) {
248 *handler_data = h->table[s].attr.handler_data;
249 }
250 return ret;
251 }
252
upb_handlers_getattr(const upb_handlers * h,upb_selector_t sel,upb_handlerattr * attr)253 bool upb_handlers_getattr(const upb_handlers *h, upb_selector_t sel,
254 upb_handlerattr *attr) {
255 if (!upb_handlers_gethandler(h, sel, NULL))
256 return false;
257 *attr = h->table[sel].attr;
258 return true;
259 }
260
upb_handlers_getsubhandlers_sel(const upb_handlers * h,upb_selector_t sel)261 const upb_handlers *upb_handlers_getsubhandlers_sel(const upb_handlers *h,
262 upb_selector_t sel) {
263 /* STARTSUBMSG selector in sel is the field's selector base. */
264 return SUBH(h, sel - UPB_STATIC_SELECTOR_COUNT);
265 }
266
upb_handlers_msgdef(const upb_handlers * h)267 const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h) { return h->msg; }
268
upb_handlers_addcleanup(upb_handlers * h,void * p,upb_handlerfree * func)269 bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *func) {
270 return upb_handlercache_addcleanup(h->cache, p, func);
271 }
272
upb_handlers_getprimitivehandlertype(const upb_fielddef * f)273 upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f) {
274 switch (upb_fielddef_type(f)) {
275 case UPB_TYPE_INT32:
276 case UPB_TYPE_ENUM: return UPB_HANDLER_INT32;
277 case UPB_TYPE_INT64: return UPB_HANDLER_INT64;
278 case UPB_TYPE_UINT32: return UPB_HANDLER_UINT32;
279 case UPB_TYPE_UINT64: return UPB_HANDLER_UINT64;
280 case UPB_TYPE_FLOAT: return UPB_HANDLER_FLOAT;
281 case UPB_TYPE_DOUBLE: return UPB_HANDLER_DOUBLE;
282 case UPB_TYPE_BOOL: return UPB_HANDLER_BOOL;
283 default: UPB_ASSERT(false); return -1; /* Invalid input. */
284 }
285 }
286
upb_handlers_getselector(const upb_fielddef * f,upb_handlertype_t type,upb_selector_t * s)287 bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type,
288 upb_selector_t *s) {
289 uint32_t selector_base = upb_fielddef_selectorbase(f);
290 switch (type) {
291 case UPB_HANDLER_INT32:
292 case UPB_HANDLER_INT64:
293 case UPB_HANDLER_UINT32:
294 case UPB_HANDLER_UINT64:
295 case UPB_HANDLER_FLOAT:
296 case UPB_HANDLER_DOUBLE:
297 case UPB_HANDLER_BOOL:
298 if (!upb_fielddef_isprimitive(f) ||
299 upb_handlers_getprimitivehandlertype(f) != type)
300 return false;
301 *s = selector_base;
302 break;
303 case UPB_HANDLER_STRING:
304 if (upb_fielddef_isstring(f)) {
305 *s = selector_base;
306 } else if (upb_fielddef_lazy(f)) {
307 *s = selector_base + 3;
308 } else {
309 return false;
310 }
311 break;
312 case UPB_HANDLER_STARTSTR:
313 if (upb_fielddef_isstring(f) || upb_fielddef_lazy(f)) {
314 *s = selector_base + 1;
315 } else {
316 return false;
317 }
318 break;
319 case UPB_HANDLER_ENDSTR:
320 if (upb_fielddef_isstring(f) || upb_fielddef_lazy(f)) {
321 *s = selector_base + 2;
322 } else {
323 return false;
324 }
325 break;
326 case UPB_HANDLER_STARTSEQ:
327 if (!upb_fielddef_isseq(f)) return false;
328 *s = selector_base - 2;
329 break;
330 case UPB_HANDLER_ENDSEQ:
331 if (!upb_fielddef_isseq(f)) return false;
332 *s = selector_base - 1;
333 break;
334 case UPB_HANDLER_STARTSUBMSG:
335 if (!upb_fielddef_issubmsg(f)) return false;
336 /* Selectors for STARTSUBMSG are at the beginning of the table so that the
337 * selector can also be used as an index into the "sub" array of
338 * subhandlers. The indexes for the two into these two tables are the
339 * same, except that in the handler table the static selectors come first. */
340 *s = upb_fielddef_index(f) + UPB_STATIC_SELECTOR_COUNT;
341 break;
342 case UPB_HANDLER_ENDSUBMSG:
343 if (!upb_fielddef_issubmsg(f)) return false;
344 *s = selector_base;
345 break;
346 }
347 UPB_ASSERT((size_t)*s < upb_msgdef_selectorcount(upb_fielddef_containingtype(f)));
348 return true;
349 }
350
351 /* upb_handlercache ***********************************************************/
352
353 struct upb_handlercache {
354 upb_arena *arena;
355 upb_inttable tab; /* maps upb_msgdef* -> upb_handlers*. */
356 upb_handlers_callback *callback;
357 const void *closure;
358 };
359
upb_handlercache_get(upb_handlercache * c,const upb_msgdef * md)360 const upb_handlers *upb_handlercache_get(upb_handlercache *c,
361 const upb_msgdef *md) {
362 int i, n;
363 upb_value v;
364 upb_handlers *h;
365
366 if (upb_inttable_lookupptr(&c->tab, md, &v)) {
367 return upb_value_getptr(v);
368 }
369
370 h = upb_handlers_new(md, c, c->arena);
371 v = upb_value_ptr(h);
372
373 if (!h) return NULL;
374 if (!upb_inttable_insertptr(&c->tab, md, v)) return NULL;
375
376 c->callback(c->closure, h);
377
378 /* For each submessage field, get or create a handlers object and set it as
379 * the subhandlers. */
380 n = upb_msgdef_fieldcount(md);
381 for (i = 0; i < n; i++) {
382 const upb_fielddef *f = upb_msgdef_field(md, i);
383
384 if (upb_fielddef_issubmsg(f)) {
385 const upb_msgdef *subdef = upb_fielddef_msgsubdef(f);
386 const upb_handlers *sub_mh = upb_handlercache_get(c, subdef);
387
388 if (!sub_mh) return NULL;
389
390 upb_handlers_setsubhandlers(h, f, sub_mh);
391 }
392 }
393
394 return h;
395 }
396
397
upb_handlercache_new(upb_handlers_callback * callback,const void * closure)398 upb_handlercache *upb_handlercache_new(upb_handlers_callback *callback,
399 const void *closure) {
400 upb_handlercache *cache = upb_gmalloc(sizeof(*cache));
401
402 if (!cache) return NULL;
403
404 cache->arena = upb_arena_new();
405
406 cache->callback = callback;
407 cache->closure = closure;
408
409 if (!upb_inttable_init(&cache->tab, UPB_CTYPE_PTR)) goto oom;
410
411 return cache;
412
413 oom:
414 upb_gfree(cache);
415 return NULL;
416 }
417
upb_handlercache_free(upb_handlercache * cache)418 void upb_handlercache_free(upb_handlercache *cache) {
419 upb_inttable_uninit(&cache->tab);
420 upb_arena_free(cache->arena);
421 upb_gfree(cache);
422 }
423
upb_handlercache_addcleanup(upb_handlercache * c,void * p,upb_handlerfree * func)424 bool upb_handlercache_addcleanup(upb_handlercache *c, void *p,
425 upb_handlerfree *func) {
426 return upb_arena_addcleanup(c->arena, p, func);
427 }
428
429 /* upb_byteshandler ***********************************************************/
430
upb_byteshandler_setstartstr(upb_byteshandler * h,upb_startstr_handlerfunc * func,void * d)431 bool upb_byteshandler_setstartstr(upb_byteshandler *h,
432 upb_startstr_handlerfunc *func, void *d) {
433 h->table[UPB_STARTSTR_SELECTOR].func = (upb_func*)func;
434 h->table[UPB_STARTSTR_SELECTOR].attr.handler_data = d;
435 return true;
436 }
437
upb_byteshandler_setstring(upb_byteshandler * h,upb_string_handlerfunc * func,void * d)438 bool upb_byteshandler_setstring(upb_byteshandler *h,
439 upb_string_handlerfunc *func, void *d) {
440 h->table[UPB_STRING_SELECTOR].func = (upb_func*)func;
441 h->table[UPB_STRING_SELECTOR].attr.handler_data = d;
442 return true;
443 }
444
upb_byteshandler_setendstr(upb_byteshandler * h,upb_endfield_handlerfunc * func,void * d)445 bool upb_byteshandler_setendstr(upb_byteshandler *h,
446 upb_endfield_handlerfunc *func, void *d) {
447 h->table[UPB_ENDSTR_SELECTOR].func = (upb_func*)func;
448 h->table[UPB_ENDSTR_SELECTOR].attr.handler_data = d;
449 return true;
450 }
451
452 /** Handlers for upb_msg ******************************************************/
453
454 typedef struct {
455 size_t offset;
456 int32_t hasbit;
457 } upb_msg_handlerdata;
458
459 /* Fallback implementation if the handler is not specialized by the producer. */
460 #define MSG_WRITER(type, ctype) \
461 bool upb_msg_set ## type (void *c, const void *hd, ctype val) { \
462 uint8_t *m = c; \
463 const upb_msg_handlerdata *d = hd; \
464 if (d->hasbit > 0) \
465 *(uint8_t*)&m[d->hasbit / 8] |= 1 << (d->hasbit % 8); \
466 *(ctype*)&m[d->offset] = val; \
467 return true; \
468 } \
469
MSG_WRITER(double,double)470 MSG_WRITER(double, double)
471 MSG_WRITER(float, float)
472 MSG_WRITER(int32, int32_t)
473 MSG_WRITER(int64, int64_t)
474 MSG_WRITER(uint32, uint32_t)
475 MSG_WRITER(uint64, uint64_t)
476 MSG_WRITER(bool, bool)
477
478 bool upb_msg_setscalarhandler(upb_handlers *h, const upb_fielddef *f,
479 size_t offset, int32_t hasbit) {
480 upb_handlerattr attr = UPB_HANDLERATTR_INIT;
481 bool ok;
482
483 upb_msg_handlerdata *d = upb_gmalloc(sizeof(*d));
484 if (!d) return false;
485 d->offset = offset;
486 d->hasbit = hasbit;
487
488 attr.handler_data = d;
489 attr.alwaysok = true;
490 upb_handlers_addcleanup(h, d, upb_gfree);
491
492 #define TYPE(u, l) \
493 case UPB_TYPE_##u: \
494 ok = upb_handlers_set##l(h, f, upb_msg_set##l, &attr); break;
495
496 ok = false;
497
498 switch (upb_fielddef_type(f)) {
499 TYPE(INT64, int64);
500 TYPE(INT32, int32);
501 TYPE(ENUM, int32);
502 TYPE(UINT64, uint64);
503 TYPE(UINT32, uint32);
504 TYPE(DOUBLE, double);
505 TYPE(FLOAT, float);
506 TYPE(BOOL, bool);
507 default: UPB_ASSERT(false); break;
508 }
509 #undef TYPE
510
511 return ok;
512 }
513
upb_msg_getscalarhandlerdata(const upb_handlers * h,upb_selector_t s,upb_fieldtype_t * type,size_t * offset,int32_t * hasbit)514 bool upb_msg_getscalarhandlerdata(const upb_handlers *h,
515 upb_selector_t s,
516 upb_fieldtype_t *type,
517 size_t *offset,
518 int32_t *hasbit) {
519 const upb_msg_handlerdata *d;
520 const void *p;
521 upb_func *f = upb_handlers_gethandler(h, s, &p);
522
523 if ((upb_int64_handlerfunc*)f == upb_msg_setint64) {
524 *type = UPB_TYPE_INT64;
525 } else if ((upb_int32_handlerfunc*)f == upb_msg_setint32) {
526 *type = UPB_TYPE_INT32;
527 } else if ((upb_uint64_handlerfunc*)f == upb_msg_setuint64) {
528 *type = UPB_TYPE_UINT64;
529 } else if ((upb_uint32_handlerfunc*)f == upb_msg_setuint32) {
530 *type = UPB_TYPE_UINT32;
531 } else if ((upb_double_handlerfunc*)f == upb_msg_setdouble) {
532 *type = UPB_TYPE_DOUBLE;
533 } else if ((upb_float_handlerfunc*)f == upb_msg_setfloat) {
534 *type = UPB_TYPE_FLOAT;
535 } else if ((upb_bool_handlerfunc*)f == upb_msg_setbool) {
536 *type = UPB_TYPE_BOOL;
537 } else {
538 return false;
539 }
540
541 d = p;
542 *offset = d->offset;
543 *hasbit = d->hasbit;
544 return true;
545 }
546