예제 #1
0
파일: defs.c 프로젝트: Overruler/protobuf
/*
 * 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;
}
예제 #2
0
파일: message.c 프로젝트: goodleon/protobuf
/*
 * 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));
  }
}
예제 #3
0
파일: message.c 프로젝트: goodleon/protobuf
/*
 * 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);
  }
}
예제 #4
0
파일: defs.c 프로젝트: Overruler/protobuf
/*
 * 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;
}