static void test_descriptor_flags() { upb_msgdef *m = upb_msgdef_new(&m); upb_msgdef *m2; upb_status s = UPB_STATUS_INIT; ASSERT(upb_msgdef_mapentry(m) == false); upb_msgdef_setfullname(m, "TestMessage", &s); ASSERT(upb_ok(&s)); upb_msgdef_setmapentry(m, true); ASSERT(upb_msgdef_mapentry(m) == true); m2 = upb_msgdef_dup(m, &m2); ASSERT(upb_msgdef_mapentry(m2) == true); upb_msgdef_unref(m, &m); upb_msgdef_unref(m2, &m2); }
bool is_map_field(const upb_fielddef* field) { if (upb_fielddef_label(field) != UPB_LABEL_REPEATED || upb_fielddef_type(field) != UPB_TYPE_MESSAGE) { return false; } const upb_msgdef* subdef = upb_fielddef_msgsubdef(field); return upb_msgdef_mapentry(subdef); }
const upb_msgdef* tryget_map_entry_msgdef(const upb_fielddef* field) { const upb_msgdef* subdef; if (upb_fielddef_label(field) != UPB_LABEL_REPEATED || upb_fielddef_type(field) != UPB_TYPE_MESSAGE) { return NULL; } subdef = upb_fielddef_msgsubdef(field); return upb_msgdef_mapentry(subdef) ? subdef : NULL; }
static void add_handlers_for_message(const void *closure, upb_handlers *h) { const upb_msgdef* msgdef = upb_handlers_msgdef(h); Descriptor* desc = ruby_to_Descriptor(get_def_obj((void*)msgdef)); upb_msg_field_iter i; // If this is a mapentry message type, set up a special set of handlers and // bail out of the normal (user-defined) message type handling. if (upb_msgdef_mapentry(msgdef)) { add_handlers_for_mapentry(msgdef, h, desc); return; } // Ensure layout exists. We may be invoked to create handlers for a given // message if we are included as a submsg of another message type before our // class is actually built, so to work around this, we just create the layout // (and handlers, in the class-building function) on-demand. if (desc->layout == NULL) { desc->layout = create_layout(desc->msgdef); } for (upb_msg_field_begin(&i, desc->msgdef); !upb_msg_field_done(&i); upb_msg_field_next(&i)) { const upb_fielddef *f = upb_msg_iter_field(&i); size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset + sizeof(MessageHeader); if (upb_fielddef_containingoneof(f)) { size_t oneof_case_offset = desc->layout->fields[upb_fielddef_index(f)].case_offset + sizeof(MessageHeader); add_handlers_for_oneof_field(h, f, offset, oneof_case_offset); } else if (is_map_field(f)) { add_handlers_for_mapfield(h, f, offset, desc); } else if (upb_fielddef_isseq(f)) { add_handlers_for_repeated_field(h, f, offset); } else { add_handlers_for_singular_field(h, f, offset); } } }
const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f, const upb_msgdef *m) { upb_value v; UPB_ASSERT(upb_symtab_lookupmsg(f->symtab, upb_msgdef_fullname(m)) == m); UPB_ASSERT(!upb_msgdef_mapentry(m)); if (upb_inttable_lookupptr(&f->layouts, m, &v)) { UPB_ASSERT(upb_value_getptr(v)); return upb_value_getptr(v); } else { /* In case of circular dependency, layout has to be inserted first. */ upb_msglayout *l = upb_gmalloc(sizeof(*l)); upb_msgfactory *mutable_f = (void*)f; upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l)); UPB_ASSERT(l); if (!upb_msglayout_init(m, l, f)) { upb_msglayout_free(l); } return l; } }