// Set up handlers for a singular field. static void add_handlers_for_singular_field(upb_handlers *h, const upb_fielddef *f, size_t offset) { switch (upb_fielddef_type(f)) { case UPB_TYPE_BOOL: case UPB_TYPE_INT32: case UPB_TYPE_UINT32: case UPB_TYPE_ENUM: case UPB_TYPE_FLOAT: case UPB_TYPE_INT64: case UPB_TYPE_UINT64: case UPB_TYPE_DOUBLE: upb_shim_set(h, f, offset, -1); break; case UPB_TYPE_STRING: case UPB_TYPE_BYTES: { bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset)); upb_handlers_setstartstr(h, f, is_bytes ? bytes_handler : str_handler, &attr); upb_handlers_setstring(h, f, stringdata_handler, &attr); upb_handlerattr_uninit(&attr); break; } case UPB_TYPE_MESSAGE: { upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, offset, f)); upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr); upb_handlerattr_uninit(&attr); break; } } }
bool upb_shim_set(upb_handlers *h, const upb_fielddef *f, size_t offset, int32_t hasbit) { upb_shim_data *d = malloc(sizeof(*d)); if (!d) return false; d->offset = offset; d->hasbit = hasbit; upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; upb_handlerattr_sethandlerdata(&attr, d, free); upb_handlerattr_setalwaysok(&attr, true); #define TYPE(u, l) \ case UPB_TYPE_##u: \ ok = upb_handlers_set##l(h, f, upb_shim_set##l, &attr); break; bool ok = false; switch (upb_fielddef_type(f)) { TYPE(INT64, int64); TYPE(INT32, int32); TYPE(ENUM, int32); TYPE(UINT64, uint64); TYPE(UINT32, uint32); TYPE(DOUBLE, double); TYPE(FLOAT, float); TYPE(BOOL, bool); default: assert(false); break; } #undef TYPE upb_handlerattr_uninit(&attr); return ok; }
// Set up handlers for a repeated field. static void add_handlers_for_repeated_field(upb_handlers *h, const upb_fielddef *f, size_t offset) { upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset)); upb_handlers_setstartseq(h, f, startseq_handler, &attr); upb_handlerattr_uninit(&attr); switch (upb_fielddef_type(f)) { #define SET_HANDLER(utype, ltype) \ case utype: \ upb_handlers_set##ltype(h, f, append##ltype##_handler, NULL); \ break; SET_HANDLER(UPB_TYPE_BOOL, bool); SET_HANDLER(UPB_TYPE_INT32, int32); SET_HANDLER(UPB_TYPE_UINT32, uint32); SET_HANDLER(UPB_TYPE_ENUM, int32); SET_HANDLER(UPB_TYPE_FLOAT, float); SET_HANDLER(UPB_TYPE_INT64, int64); SET_HANDLER(UPB_TYPE_UINT64, uint64); SET_HANDLER(UPB_TYPE_DOUBLE, double); #undef SET_HANDLER case UPB_TYPE_STRING: case UPB_TYPE_BYTES: { bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; upb_handlers_setstartstr(h, f, is_bytes ? appendbytes_handler : appendstr_handler, NULL); upb_handlers_setstring(h, f, stringdata_handler, NULL); break; } case UPB_TYPE_MESSAGE: { upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, 0, f)); upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr); upb_handlerattr_uninit(&attr); break; } } }
// Adds handlers to a map field. static void add_handlers_for_mapfield(upb_handlers* h, const upb_fielddef* fielddef, size_t offset, Descriptor* desc) { const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef); map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc); upb_handlers_addcleanup(h, hd, free); upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; upb_handlerattr_sethandlerdata(&attr, hd); upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr); upb_handlerattr_uninit(&attr); }
static void newhandlers_callback(const void *closure, upb_handlers *h) { UPB_UNUSED(closure); upb_handlers_setstartmsg(h, startmsg, NULL); upb_handlers_setendmsg(h, endmsg, NULL); const upb_msgdef *m = upb_handlers_msgdef(h); upb_msg_field_iter i; for(upb_msg_field_begin(&i, m); !upb_msg_field_done(&i); upb_msg_field_next(&i)) { const upb_fielddef *f = upb_msg_iter_field(&i); bool packed = upb_fielddef_isseq(f) && upb_fielddef_isprimitive(f) && upb_fielddef_packed(f); upb_handlerattr attr; upb_wiretype_t wt = packed ? UPB_WIRE_TYPE_DELIMITED : upb_pb_native_wire_types[upb_fielddef_descriptortype(f)]; // Pre-encode the tag for this field. new_tag(h, f, wt, &attr); if (packed) { upb_handlers_setstartseq(h, f, encode_startdelimfield, &attr); upb_handlers_setendseq(h, f, encode_enddelimfield, &attr); } #define T(upper, lower, upbtype) \ case UPB_DESCRIPTOR_TYPE_##upper: \ if (packed) { \ upb_handlers_set##upbtype(h, f, encode_packed_##lower, &attr); \ } else { \ upb_handlers_set##upbtype(h, f, encode_scalar_##lower, &attr); \ } \ break; switch (upb_fielddef_descriptortype(f)) { T(DOUBLE, double, double); T(FLOAT, float, float); T(INT64, int64, int64); T(INT32, int32, int32); T(FIXED64, fixed64, uint64); T(FIXED32, fixed32, uint32); T(BOOL, bool, bool); T(UINT32, uint32, uint32); T(UINT64, uint64, uint64); T(ENUM, enum, int32); T(SFIXED32, sfixed32, int32); T(SFIXED64, sfixed64, int64); T(SINT32, sint32, int32); T(SINT64, sint64, int64); case UPB_DESCRIPTOR_TYPE_STRING: case UPB_DESCRIPTOR_TYPE_BYTES: upb_handlers_setstartstr(h, f, encode_startstr, &attr); upb_handlers_setendstr(h, f, encode_enddelimfield, &attr); upb_handlers_setstring(h, f, encode_strbuf, &attr); break; case UPB_DESCRIPTOR_TYPE_MESSAGE: upb_handlers_setstartsubmsg(h, f, encode_startdelimfield, &attr); upb_handlers_setendsubmsg(h, f, encode_enddelimfield, &attr); break; case UPB_DESCRIPTOR_TYPE_GROUP: { // Endgroup takes a different tag (wire_type = END_GROUP). upb_handlerattr attr2; new_tag(h, f, UPB_WIRE_TYPE_END_GROUP, &attr2); upb_handlers_setstartsubmsg(h, f, encode_startgroup, &attr); upb_handlers_setendsubmsg(h, f, encode_endgroup, &attr2); upb_handlerattr_uninit(&attr2); break; } } #undef T upb_handlerattr_uninit(&attr); } }