|  | @@ -0,0 +1,1286 @@
 | 
	
		
			
				|  |  | +// Protocol Buffers - Google's data interchange format
 | 
	
		
			
				|  |  | +// Copyright 2014 Google Inc.  All rights reserved.
 | 
	
		
			
				|  |  | +// https://developers.google.com/protocol-buffers/
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +// Redistribution and use in source and binary forms, with or without
 | 
	
		
			
				|  |  | +// modification, are permitted provided that the following conditions are
 | 
	
		
			
				|  |  | +// met:
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +//     * Redistributions of source code must retain the above copyright
 | 
	
		
			
				|  |  | +// notice, this list of conditions and the following disclaimer.
 | 
	
		
			
				|  |  | +//     * Redistributions in binary form must reproduce the above
 | 
	
		
			
				|  |  | +// copyright notice, this list of conditions and the following disclaimer
 | 
	
		
			
				|  |  | +// in the documentation and/or other materials provided with the
 | 
	
		
			
				|  |  | +// distribution.
 | 
	
		
			
				|  |  | +//     * Neither the name of Google Inc. nor the names of its
 | 
	
		
			
				|  |  | +// contributors may be used to endorse or promote products derived from
 | 
	
		
			
				|  |  | +// this software without specific prior written permission.
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
	
		
			
				|  |  | +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
	
		
			
				|  |  | +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
	
		
			
				|  |  | +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
	
		
			
				|  |  | +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
	
		
			
				|  |  | +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
	
		
			
				|  |  | +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
	
		
			
				|  |  | +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
	
		
			
				|  |  | +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
	
		
			
				|  |  | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
	
		
			
				|  |  | +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#include "protobuf.h"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +// Common utilities.
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const char* kDescriptorInstanceVar = "descriptor";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static const char* get_str(VALUE str) {
 | 
	
		
			
				|  |  | +  Check_Type(str, T_STRING);
 | 
	
		
			
				|  |  | +  return RSTRING_PTR(str);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static VALUE rb_str_maybe_null(const char* s) {
 | 
	
		
			
				|  |  | +  if (s == NULL) {
 | 
	
		
			
				|  |  | +    s = "";
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return rb_str_new2(s);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static upb_def* check_notfrozen(const upb_def* def) {
 | 
	
		
			
				|  |  | +  if (upb_def_isfrozen(def)) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eRuntimeError,
 | 
	
		
			
				|  |  | +             "Attempt to modify a frozen descriptor. Once descriptors are "
 | 
	
		
			
				|  |  | +             "added to the descriptor pool, they may not be modified.");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return (upb_def*)def;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static upb_msgdef* check_msg_notfrozen(const upb_msgdef* def) {
 | 
	
		
			
				|  |  | +  return (upb_msgdef*)check_notfrozen((const upb_def*)def);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static upb_fielddef* check_field_notfrozen(const upb_fielddef* def) {
 | 
	
		
			
				|  |  | +  return (upb_fielddef*)check_notfrozen((const upb_def*)def);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static upb_enumdef* check_enum_notfrozen(const upb_enumdef* def) {
 | 
	
		
			
				|  |  | +  return (upb_enumdef*)check_notfrozen((const upb_def*)def);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +// DescriptorPool.
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#define DEFINE_CLASS(name, string_name)                             \
 | 
	
		
			
				|  |  | +    VALUE c ## name;                                                \
 | 
	
		
			
				|  |  | +    const rb_data_type_t _ ## name ## _type = {                     \
 | 
	
		
			
				|  |  | +      string_name,                                                  \
 | 
	
		
			
				|  |  | +      { name ## _mark, name ## _free, NULL },                       \
 | 
	
		
			
				|  |  | +    };                                                              \
 | 
	
		
			
				|  |  | +    name* ruby_to_ ## name(VALUE val) {                             \
 | 
	
		
			
				|  |  | +      name* ret;                                                    \
 | 
	
		
			
				|  |  | +      TypedData_Get_Struct(val, name, &_ ## name ## _type, ret);    \
 | 
	
		
			
				|  |  | +      return ret;                                                   \
 | 
	
		
			
				|  |  | +    }                                                               \
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#define DEFINE_SELF(type, var, rb_var)                              \
 | 
	
		
			
				|  |  | +    type* var = ruby_to_ ## type(rb_var);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Global singleton DescriptorPool. The user is free to create others, but this
 | 
	
		
			
				|  |  | +// is used by generated code.
 | 
	
		
			
				|  |  | +VALUE generated_pool;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +DEFINE_CLASS(DescriptorPool, "Google::Protobuf::DescriptorPool");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void DescriptorPool_mark(void* _self) {
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void DescriptorPool_free(void* _self) {
 | 
	
		
			
				|  |  | +  DescriptorPool* self = _self;
 | 
	
		
			
				|  |  | +  upb_symtab_unref(self->symtab, &self->symtab);
 | 
	
		
			
				|  |  | +  xfree(self);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     DescriptorPool.new => pool
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Creates a new, empty, descriptor pool.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE DescriptorPool_alloc(VALUE klass) {
 | 
	
		
			
				|  |  | +  DescriptorPool* self = ALLOC(DescriptorPool);
 | 
	
		
			
				|  |  | +  self->symtab = upb_symtab_new(&self->symtab);
 | 
	
		
			
				|  |  | +  return TypedData_Wrap_Struct(klass, &_DescriptorPool_type, self);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void DescriptorPool_register(VALUE module) {
 | 
	
		
			
				|  |  | +  VALUE klass = rb_define_class_under(
 | 
	
		
			
				|  |  | +      module, "DescriptorPool", rb_cObject);
 | 
	
		
			
				|  |  | +  rb_define_alloc_func(klass, DescriptorPool_alloc);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "add", DescriptorPool_add, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "build", DescriptorPool_build, 0);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
 | 
	
		
			
				|  |  | +  rb_define_singleton_method(klass, "generated_pool",
 | 
	
		
			
				|  |  | +                             DescriptorPool_generated_pool, 0);
 | 
	
		
			
				|  |  | +  cDescriptorPool = klass;
 | 
	
		
			
				|  |  | +  rb_gc_register_address(&cDescriptorPool);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  generated_pool = rb_class_new_instance(0, NULL, klass);
 | 
	
		
			
				|  |  | +  rb_gc_register_address(&generated_pool);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +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 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:
 | 
	
		
			
				|  |  | + *     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;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     DescriptorPool.build(&block)
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Invokes the block with a Builder instance as self. All message and enum types
 | 
	
		
			
				|  |  | + * added within the block are committed to the pool atomically, and may refer
 | 
	
		
			
				|  |  | + * (co)recursively to each other. The user should call Builder#add_message and
 | 
	
		
			
				|  |  | + * Builder#add_enum within the block as appropriate.  This is the recommended,
 | 
	
		
			
				|  |  | + * idiomatic way to define new message and enum types.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE DescriptorPool_build(VALUE _self) {
 | 
	
		
			
				|  |  | +  VALUE ctx = rb_class_new_instance(0, NULL, cBuilder);
 | 
	
		
			
				|  |  | +  VALUE block = rb_block_proc();
 | 
	
		
			
				|  |  | +  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
 | 
	
		
			
				|  |  | +  rb_funcall(ctx, rb_intern("finalize_to_pool"), 1, _self);
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     DescriptorPool.lookup(name) => descriptor
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none
 | 
	
		
			
				|  |  | + * exists with the given name.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(DescriptorPool, self, _self);
 | 
	
		
			
				|  |  | +  const char* name_str = get_str(name);
 | 
	
		
			
				|  |  | +  const upb_def* def = upb_symtab_lookup(self->symtab, name_str);
 | 
	
		
			
				|  |  | +  if (!def) {
 | 
	
		
			
				|  |  | +    return Qnil;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return get_def_obj(def);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     DescriptorPool.generated_pool => descriptor_pool
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Class method that returns the global DescriptorPool. This is a singleton into
 | 
	
		
			
				|  |  | + * which generated-code message and enum types are registered. The user may also
 | 
	
		
			
				|  |  | + * register types in this pool for convenience so that they do not have to hold
 | 
	
		
			
				|  |  | + * a reference to a private pool instance.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE DescriptorPool_generated_pool(VALUE _self) {
 | 
	
		
			
				|  |  | +  return generated_pool;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +// Descriptor.
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +DEFINE_CLASS(Descriptor, "Google::Protobuf::Descriptor");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void Descriptor_mark(void* _self) {
 | 
	
		
			
				|  |  | +  Descriptor* self = _self;
 | 
	
		
			
				|  |  | +  rb_gc_mark(self->klass);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void Descriptor_free(void* _self) {
 | 
	
		
			
				|  |  | +  Descriptor* self = _self;
 | 
	
		
			
				|  |  | +  upb_msgdef_unref(self->msgdef, &self->msgdef);
 | 
	
		
			
				|  |  | +  if (self->layout) {
 | 
	
		
			
				|  |  | +    free_layout(self->layout);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if (self->fill_handlers) {
 | 
	
		
			
				|  |  | +    upb_handlers_unref(self->fill_handlers, &self->fill_handlers);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if (self->fill_method) {
 | 
	
		
			
				|  |  | +    upb_pbdecodermethod_unref(self->fill_method, &self->fill_method);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if (self->pb_serialize_handlers) {
 | 
	
		
			
				|  |  | +    upb_handlers_unref(self->pb_serialize_handlers,
 | 
	
		
			
				|  |  | +                       &self->pb_serialize_handlers);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if (self->json_serialize_handlers) {
 | 
	
		
			
				|  |  | +    upb_handlers_unref(self->pb_serialize_handlers,
 | 
	
		
			
				|  |  | +                       &self->json_serialize_handlers);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  xfree(self);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     Descriptor.new => descriptor
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Creates a new, empty, message type descriptor. At a minimum, its name must be
 | 
	
		
			
				|  |  | + * set before it is added to a pool. It cannot be used to create messages until
 | 
	
		
			
				|  |  | + * it is added to a pool, after which it becomes immutable (as part of a
 | 
	
		
			
				|  |  | + * finalization process).
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE Descriptor_alloc(VALUE klass) {
 | 
	
		
			
				|  |  | +  Descriptor* self = ALLOC(Descriptor);
 | 
	
		
			
				|  |  | +  VALUE ret = TypedData_Wrap_Struct(klass, &_Descriptor_type, self);
 | 
	
		
			
				|  |  | +  self->msgdef = upb_msgdef_new(&self->msgdef);
 | 
	
		
			
				|  |  | +  self->klass = Qnil;
 | 
	
		
			
				|  |  | +  self->layout = NULL;
 | 
	
		
			
				|  |  | +  self->fill_handlers = NULL;
 | 
	
		
			
				|  |  | +  self->fill_method = NULL;
 | 
	
		
			
				|  |  | +  self->pb_serialize_handlers = NULL;
 | 
	
		
			
				|  |  | +  self->json_serialize_handlers = NULL;
 | 
	
		
			
				|  |  | +  return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void Descriptor_register(VALUE module) {
 | 
	
		
			
				|  |  | +  VALUE klass = rb_define_class_under(
 | 
	
		
			
				|  |  | +      module, "Descriptor", rb_cObject);
 | 
	
		
			
				|  |  | +  rb_define_alloc_func(klass, Descriptor_alloc);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "each", Descriptor_each, 0);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "lookup", Descriptor_lookup, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "add_field", Descriptor_add_field, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "name", Descriptor_name, 0);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "name=", Descriptor_name_set, 1);
 | 
	
		
			
				|  |  | +  rb_include_module(klass, rb_mEnumerable);
 | 
	
		
			
				|  |  | +  cDescriptor = klass;
 | 
	
		
			
				|  |  | +  rb_gc_register_address(&cDescriptor);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     Descriptor.name => name
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns the name of this message type as a fully-qualfied string (e.g.,
 | 
	
		
			
				|  |  | + * My.Package.MessageType).
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE Descriptor_name(VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(Descriptor, self, _self);
 | 
	
		
			
				|  |  | +  return rb_str_maybe_null(upb_msgdef_fullname(self->msgdef));
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *    Descriptor.name = name
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Assigns a name to this message type. The descriptor must not have been added
 | 
	
		
			
				|  |  | + * to a pool yet.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE Descriptor_name_set(VALUE _self, VALUE str) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(Descriptor, self, _self);
 | 
	
		
			
				|  |  | +  upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
 | 
	
		
			
				|  |  | +  const char* name = get_str(str);
 | 
	
		
			
				|  |  | +  CHECK_UPB(
 | 
	
		
			
				|  |  | +      upb_msgdef_setfullname(mut_def, name, &status),
 | 
	
		
			
				|  |  | +      "Error setting Descriptor name");
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     Descriptor.each(&block)
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Iterates over fields in this message type, yielding to the block on each one.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE Descriptor_each(VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(Descriptor, self, _self);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  upb_msg_iter it;
 | 
	
		
			
				|  |  | +  for (upb_msg_begin(&it, self->msgdef);
 | 
	
		
			
				|  |  | +       !upb_msg_done(&it);
 | 
	
		
			
				|  |  | +       upb_msg_next(&it)) {
 | 
	
		
			
				|  |  | +    const upb_fielddef* field = upb_msg_iter_field(&it);
 | 
	
		
			
				|  |  | +    VALUE obj = get_def_obj(field);
 | 
	
		
			
				|  |  | +    rb_yield(obj);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     Descriptor.lookup(name) => FieldDescriptor
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns the field descriptor for the field with the given name, if present,
 | 
	
		
			
				|  |  | + * or nil if none.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE Descriptor_lookup(VALUE _self, VALUE name) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(Descriptor, self, _self);
 | 
	
		
			
				|  |  | +  const char* s = get_str(name);
 | 
	
		
			
				|  |  | +  const upb_fielddef* field = upb_msgdef_ntofz(self->msgdef, s);
 | 
	
		
			
				|  |  | +  if (field == NULL) {
 | 
	
		
			
				|  |  | +    return Qnil;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return get_def_obj(field);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     Descriptor.add_field(field) => nil
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Adds the given FieldDescriptor to this message type. The descriptor must not
 | 
	
		
			
				|  |  | + * have been added to a pool yet. Raises an exception if a field with the same
 | 
	
		
			
				|  |  | + * name or number already exists. Sub-type references (e.g. for fields of type
 | 
	
		
			
				|  |  | + * message) are not resolved at this point.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE Descriptor_add_field(VALUE _self, VALUE obj) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(Descriptor, self, _self);
 | 
	
		
			
				|  |  | +  upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
 | 
	
		
			
				|  |  | +  FieldDescriptor* def = ruby_to_FieldDescriptor(obj);
 | 
	
		
			
				|  |  | +  upb_fielddef* mut_field_def = check_field_notfrozen(def->fielddef);
 | 
	
		
			
				|  |  | +  CHECK_UPB(
 | 
	
		
			
				|  |  | +      upb_msgdef_addfield(mut_def, mut_field_def, NULL, &status),
 | 
	
		
			
				|  |  | +      "Adding field to Descriptor failed");
 | 
	
		
			
				|  |  | +  add_def_obj(def->fielddef, obj);
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     Descriptor.msgclass => message_klass
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns the Ruby class created for this message type. Valid only once the
 | 
	
		
			
				|  |  | + * message type has been added to a pool.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE Descriptor_msgclass(VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(Descriptor, self, _self);
 | 
	
		
			
				|  |  | +  if (!upb_def_isfrozen((const upb_def*)self->msgdef)) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eRuntimeError,
 | 
	
		
			
				|  |  | +             "Cannot fetch message class from a Descriptor not yet in a pool.");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if (self->klass == Qnil) {
 | 
	
		
			
				|  |  | +    self->klass = build_class_from_descriptor(self);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return self->klass;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +// FieldDescriptor.
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +DEFINE_CLASS(FieldDescriptor, "Google::Protobuf::FieldDescriptor");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void FieldDescriptor_mark(void* _self) {
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void FieldDescriptor_free(void* _self) {
 | 
	
		
			
				|  |  | +  FieldDescriptor* self = _self;
 | 
	
		
			
				|  |  | +  upb_fielddef_unref(self->fielddef, &self->fielddef);
 | 
	
		
			
				|  |  | +  xfree(self);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.new => field
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns a new field descriptor. Its name, type, etc. must be set before it is
 | 
	
		
			
				|  |  | + * added to a message type.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_alloc(VALUE klass) {
 | 
	
		
			
				|  |  | +  FieldDescriptor* self = ALLOC(FieldDescriptor);
 | 
	
		
			
				|  |  | +  VALUE ret = TypedData_Wrap_Struct(klass, &_FieldDescriptor_type, self);
 | 
	
		
			
				|  |  | +  upb_fielddef* fielddef = upb_fielddef_new(&self->fielddef);
 | 
	
		
			
				|  |  | +  upb_fielddef_setpacked(fielddef, false);
 | 
	
		
			
				|  |  | +  self->fielddef = fielddef;
 | 
	
		
			
				|  |  | +  return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void FieldDescriptor_register(VALUE module) {
 | 
	
		
			
				|  |  | +  VALUE klass = rb_define_class_under(
 | 
	
		
			
				|  |  | +      module, "FieldDescriptor", rb_cObject);
 | 
	
		
			
				|  |  | +  rb_define_alloc_func(klass, FieldDescriptor_alloc);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "name", FieldDescriptor_name, 0);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "name=", FieldDescriptor_name_set, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "type", FieldDescriptor_type, 0);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "type=", FieldDescriptor_type_set, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "label", FieldDescriptor_label, 0);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "label=", FieldDescriptor_label_set, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "number", FieldDescriptor_number, 0);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "number=", FieldDescriptor_number_set, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "submsg_name=", FieldDescriptor_submsg_name_set, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "get", FieldDescriptor_get, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "set", FieldDescriptor_set, 2);
 | 
	
		
			
				|  |  | +  cFieldDescriptor = klass;
 | 
	
		
			
				|  |  | +  rb_gc_register_address(&cFieldDescriptor);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.name => name
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns the name of this field.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_name(VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  return rb_str_maybe_null(upb_fielddef_name(self->fielddef));
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.name = name
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Sets the name of this field. Cannot be called once the containing message
 | 
	
		
			
				|  |  | + * type, if any, is added to a pool.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_name_set(VALUE _self, VALUE str) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
 | 
	
		
			
				|  |  | +  const char* name = get_str(str);
 | 
	
		
			
				|  |  | +  CHECK_UPB(upb_fielddef_setname(mut_def, name, &status),
 | 
	
		
			
				|  |  | +            "Error setting FieldDescriptor name");
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
 | 
	
		
			
				|  |  | +  if (TYPE(type) != T_SYMBOL) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eArgError, "Expected symbol for field type.");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  upb_fieldtype_t upb_type = -1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#define CONVERT(upb, ruby)                                           \
 | 
	
		
			
				|  |  | +  if (SYM2ID(type) == rb_intern( # ruby )) {                         \
 | 
	
		
			
				|  |  | +    upb_type = UPB_TYPE_ ## upb;                                     \
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  CONVERT(FLOAT, float);
 | 
	
		
			
				|  |  | +  CONVERT(DOUBLE, double);
 | 
	
		
			
				|  |  | +  CONVERT(BOOL, bool);
 | 
	
		
			
				|  |  | +  CONVERT(STRING, string);
 | 
	
		
			
				|  |  | +  CONVERT(BYTES, bytes);
 | 
	
		
			
				|  |  | +  CONVERT(MESSAGE, message);
 | 
	
		
			
				|  |  | +  CONVERT(ENUM, enum);
 | 
	
		
			
				|  |  | +  CONVERT(INT32, int32);
 | 
	
		
			
				|  |  | +  CONVERT(INT64, int64);
 | 
	
		
			
				|  |  | +  CONVERT(UINT32, uint32);
 | 
	
		
			
				|  |  | +  CONVERT(UINT64, uint64);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#undef CONVERT
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (upb_type == -1) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eArgError, "Unknown field type.");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return upb_type;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +VALUE fieldtype_to_ruby(upb_fieldtype_t type) {
 | 
	
		
			
				|  |  | +  switch (type) {
 | 
	
		
			
				|  |  | +#define CONVERT(upb, ruby)                                           \
 | 
	
		
			
				|  |  | +    case UPB_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby ));
 | 
	
		
			
				|  |  | +    CONVERT(FLOAT, float);
 | 
	
		
			
				|  |  | +    CONVERT(DOUBLE, double);
 | 
	
		
			
				|  |  | +    CONVERT(BOOL, bool);
 | 
	
		
			
				|  |  | +    CONVERT(STRING, string);
 | 
	
		
			
				|  |  | +    CONVERT(BYTES, bytes);
 | 
	
		
			
				|  |  | +    CONVERT(MESSAGE, message);
 | 
	
		
			
				|  |  | +    CONVERT(ENUM, enum);
 | 
	
		
			
				|  |  | +    CONVERT(INT32, int32);
 | 
	
		
			
				|  |  | +    CONVERT(INT64, int64);
 | 
	
		
			
				|  |  | +    CONVERT(UINT32, uint32);
 | 
	
		
			
				|  |  | +    CONVERT(UINT64, uint64);
 | 
	
		
			
				|  |  | +#undef CONVERT
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.type => type
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns this field's type, as a Ruby symbol, or nil if not yet set.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Valid field types are:
 | 
	
		
			
				|  |  | + *     :int32, :int64, :uint32, :uint64, :float, :double, :bool, :string,
 | 
	
		
			
				|  |  | + *     :bytes, :message.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_type(VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  if (!upb_fielddef_typeisset(self->fielddef)) {
 | 
	
		
			
				|  |  | +    return Qnil;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return fieldtype_to_ruby(upb_fielddef_type(self->fielddef));
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.type = type
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Sets this field's type. Cannot be called if field is part of a message type
 | 
	
		
			
				|  |  | + * already in a pool.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_type_set(VALUE _self, VALUE type) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
 | 
	
		
			
				|  |  | +  upb_fielddef_settype(mut_def, ruby_to_fieldtype(type));
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.label => label
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns this field's label (i.e., plurality), as a Ruby symbol.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Valid field labels are:
 | 
	
		
			
				|  |  | + *     :optional, :repeated
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_label(VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  switch (upb_fielddef_label(self->fielddef)) {
 | 
	
		
			
				|  |  | +#define CONVERT(upb, ruby)                                           \
 | 
	
		
			
				|  |  | +    case UPB_LABEL_ ## upb : return ID2SYM(rb_intern( # ruby ));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    CONVERT(OPTIONAL, optional);
 | 
	
		
			
				|  |  | +    CONVERT(REQUIRED, required);
 | 
	
		
			
				|  |  | +    CONVERT(REPEATED, repeated);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#undef CONVERT
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.label = label
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Sets the label on this field. Cannot be called if field is part of a message
 | 
	
		
			
				|  |  | + * type already in a pool.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_label_set(VALUE _self, VALUE label) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
 | 
	
		
			
				|  |  | +  if (TYPE(label) != T_SYMBOL) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eArgError, "Expected symbol for field label.");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  upb_label_t upb_label = -1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#define CONVERT(upb, ruby)                                           \
 | 
	
		
			
				|  |  | +  if (SYM2ID(label) == rb_intern( # ruby )) {                        \
 | 
	
		
			
				|  |  | +    upb_label = UPB_LABEL_ ## upb;                                   \
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  CONVERT(OPTIONAL, optional);
 | 
	
		
			
				|  |  | +  CONVERT(REQUIRED, required);
 | 
	
		
			
				|  |  | +  CONVERT(REPEATED, repeated);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#undef CONVERT
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (upb_label == -1) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eArgError, "Unknown field label.");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  upb_fielddef_setlabel(mut_def, upb_label);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.number => number
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns the tag number for this field.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_number(VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  return INT2NUM(upb_fielddef_number(self->fielddef));
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.number = number
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Sets the tag number for this field. Cannot be called if field is part of a
 | 
	
		
			
				|  |  | + * message type already in a pool.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_number_set(VALUE _self, VALUE number) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
 | 
	
		
			
				|  |  | +  CHECK_UPB(upb_fielddef_setnumber(mut_def, NUM2INT(number), &status),
 | 
	
		
			
				|  |  | +            "Error setting field number");
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.submsg_name => submsg_name
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns the name of the message or enum type corresponding to this field, if
 | 
	
		
			
				|  |  | + * it is a message or enum field (respectively), or nil otherwise. This type
 | 
	
		
			
				|  |  | + * name will be resolved within the context of the pool to which the containing
 | 
	
		
			
				|  |  | + * message type is added.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_submsg_name(VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  if (!upb_fielddef_hassubdef(self->fielddef)) {
 | 
	
		
			
				|  |  | +    return Qnil;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return rb_str_maybe_null(upb_fielddef_subdefname(self->fielddef));
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.submsg_name = submsg_name
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Sets the name of the message or enum type corresponding to this field, if it
 | 
	
		
			
				|  |  | + * is a message or enum field (respectively). This type name will be resolved
 | 
	
		
			
				|  |  | + * within the context of the pool to which the containing message type is added.
 | 
	
		
			
				|  |  | + * Cannot be called on field that are not of message or enum type, or on fields
 | 
	
		
			
				|  |  | + * that are part of a message type already added to a pool.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
 | 
	
		
			
				|  |  | +  if (!upb_fielddef_hassubdef(self->fielddef)) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eTypeError, "FieldDescriptor does not have subdef.");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  const char* str = get_str(value);
 | 
	
		
			
				|  |  | +  CHECK_UPB(upb_fielddef_setsubdefname(mut_def, str, &status),
 | 
	
		
			
				|  |  | +            "Error setting submessage name");
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.subtype => message_or_enum_descriptor
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns the message or enum descriptor corresponding to this field's type if
 | 
	
		
			
				|  |  | + * it is a message or enum field, respectively, or nil otherwise. Cannot be
 | 
	
		
			
				|  |  | + * called *until* the containing message type is added to a pool (and thus
 | 
	
		
			
				|  |  | + * resolved).
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_subtype(VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  if (!upb_fielddef_hassubdef(self->fielddef)) {
 | 
	
		
			
				|  |  | +    return Qnil;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  const upb_def* def = upb_fielddef_subdef(self->fielddef);
 | 
	
		
			
				|  |  | +  if (def == NULL) {
 | 
	
		
			
				|  |  | +    return Qnil;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return get_def_obj(def);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.get(message) => value
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns the value set for this field on the given message. Raises an
 | 
	
		
			
				|  |  | + * exception if message is of the wrong type.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  MessageHeader* msg;
 | 
	
		
			
				|  |  | +  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
 | 
	
		
			
				|  |  | +  if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eTypeError, "get method called on wrong message type");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return layout_get(msg->descriptor->layout, Message_data(msg), self->fielddef);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     FieldDescriptor.set(message, value)
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Sets the value corresponding to this field to the given value on the given
 | 
	
		
			
				|  |  | + * message. Raises an exception if message is of the wrong type. Performs the
 | 
	
		
			
				|  |  | + * ordinary type-checks for field setting.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(FieldDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  MessageHeader* msg;
 | 
	
		
			
				|  |  | +  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
 | 
	
		
			
				|  |  | +  if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eTypeError, "set method called on wrong message type");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  layout_set(msg->descriptor->layout, Message_data(msg), self->fielddef, value);
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +// EnumDescriptor.
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +DEFINE_CLASS(EnumDescriptor, "Google::Protobuf::EnumDescriptor");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void EnumDescriptor_mark(void* _self) {
 | 
	
		
			
				|  |  | +  EnumDescriptor* self = _self;
 | 
	
		
			
				|  |  | +  rb_gc_mark(self->module);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void EnumDescriptor_free(void* _self) {
 | 
	
		
			
				|  |  | +  EnumDescriptor* self = _self;
 | 
	
		
			
				|  |  | +  upb_enumdef_unref(self->enumdef, &self->enumdef);
 | 
	
		
			
				|  |  | +  xfree(self);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     EnumDescriptor.new => enum_descriptor
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Creates a new, empty, enum descriptor. Must be added to a pool before the
 | 
	
		
			
				|  |  | + * enum type can be used. The enum type may only be modified prior to adding to
 | 
	
		
			
				|  |  | + * a pool.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE EnumDescriptor_alloc(VALUE klass) {
 | 
	
		
			
				|  |  | +  EnumDescriptor* self = ALLOC(EnumDescriptor);
 | 
	
		
			
				|  |  | +  VALUE ret = TypedData_Wrap_Struct(klass, &_EnumDescriptor_type, self);
 | 
	
		
			
				|  |  | +  self->enumdef = upb_enumdef_new(&self->enumdef);
 | 
	
		
			
				|  |  | +  self->module = Qnil;
 | 
	
		
			
				|  |  | +  return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void EnumDescriptor_register(VALUE module) {
 | 
	
		
			
				|  |  | +  VALUE klass = rb_define_class_under(
 | 
	
		
			
				|  |  | +      module, "EnumDescriptor", rb_cObject);
 | 
	
		
			
				|  |  | +  rb_define_alloc_func(klass, EnumDescriptor_alloc);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "name", EnumDescriptor_name, 0);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "name=", EnumDescriptor_name_set, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "add_value", EnumDescriptor_add_value, 2);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "lookup_name", EnumDescriptor_lookup_name, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "each", EnumDescriptor_each, 0);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
 | 
	
		
			
				|  |  | +  rb_include_module(klass, rb_mEnumerable);
 | 
	
		
			
				|  |  | +  cEnumDescriptor = klass;
 | 
	
		
			
				|  |  | +  rb_gc_register_address(&cEnumDescriptor);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     EnumDescriptor.name => name
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns the name of this enum type.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE EnumDescriptor_name(VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(EnumDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  return rb_str_maybe_null(upb_enumdef_fullname(self->enumdef));
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     EnumDescriptor.name = name
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Sets the name of this enum type. Cannot be called if the enum type has
 | 
	
		
			
				|  |  | + * already been added to a pool.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE EnumDescriptor_name_set(VALUE _self, VALUE str) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(EnumDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  upb_enumdef* mut_def = check_enum_notfrozen(self->enumdef);
 | 
	
		
			
				|  |  | +  const char* name = get_str(str);
 | 
	
		
			
				|  |  | +  CHECK_UPB(upb_enumdef_setfullname(mut_def, name, &status),
 | 
	
		
			
				|  |  | +            "Error setting EnumDescriptor name");
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     EnumDescriptor.add_value(key, value)
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Adds a new key => value mapping to this enum type. Key must be given as a
 | 
	
		
			
				|  |  | + * Ruby symbol. Cannot be called if the enum type has already been added to a
 | 
	
		
			
				|  |  | + * pool. Will raise an exception if the key or value is already in use.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE EnumDescriptor_add_value(VALUE _self, VALUE name, VALUE number) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(EnumDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  upb_enumdef* mut_def = check_enum_notfrozen(self->enumdef);
 | 
	
		
			
				|  |  | +  const char* name_str = rb_id2name(SYM2ID(name));
 | 
	
		
			
				|  |  | +  int32_t val = NUM2INT(number);
 | 
	
		
			
				|  |  | +  CHECK_UPB(upb_enumdef_addval(mut_def, name_str, val, &status),
 | 
	
		
			
				|  |  | +            "Error adding value to enum");
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     EnumDescriptor.lookup_name(name) => value
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns the numeric value corresponding to the given key name (as a Ruby
 | 
	
		
			
				|  |  | + * symbol), or nil if none.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(EnumDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  const char* name_str= rb_id2name(SYM2ID(name));
 | 
	
		
			
				|  |  | +  int32_t val = 0;
 | 
	
		
			
				|  |  | +  if (upb_enumdef_ntoiz(self->enumdef, name_str, &val)) {
 | 
	
		
			
				|  |  | +    return INT2NUM(val);
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    return Qnil;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     EnumDescriptor.lookup_value(name) => value
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns the key name (as a Ruby symbol) corresponding to the integer value,
 | 
	
		
			
				|  |  | + * or nil if none.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(EnumDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  int32_t val = NUM2INT(number);
 | 
	
		
			
				|  |  | +  const char* name = upb_enumdef_iton(self->enumdef, val);
 | 
	
		
			
				|  |  | +  if (name != NULL) {
 | 
	
		
			
				|  |  | +    return ID2SYM(rb_intern(name));
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    return Qnil;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     EnumDescriptor.each(&block)
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Iterates over key => value mappings in this enum's definition, yielding to
 | 
	
		
			
				|  |  | + * the block with (key, value) arguments for each one.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE EnumDescriptor_each(VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(EnumDescriptor, self, _self);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  upb_enum_iter it;
 | 
	
		
			
				|  |  | +  for (upb_enum_begin(&it, self->enumdef);
 | 
	
		
			
				|  |  | +       !upb_enum_done(&it);
 | 
	
		
			
				|  |  | +       upb_enum_next(&it)) {
 | 
	
		
			
				|  |  | +    VALUE key = ID2SYM(rb_intern(upb_enum_iter_name(&it)));
 | 
	
		
			
				|  |  | +    VALUE number = INT2NUM(upb_enum_iter_number(&it));
 | 
	
		
			
				|  |  | +    rb_yield_values(2, key, number);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     EnumDescriptor.enummodule => module
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns the Ruby module corresponding to this enum type. Cannot be called
 | 
	
		
			
				|  |  | + * until the enum descriptor has been added to a pool.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE EnumDescriptor_enummodule(VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(EnumDescriptor, self, _self);
 | 
	
		
			
				|  |  | +  if (!upb_def_isfrozen((const upb_def*)self->enumdef)) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eRuntimeError,
 | 
	
		
			
				|  |  | +             "Cannot fetch enum module from an EnumDescriptor not yet "
 | 
	
		
			
				|  |  | +             "in a pool.");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if (self->module == Qnil) {
 | 
	
		
			
				|  |  | +    self->module = build_module_from_enumdesc(self);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return self->module;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +// MessageBuilderContext.
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +DEFINE_CLASS(MessageBuilderContext,
 | 
	
		
			
				|  |  | +    "Google::Protobuf::Internal::MessageBuilderContext");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void MessageBuilderContext_mark(void* _self) {
 | 
	
		
			
				|  |  | +  MessageBuilderContext* self = _self;
 | 
	
		
			
				|  |  | +  rb_gc_mark(self->descriptor);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void MessageBuilderContext_free(void* _self) {
 | 
	
		
			
				|  |  | +  MessageBuilderContext* self = _self;
 | 
	
		
			
				|  |  | +  xfree(self);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +VALUE MessageBuilderContext_alloc(VALUE klass) {
 | 
	
		
			
				|  |  | +  MessageBuilderContext* self = ALLOC(MessageBuilderContext);
 | 
	
		
			
				|  |  | +  VALUE ret = TypedData_Wrap_Struct(
 | 
	
		
			
				|  |  | +      klass, &_MessageBuilderContext_type, self);
 | 
	
		
			
				|  |  | +  self->descriptor = Qnil;
 | 
	
		
			
				|  |  | +  return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void MessageBuilderContext_register(VALUE module) {
 | 
	
		
			
				|  |  | +  VALUE klass = rb_define_class_under(
 | 
	
		
			
				|  |  | +      module, "MessageBuilderContext", rb_cObject);
 | 
	
		
			
				|  |  | +  rb_define_alloc_func(klass, MessageBuilderContext_alloc);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "initialize",
 | 
	
		
			
				|  |  | +                   MessageBuilderContext_initialize, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "optional", MessageBuilderContext_optional, -1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "required", MessageBuilderContext_required, -1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1);
 | 
	
		
			
				|  |  | +  cMessageBuilderContext = klass;
 | 
	
		
			
				|  |  | +  rb_gc_register_address(&cMessageBuilderContext);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     MessageBuilderContext.new(desc) => context
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Create a new builder context around the given message descriptor. This class
 | 
	
		
			
				|  |  | + * is intended to serve as a DSL context to be used with #instance_eval.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE MessageBuilderContext_initialize(VALUE _self, VALUE msgdef) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(MessageBuilderContext, self, _self);
 | 
	
		
			
				|  |  | +  self->descriptor = msgdef;
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static VALUE msgdef_add_field(VALUE msgdef,
 | 
	
		
			
				|  |  | +                              const char* label, VALUE name,
 | 
	
		
			
				|  |  | +                              VALUE type, VALUE number,
 | 
	
		
			
				|  |  | +                              VALUE type_class) {
 | 
	
		
			
				|  |  | +  VALUE fielddef = rb_class_new_instance(0, NULL, cFieldDescriptor);
 | 
	
		
			
				|  |  | +  VALUE name_str = rb_str_new2(rb_id2name(SYM2ID(name)));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  rb_funcall(fielddef, rb_intern("label="), 1, ID2SYM(rb_intern(label)));
 | 
	
		
			
				|  |  | +  rb_funcall(fielddef, rb_intern("name="), 1, name_str);
 | 
	
		
			
				|  |  | +  rb_funcall(fielddef, rb_intern("type="), 1, type);
 | 
	
		
			
				|  |  | +  rb_funcall(fielddef, rb_intern("number="), 1, number);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (type_class != Qnil) {
 | 
	
		
			
				|  |  | +    if (TYPE(type_class) != T_STRING) {
 | 
	
		
			
				|  |  | +      rb_raise(rb_eArgError, "Expected string for type class");
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    // Make it an absolute type name by prepending a dot.
 | 
	
		
			
				|  |  | +    type_class = rb_str_append(rb_str_new2("."), type_class);
 | 
	
		
			
				|  |  | +    rb_funcall(fielddef, rb_intern("submsg_name="), 1, type_class);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  rb_funcall(msgdef, rb_intern("add_field"), 1, fielddef);
 | 
	
		
			
				|  |  | +  return fielddef;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     MessageBuilderContext.optional(name, type, number, type_class = nil)
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Defines a new optional field on this message type with the given type, tag
 | 
	
		
			
				|  |  | + * number, and type class (for message and enum fields). The type must be a Ruby
 | 
	
		
			
				|  |  | + * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
 | 
	
		
			
				|  |  | + * string, if present (as accepted by FieldDescriptor#submsg_name=).
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(MessageBuilderContext, self, _self);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (argc < 3) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eArgError, "Expected at least 3 arguments.");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  VALUE name = argv[0];
 | 
	
		
			
				|  |  | +  VALUE type = argv[1];
 | 
	
		
			
				|  |  | +  VALUE number = argv[2];
 | 
	
		
			
				|  |  | +  VALUE type_class = (argc > 3) ? argv[3] : Qnil;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return msgdef_add_field(self->descriptor, "optional",
 | 
	
		
			
				|  |  | +                          name, type, number, type_class);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     MessageBuilderContext.required(name, type, number, type_class = nil)
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Defines a new required field on this message type with the given type, tag
 | 
	
		
			
				|  |  | + * number, and type class (for message and enum fields). The type must be a Ruby
 | 
	
		
			
				|  |  | + * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
 | 
	
		
			
				|  |  | + * string, if present (as accepted by FieldDescriptor#submsg_name=).
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Proto3 does not have required fields, but this method exists for
 | 
	
		
			
				|  |  | + * completeness. Any attempt to add a message type with required fields to a
 | 
	
		
			
				|  |  | + * pool will currently result in an error.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(MessageBuilderContext, self, _self);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (argc < 3) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eArgError, "Expected at least 3 arguments.");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  VALUE name = argv[0];
 | 
	
		
			
				|  |  | +  VALUE type = argv[1];
 | 
	
		
			
				|  |  | +  VALUE number = argv[2];
 | 
	
		
			
				|  |  | +  VALUE type_class = (argc > 3) ? argv[3] : Qnil;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return msgdef_add_field(self->descriptor, "required",
 | 
	
		
			
				|  |  | +                          name, type, number, type_class);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     MessageBuilderContext.repeated(name, type, number, type_class = nil)
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Defines a new repeated field on this message type with the given type, tag
 | 
	
		
			
				|  |  | + * number, and type class (for message and enum fields). The type must be a Ruby
 | 
	
		
			
				|  |  | + * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
 | 
	
		
			
				|  |  | + * string, if present (as accepted by FieldDescriptor#submsg_name=).
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(MessageBuilderContext, self, _self);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (argc < 3) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eArgError, "Expected at least 3 arguments.");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  VALUE name = argv[0];
 | 
	
		
			
				|  |  | +  VALUE type = argv[1];
 | 
	
		
			
				|  |  | +  VALUE number = argv[2];
 | 
	
		
			
				|  |  | +  VALUE type_class = (argc > 3) ? argv[3] : Qnil;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return msgdef_add_field(self->descriptor, "repeated",
 | 
	
		
			
				|  |  | +                          name, type, number, type_class);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +// EnumBuilderContext.
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +DEFINE_CLASS(EnumBuilderContext,
 | 
	
		
			
				|  |  | +    "Google::Protobuf::Internal::EnumBuilderContext");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void EnumBuilderContext_mark(void* _self) {
 | 
	
		
			
				|  |  | +  EnumBuilderContext* self = _self;
 | 
	
		
			
				|  |  | +  rb_gc_mark(self->enumdesc);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void EnumBuilderContext_free(void* _self) {
 | 
	
		
			
				|  |  | +  EnumBuilderContext* self = _self;
 | 
	
		
			
				|  |  | +  xfree(self);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +VALUE EnumBuilderContext_alloc(VALUE klass) {
 | 
	
		
			
				|  |  | +  EnumBuilderContext* self = ALLOC(EnumBuilderContext);
 | 
	
		
			
				|  |  | +  VALUE ret = TypedData_Wrap_Struct(
 | 
	
		
			
				|  |  | +      klass, &_EnumBuilderContext_type, self);
 | 
	
		
			
				|  |  | +  self->enumdesc = Qnil;
 | 
	
		
			
				|  |  | +  return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void EnumBuilderContext_register(VALUE module) {
 | 
	
		
			
				|  |  | +  VALUE klass = rb_define_class_under(
 | 
	
		
			
				|  |  | +      module, "EnumBuilderContext", rb_cObject);
 | 
	
		
			
				|  |  | +  rb_define_alloc_func(klass, EnumBuilderContext_alloc);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "initialize",
 | 
	
		
			
				|  |  | +                   EnumBuilderContext_initialize, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "value", EnumBuilderContext_value, 2);
 | 
	
		
			
				|  |  | +  cEnumBuilderContext = klass;
 | 
	
		
			
				|  |  | +  rb_gc_register_address(&cEnumBuilderContext);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     EnumBuilderContext.new(enumdesc) => context
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Create a new builder context around the given enum descriptor. This class is
 | 
	
		
			
				|  |  | + * intended to serve as a DSL context to be used with #instance_eval.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE EnumBuilderContext_initialize(VALUE _self, VALUE enumdef) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(EnumBuilderContext, self, _self);
 | 
	
		
			
				|  |  | +  self->enumdesc = enumdef;
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static VALUE enumdef_add_value(VALUE enumdef,
 | 
	
		
			
				|  |  | +                               VALUE name, VALUE number) {
 | 
	
		
			
				|  |  | +  rb_funcall(enumdef, rb_intern("add_value"), 2, name, number);
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     EnumBuilder.add_value(name, number)
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Adds the given name => number mapping to the enum type. Name must be a Ruby
 | 
	
		
			
				|  |  | + * symbol.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(EnumBuilderContext, self, _self);
 | 
	
		
			
				|  |  | +  return enumdef_add_value(self->enumdesc, name, number);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +// Builder.
 | 
	
		
			
				|  |  | +// -----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +DEFINE_CLASS(Builder, "Google::Protobuf::Internal::Builder");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void Builder_mark(void* _self) {
 | 
	
		
			
				|  |  | +  Builder* self = _self;
 | 
	
		
			
				|  |  | +  rb_gc_mark(self->pending_list);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void Builder_free(void* _self) {
 | 
	
		
			
				|  |  | +  Builder* self = _self;
 | 
	
		
			
				|  |  | +  xfree(self->defs);
 | 
	
		
			
				|  |  | +  xfree(self);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     Builder.new => builder
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Creates a new Builder. A Builder can accumulate a set of new message and enum
 | 
	
		
			
				|  |  | + * descriptors and atomically register them into a pool in a way that allows for
 | 
	
		
			
				|  |  | + * (co)recursive type references.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE Builder_alloc(VALUE klass) {
 | 
	
		
			
				|  |  | +  Builder* self = ALLOC(Builder);
 | 
	
		
			
				|  |  | +  VALUE ret = TypedData_Wrap_Struct(
 | 
	
		
			
				|  |  | +      klass, &_Builder_type, self);
 | 
	
		
			
				|  |  | +  self->pending_list = rb_ary_new();
 | 
	
		
			
				|  |  | +  self->defs = NULL;
 | 
	
		
			
				|  |  | +  return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void Builder_register(VALUE module) {
 | 
	
		
			
				|  |  | +  VALUE klass = rb_define_class_under(module, "Builder", rb_cObject);
 | 
	
		
			
				|  |  | +  rb_define_alloc_func(klass, Builder_alloc);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "add_message", Builder_add_message, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "add_enum", Builder_add_enum, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "finalize_to_pool", Builder_finalize_to_pool, 1);
 | 
	
		
			
				|  |  | +  cBuilder = klass;
 | 
	
		
			
				|  |  | +  rb_gc_register_address(&cBuilder);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     Builder.add_message(name, &block)
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Creates a new, empty descriptor with the given name, and invokes the block in
 | 
	
		
			
				|  |  | + * the context of a MessageBuilderContext on that descriptor. The block can then
 | 
	
		
			
				|  |  | + * call, e.g., MessageBuilderContext#optional and MessageBuilderContext#repeated
 | 
	
		
			
				|  |  | + * methods to define the message fields.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * This is the recommended, idiomatic way to build message definitions.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE Builder_add_message(VALUE _self, VALUE name) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(Builder, self, _self);
 | 
	
		
			
				|  |  | +  VALUE msgdef = rb_class_new_instance(0, NULL, cDescriptor);
 | 
	
		
			
				|  |  | +  VALUE ctx = rb_class_new_instance(1, &msgdef, cMessageBuilderContext);
 | 
	
		
			
				|  |  | +  VALUE block = rb_block_proc();
 | 
	
		
			
				|  |  | +  rb_funcall(msgdef, rb_intern("name="), 1, name);
 | 
	
		
			
				|  |  | +  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
 | 
	
		
			
				|  |  | +  rb_ary_push(self->pending_list, msgdef);
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     Builder.add_enum(name, &block)
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Creates a new, empty enum descriptor with the given name, and invokes the block in
 | 
	
		
			
				|  |  | + * the context of an EnumBuilderContext on that descriptor. The block can then
 | 
	
		
			
				|  |  | + * call EnumBuilderContext#add_value to define the enum values.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * This is the recommended, idiomatic way to build enum definitions.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE Builder_add_enum(VALUE _self, VALUE name) {
 | 
	
		
			
				|  |  | +  DEFINE_SELF(Builder, self, _self);
 | 
	
		
			
				|  |  | +  VALUE enumdef = rb_class_new_instance(0, NULL, cEnumDescriptor);
 | 
	
		
			
				|  |  | +  VALUE ctx = rb_class_new_instance(1, &enumdef, cEnumBuilderContext);
 | 
	
		
			
				|  |  | +  VALUE block = rb_block_proc();
 | 
	
		
			
				|  |  | +  rb_funcall(enumdef, rb_intern("name="), 1, name);
 | 
	
		
			
				|  |  | +  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
 | 
	
		
			
				|  |  | +  rb_ary_push(self->pending_list, enumdef);
 | 
	
		
			
				|  |  | +  return Qnil;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void validate_msgdef(const upb_msgdef* msgdef) {
 | 
	
		
			
				|  |  | +  // Verify that no required fields exist. proto3 does not support these.
 | 
	
		
			
				|  |  | +  upb_msg_iter it;
 | 
	
		
			
				|  |  | +  for (upb_msg_begin(&it, msgdef); !upb_msg_done(&it); upb_msg_next(&it)) {
 | 
	
		
			
				|  |  | +    const upb_fielddef* field = upb_msg_iter_field(&it);
 | 
	
		
			
				|  |  | +    if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) {
 | 
	
		
			
				|  |  | +      rb_raise(rb_eTypeError, "Required fields are unsupported in proto3.");
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void validate_enumdef(const upb_enumdef* enumdef) {
 | 
	
		
			
				|  |  | +  // Verify that an entry exists with integer value 0. (This is the default
 | 
	
		
			
				|  |  | +  // value.)
 | 
	
		
			
				|  |  | +  const char* lookup = upb_enumdef_iton(enumdef, 0);
 | 
	
		
			
				|  |  | +  if (lookup == NULL) {
 | 
	
		
			
				|  |  | +    rb_raise(rb_eTypeError,
 | 
	
		
			
				|  |  | +             "Enum definition does not contain a value for '0'.");
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * 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;
 | 
	
		
			
				|  |  | +}
 |