static void test_mapentry_check() { upb_status s = UPB_STATUS_INIT; upb_msgdef *m = upb_msgdef_new(&m); upb_fielddef *f = upb_fielddef_new(&f); upb_symtab *symtab = upb_symtab_new(&symtab); upb_msgdef *subm = upb_msgdef_new(&subm); upb_def *defs[2]; upb_msgdef_setfullname(m, "TestMessage", &s); upb_fielddef_setname(f, "field1", &s); upb_fielddef_setnumber(f, 1, &s); upb_fielddef_setlabel(f, UPB_LABEL_OPTIONAL); upb_fielddef_settype(f, UPB_TYPE_MESSAGE); upb_fielddef_setsubdefname(f, ".MapEntry", &s); upb_msgdef_addfield(m, f, &f, &s); ASSERT(upb_ok(&s)); upb_msgdef_setfullname(subm, "MapEntry", &s); upb_msgdef_setmapentry(subm, true); defs[0] = upb_msgdef_upcast_mutable(m); defs[1] = upb_msgdef_upcast_mutable(subm); upb_symtab_add(symtab, defs, 2, NULL, &s); /* Should not have succeeded: non-repeated field pointing to a MapEntry. */ ASSERT(!upb_ok(&s)); upb_fielddef_setlabel(f, UPB_LABEL_REPEATED); upb_symtab_add(symtab, defs, 2, NULL, &s); ASSERT(upb_ok(&s)); upb_symtab_unref(symtab, &symtab); upb_msgdef_unref(subm, &subm); upb_msgdef_unref(m, &m); }
static void test_symbol_resolution() { upb_status s = UPB_STATUS_INIT; upb_def *defs[2]; upb_msgdef *m1; upb_msgdef *m2; upb_msgdef *m3; upb_fielddef *m3_field1; upb_fielddef *m3_field2; upb_symtab *symtab = upb_symtab_new(&symtab); ASSERT(symtab); /* m1 has name "A.B.C" and no fields. We'll add it to the symtab now. */ m1 = upb_msgdef_new(&m1); ASSERT(m1); ASSERT_STATUS(upb_msgdef_setfullname(m1, "A.B.C", &s), &s); ASSERT_STATUS(upb_symtab_add(symtab, (upb_def**)&m1, 1, NULL, &s), &s); /* m2 has name "D.E" and no fields. We'll add it in the same batch as m3 * below. */ m2 = upb_msgdef_new(&m2); ASSERT(m2); ASSERT_STATUS(upb_msgdef_setfullname(m2, "D.E", &s), &s); /* m3 has name "F.G" and two fields, of type A.B.C and D.E respectively. We'll * add it in the same batch as m2 above. */ m3 = upb_msgdef_new(&m3); ASSERT(m3); ASSERT_STATUS(upb_msgdef_setfullname(m3, "F.G", &s), &s); m3_field1 = upb_fielddef_new(&m3_field1); ASSERT_STATUS(upb_fielddef_setname(m3_field1, "field1", &s), &s); ASSERT_STATUS(upb_fielddef_setnumber(m3_field1, 1, &s), &s); upb_fielddef_setlabel(m3_field1, UPB_LABEL_OPTIONAL); upb_fielddef_settype(m3_field1, UPB_TYPE_MESSAGE); ASSERT_STATUS(upb_fielddef_setsubdefname(m3_field1, ".A.B.C", &s), &s); ASSERT_STATUS(upb_msgdef_addfield(m3, m3_field1, NULL, &s), &s); m3_field2 = upb_fielddef_new(&m3_field2); ASSERT_STATUS(upb_fielddef_setname(m3_field2, "field2", &s), &s); ASSERT_STATUS(upb_fielddef_setnumber(m3_field2, 2, &s), &s); upb_fielddef_setlabel(m3_field2, UPB_LABEL_OPTIONAL); upb_fielddef_settype(m3_field2, UPB_TYPE_MESSAGE); ASSERT_STATUS(upb_fielddef_setsubdefname(m3_field2, ".D.E", &s), &s); ASSERT_STATUS(upb_msgdef_addfield(m3, m3_field2, NULL, &s), &s); defs[0] = upb_msgdef_upcast_mutable(m2); defs[1] = upb_msgdef_upcast_mutable(m3); ASSERT_STATUS(upb_symtab_add(symtab, defs, 2, NULL, &s), &s); upb_fielddef_unref(m3_field2, &m3_field2); upb_fielddef_unref(m3_field1, &m3_field1); upb_msgdef_unref(m3, &m3); upb_msgdef_unref(m2, &m2); upb_msgdef_unref(m1, &m1); upb_symtab_unref(symtab, &symtab); }
static void test_oneofs() { upb_status s = UPB_STATUS_INIT; bool ok = true; upb_def *subm_defs[1]; upb_symtab *symtab = upb_symtab_new(&symtab); upb_msgdef *subm = upb_msgdef_newnamed("SubMessage", &symtab); upb_msgdef *m = upb_msgdef_newnamed("TestMessage", &symtab); upb_oneofdef *o = upb_oneofdef_new(&o); const upb_oneofdef *lookup_o; const upb_fielddef *lookup_field; upb_def *defs[1]; ASSERT(symtab != NULL); /* Create a test message for fields to refer to. */ upb_msgdef_addfield(subm, newfield("field1", 1, UPB_TYPE_INT32, UPB_LABEL_OPTIONAL, NULL, &symtab), &symtab, NULL); subm_defs[0] = upb_msgdef_upcast_mutable(subm); ASSERT_STATUS(upb_symtab_add(symtab, subm_defs, 1, &symtab, &s), &s); ASSERT(upb_msgdef_numoneofs(m) == 0); ASSERT(upb_oneofdef_numfields(o) == 0); ASSERT(upb_oneofdef_name(o) == NULL); ok = upb_oneofdef_setname(o, "test_oneof", &s); ASSERT_STATUS(ok, &s); ok = upb_oneofdef_addfield(o, newfield("field1", 1, UPB_TYPE_INT32, UPB_LABEL_OPTIONAL, NULL, &symtab), &symtab, NULL); ASSERT_STATUS(ok, &s); ok = upb_oneofdef_addfield(o, newfield("field2", 2, UPB_TYPE_MESSAGE, UPB_LABEL_OPTIONAL, ".SubMessage", &symtab), &symtab, NULL); ASSERT_STATUS(ok, &s); ok = upb_msgdef_addoneof(m, o, NULL, &s); ASSERT_STATUS(ok, &s); defs[0] = upb_msgdef_upcast_mutable(m); ASSERT_STATUS(upb_symtab_add(symtab, defs, 1, &symtab, &s), &s); ASSERT(upb_msgdef_numoneofs(m) == 1); lookup_o = upb_msgdef_ntooz(m, "test_oneof"); ASSERT(lookup_o == o); lookup_field = upb_oneofdef_ntofz(o, "field1"); ASSERT(lookup_field != NULL && upb_fielddef_number(lookup_field) == 1); upb_symtab_unref(symtab, &symtab); upb_oneofdef_unref(o, &o); }
static void test_cycles_in_replacement() { upb_symtab *s = upb_symtab_new(&s); upb_msgdef *m = upb_msgdef_newnamed("M", &s); upb_status status = UPB_STATUS_INIT; upb_msgdef_addfield(m, newfield("m", 1, UPB_TYPE_MESSAGE, UPB_LABEL_OPTIONAL, ".M", &s), &s, NULL); ASSERT_STATUS(upb_symtab_add(s, (upb_def**)&m, 1, &s, &status), &status); ASSERT_STATUS(upb_symtab_add(s, NULL, 0, &s, &status), &status); }
// narg is a lua table containing a list of defs to add. static PyObject *PyUpb_SymbolTable_add_defs(PyObject *o, PyObject *defs) { upb_symtab *s = Check_SymbolTable(o, NULL); if (!PySequence_Check(defs)) return PyUpb_Error("Must be a sequence"); Py_ssize_t n = PySequence_Length(defs); // Prevent stack overflow. if (n > 2048) return PyUpb_Error("Too many defs"); upb_def *cdefs[n]; int i = 0; for (i = 0; i < n; i++) { PyObject *pydef = PySequence_GetItem(defs, i); upb_def *def = Check_MessageDef(pydef, NULL); cdefs[i++] = def; upb_msgdef *md = upb_dyncast_msgdef(def); if (!md) continue; upb_msg_field_iter j; for(upb_msg_field_begin(&j, md); !upb_msg_field_done(&j); upb_msg_field_next(&j)) { upb_fielddef *f = upb_msg_iter_field(j); upb_fielddef_setaccessor(f, PyUpb_AccessorForField(f)); } upb_msgdef_layout(md); } upb_status status = UPB_STATUS_INIT; upb_symtab_add(s, cdefs, n, &status); PyUpb_CheckStatus(&status); return Py_None; }
static void add_enumdesc_to_pool(DescriptorPool* self, EnumDescriptor* enumdesc) { CHECK_UPB( upb_symtab_add(self->symtab, (upb_def**)&enumdesc->enumdef, 1, NULL, &status), "Adding EnumDescriptor to DescriptorPool failed"); }
/* * call-seq: * Builder.finalize_to_pool(pool) * * Adds all accumulated message and enum descriptors created in this builder * context to the given pool. The operation occurs atomically, and all * descriptors can refer to each other (including in cycles). This is the only * way to build (co)recursive message definitions. * * This method is usually called automatically by DescriptorPool#build after it * invokes the given user block in the context of the builder. The user should * not normally need to call this manually because a Builder is not normally * created manually. */ VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb) { DEFINE_SELF(Builder, self, _self); DescriptorPool* pool = ruby_to_DescriptorPool(pool_rb); REALLOC_N(self->defs, upb_def*, RARRAY_LEN(self->pending_list)); for (int i = 0; i < RARRAY_LEN(self->pending_list); i++) { VALUE def_rb = rb_ary_entry(self->pending_list, i); if (CLASS_OF(def_rb) == cDescriptor) { self->defs[i] = (upb_def*)ruby_to_Descriptor(def_rb)->msgdef; validate_msgdef((const upb_msgdef*)self->defs[i]); } else if (CLASS_OF(def_rb) == cEnumDescriptor) { self->defs[i] = (upb_def*)ruby_to_EnumDescriptor(def_rb)->enumdef; validate_enumdef((const upb_enumdef*)self->defs[i]); } } CHECK_UPB(upb_symtab_add(pool->symtab, (upb_def**)self->defs, RARRAY_LEN(self->pending_list), NULL, &status), "Unable to add defs to DescriptorPool"); for (int i = 0; i < RARRAY_LEN(self->pending_list); i++) { VALUE def_rb = rb_ary_entry(self->pending_list, i); add_def_obj(self->defs[i], def_rb); } self->pending_list = rb_ary_new(); return Qnil; }
static void add_descriptor_to_pool(DescriptorPool* self, Descriptor* descriptor) { CHECK_UPB( upb_symtab_add(self->symtab, (upb_def**)&descriptor->msgdef, 1, NULL, &status), "Adding Descriptor to DescriptorPool failed"); }
static void test_replacement() { upb_symtab *s = upb_symtab_new(&s); upb_enumdef *e2; upb_msgdef *m2; upb_enumdef *e; upb_status status = UPB_STATUS_INIT; upb_def *newdefs[3]; upb_def *newdefs2[1]; const upb_msgdef *m3; upb_msgdef *m = upb_msgdef_newnamed("MyMessage", &s); upb_msgdef_addfield(m, newfield("field1", 1, UPB_TYPE_ENUM, UPB_LABEL_OPTIONAL, ".MyEnum", &s), &s, NULL); m2 = upb_msgdef_newnamed("MyMessage2", &s); e = upb_enumdef_newnamed("MyEnum", &s); ASSERT_STATUS(upb_enumdef_addval(e, "VAL1", 1, &status), &status); newdefs[0] = upb_msgdef_upcast_mutable(m); newdefs[1] = upb_msgdef_upcast_mutable(m2); newdefs[2] = upb_enumdef_upcast_mutable(e); ASSERT_STATUS(upb_symtab_add(s, newdefs, 3, &s, &status), &status); /* Try adding a new definition of MyEnum, MyMessage should get replaced with * a new version. */ e2 = upb_enumdef_newnamed("MyEnum", &s); ASSERT_STATUS(upb_enumdef_addval(e2, "VAL1", 1, &status), &status); newdefs2[0] = upb_enumdef_upcast_mutable(e2); ASSERT_STATUS(upb_symtab_add(s, newdefs2, 1, &s, &status), &status); m3 = upb_symtab_lookupmsg(s, "MyMessage"); ASSERT(m3); /* Must be different because it points to MyEnum which was replaced. */ ASSERT(m3 != m); m3 = upb_symtab_lookupmsg(s, "MyMessage2"); /* Should be the same because it was not replaced, nor were any defs that * are reachable from it. */ ASSERT(m3 == m2); upb_symtab_unref(s, &s); }