/* * 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; }
/* * call-seq: * Enum.lookup(number) => name * * This module method, provided on each generated enum module, looks up an enum * value by number and returns its name as a Ruby symbol, or nil if not found. */ VALUE enum_lookup(VALUE self, VALUE number) { int32_t num = NUM2INT(number); VALUE desc = rb_iv_get(self, kDescriptorInstanceVar); EnumDescriptor* enumdesc = ruby_to_EnumDescriptor(desc); const char* name = upb_enumdef_iton(enumdesc->enumdef, num); if (name == NULL) { return Qnil; } else { return ID2SYM(rb_intern(name)); } }
/* * call-seq: * Enum.resolve(name) => number * * This module method, provided on each generated enum module, looks up an enum * value by name (as a Ruby symbol) and returns its name, or nil if not found. */ VALUE enum_resolve(VALUE self, VALUE sym) { const char* name = rb_id2name(SYM2ID(sym)); VALUE desc = rb_iv_get(self, kDescriptorInstanceVar); EnumDescriptor* enumdesc = ruby_to_EnumDescriptor(desc); int32_t num = 0; bool found = upb_enumdef_ntoiz(enumdesc->enumdef, name, &num); if (!found) { return Qnil; } else { return INT2NUM(num); } }
/* * call-seq: * DescriptorPool.add(descriptor) * * Adds the given Descriptor or EnumDescriptor to this pool. All references to * other types in a Descriptor's fields must be resolvable within this pool or * an exception will be raised. */ VALUE DescriptorPool_add(VALUE _self, VALUE def) { DEFINE_SELF(DescriptorPool, self, _self); VALUE def_klass = rb_obj_class(def); if (def_klass == cDescriptor) { add_descriptor_to_pool(self, ruby_to_Descriptor(def)); } else if (def_klass == cEnumDescriptor) { add_enumdesc_to_pool(self, ruby_to_EnumDescriptor(def)); } else { rb_raise(rb_eArgError, "Second argument must be a Descriptor or EnumDescriptor."); } return Qnil; }