// 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 <ctype.h>
#include <errno.h>
#include "protobuf.h"

// -----------------------------------------------------------------------------
// Common utilities.
// -----------------------------------------------------------------------------

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 void rewrite_enum_default(const upb_symtab* symtab,
                                 google_protobuf_FileDescriptorProto* file,
                                 google_protobuf_FieldDescriptorProto* field) {
  upb_strview defaultval;
  const char *type_name_str;
  char *end;
  long val;
  const upb_enumdef *e;
  upb_strview type_name;

  /* Look for TYPE_ENUM fields that have a default. */
  if (google_protobuf_FieldDescriptorProto_type(field) !=
          google_protobuf_FieldDescriptorProto_TYPE_ENUM ||
      !google_protobuf_FieldDescriptorProto_has_default_value(field) ||
      !google_protobuf_FieldDescriptorProto_has_type_name(field)) {
    return;
  }

  defaultval = google_protobuf_FieldDescriptorProto_default_value(field);
  type_name = google_protobuf_FieldDescriptorProto_type_name(field);

  if (defaultval.size == 0 || !isdigit(defaultval.data[0])) {
    return;
  }

  if (type_name.size == 0 || type_name.data[0] != '.') {
    return;
  }

  type_name_str = type_name.data + 1;

  errno = 0;
  val = strtol(defaultval.data, &end, 10);

  if (errno != 0 || *end != 0 || val < INT32_MIN || val > INT32_MAX) {
    return;
  }

  /* Now find the corresponding enum definition. */
  e = upb_symtab_lookupenum(symtab, type_name_str);
  if (e) {
    /* Look in previously loaded files. */
    const char *label = upb_enumdef_iton(e, val);
    if (!label) {
      return;
    }
    google_protobuf_FieldDescriptorProto_set_default_value(
        field, upb_strview_makez(label));
  } else {
    /* Look in enums defined in this file. */
    const google_protobuf_EnumDescriptorProto* matching_enum = NULL;
    size_t i, n;
    const google_protobuf_EnumDescriptorProto* const* enums =
        google_protobuf_FileDescriptorProto_enum_type(file, &n);
    const google_protobuf_EnumValueDescriptorProto* const* values;

    for (i = 0; i < n; i++) {
      if (upb_strview_eql(google_protobuf_EnumDescriptorProto_name(enums[i]),
                          upb_strview_makez(type_name_str))) {
        matching_enum = enums[i];
        break;
      }
    }

    if (!matching_enum) {
      return;
    }

    values = google_protobuf_EnumDescriptorProto_value(matching_enum, &n);
    for (i = 0; i < n; i++) {
      if (google_protobuf_EnumValueDescriptorProto_number(values[i]) == val) {
        google_protobuf_FieldDescriptorProto_set_default_value(
            field, google_protobuf_EnumValueDescriptorProto_name(values[i]));
        return;
      }
    }

    /* We failed to find an enum default.  But we'll just leave the enum
     * untouched and let the normal def-building code catch it. */
  }
}

/* Historically we allowed enum defaults to be specified as a number.  In
 * retrospect this was a mistake as descriptors require defaults to be
 * specified as a label. This can make a difference if multiple labels have the
 * same number.
 *
 * Here we do a pass over all enum defaults and rewrite numeric defaults by
 * looking up their labels.  This is complicated by the fact that the enum
 * definition can live in either the symtab or the file_proto.
 * */
static void rewrite_enum_defaults(
    const upb_symtab* symtab, google_protobuf_FileDescriptorProto* file_proto) {
  size_t i, n;
  google_protobuf_DescriptorProto** msgs =
      google_protobuf_FileDescriptorProto_mutable_message_type(file_proto, &n);

  for (i = 0; i < n; i++) {
    size_t j, m;
    google_protobuf_FieldDescriptorProto** fields =
        google_protobuf_DescriptorProto_mutable_field(msgs[i], &m);
    for (j = 0; j < m; j++) {
      rewrite_enum_default(symtab, file_proto, fields[j]);
    }
  }
}

static void remove_path(upb_strview *name) {
  const char* last = strrchr(name->data, '.');
  if (last) {
    size_t remove = last - name->data + 1;
    name->data += remove;
    name->size -= remove;
  }
}

static void rewrite_nesting(VALUE msg_ent, google_protobuf_DescriptorProto* msg,
                            google_protobuf_DescriptorProto* const* msgs,
                            google_protobuf_EnumDescriptorProto* const* enums,
                            upb_arena *arena) {
  VALUE submsgs = rb_hash_aref(msg_ent, ID2SYM(rb_intern("msgs")));
  VALUE enum_pos = rb_hash_aref(msg_ent, ID2SYM(rb_intern("enums")));
  int submsg_count;
  int enum_count;
  int i;
  google_protobuf_DescriptorProto** msg_msgs;
  google_protobuf_EnumDescriptorProto** msg_enums;

  Check_Type(submsgs, T_ARRAY);
  Check_Type(enum_pos, T_ARRAY);

  submsg_count = RARRAY_LEN(submsgs);
  enum_count = RARRAY_LEN(enum_pos);

  msg_msgs = google_protobuf_DescriptorProto_resize_nested_type(
      msg, submsg_count, arena);
  msg_enums =
      google_protobuf_DescriptorProto_resize_enum_type(msg, enum_count, arena);

  for (i = 0; i < submsg_count; i++) {
    VALUE submsg_ent = RARRAY_PTR(submsgs)[i];
    VALUE pos = rb_hash_aref(submsg_ent, ID2SYM(rb_intern("pos")));
    upb_strview name;

    msg_msgs[i] = msgs[NUM2INT(pos)];
    name = google_protobuf_DescriptorProto_name(msg_msgs[i]);
    remove_path(&name);
    google_protobuf_DescriptorProto_set_name(msg_msgs[i], name);
    rewrite_nesting(submsg_ent, msg_msgs[i], msgs, enums, arena);
  }

  for (i = 0; i < enum_count; i++) {
    VALUE pos = RARRAY_PTR(enum_pos)[i];
    msg_enums[i] = enums[NUM2INT(pos)];
  }
}

/* We have to do some relatively complicated logic here for backward
 * compatibility.
 *
 * In descriptor.proto, messages are nested inside other messages if that is
 * what the original .proto file looks like.  For example, suppose we have this
 * foo.proto:
 *
 * package foo;
 * message Bar {
 *   message Baz {}
 * }
 *
 * The descriptor for this must look like this:
 *
 * file {
 *   name: "test.proto"
 *   package: "foo"
 *   message_type {
 *     name: "Bar"
 *     nested_type {
 *       name: "Baz"
 *     }
 *   }
 * }
 *
 * However, the Ruby generated code has always generated messages in a flat,
 * non-nested way:
 *
 * Google::Protobuf::DescriptorPool.generated_pool.build do
 *   add_message "foo.Bar" do
 *   end
 *   add_message "foo.Bar.Baz" do
 *   end
 * end
 *
 * Here we need to do a translation where we turn this generated code into the
 * above descriptor.  We need to infer that "foo" is the package name, and not
 * a message itself.
 *
 * We delegate to Ruby to compute the transformation, for more concice and
 * readable code than we can do in C */
static void rewrite_names(VALUE _file_builder,
                          google_protobuf_FileDescriptorProto* file_proto) {
  FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
  upb_arena *arena = file_builder->arena;
  // Build params (package, msg_names, enum_names).
  VALUE package = Qnil;
  VALUE msg_names = rb_ary_new();
  VALUE enum_names = rb_ary_new();
  size_t msg_count, enum_count, i;
  VALUE new_package, nesting, msg_ents, enum_ents;
  google_protobuf_DescriptorProto** msgs;
  google_protobuf_EnumDescriptorProto** enums;

  if (google_protobuf_FileDescriptorProto_has_package(file_proto)) {
    upb_strview package_str =
        google_protobuf_FileDescriptorProto_package(file_proto);
    package = rb_str_new(package_str.data, package_str.size);
  }

  msgs = google_protobuf_FileDescriptorProto_mutable_message_type(file_proto,
                                                                  &msg_count);
  for (i = 0; i < msg_count; i++) {
    upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
    rb_ary_push(msg_names, rb_str_new(name.data, name.size));
  }

  enums = google_protobuf_FileDescriptorProto_mutable_enum_type(file_proto,
                                                                &enum_count);
  for (i = 0; i < enum_count; i++) {
    upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
    rb_ary_push(enum_names, rb_str_new(name.data, name.size));
  }

  {
    // Call Ruby code to calculate package name and nesting.
    VALUE args[3] = { package, msg_names, enum_names };
    VALUE internal = rb_eval_string("Google::Protobuf::Internal");
    VALUE ret = rb_funcallv(internal, rb_intern("fixup_descriptor"), 3, args);

    new_package = rb_ary_entry(ret, 0);
    nesting = rb_ary_entry(ret, 1);
  }

  // Rewrite package and names.
  if (new_package != Qnil) {
    upb_strview new_package_str =
        FileBuilderContext_strdup(_file_builder, new_package);
    google_protobuf_FileDescriptorProto_set_package(file_proto,
                                                    new_package_str);
  }

  for (i = 0; i < msg_count; i++) {
    upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
    remove_path(&name);
    google_protobuf_DescriptorProto_set_name(msgs[i], name);
  }

  for (i = 0; i < enum_count; i++) {
    upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
    remove_path(&name);
    google_protobuf_EnumDescriptorProto_set_name(enums[i], name);
  }

  // Rewrite nesting.
  msg_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("msgs")));
  enum_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("enums")));

  Check_Type(msg_ents, T_ARRAY);
  Check_Type(enum_ents, T_ARRAY);

  for (i = 0; i < (size_t)RARRAY_LEN(msg_ents); i++) {
    VALUE msg_ent = rb_ary_entry(msg_ents, i);
    VALUE pos = rb_hash_aref(msg_ent, ID2SYM(rb_intern("pos")));
    msgs[i] = msgs[NUM2INT(pos)];
    rewrite_nesting(msg_ent, msgs[i], msgs, enums, arena);
  }

  for (i = 0; i < (size_t)RARRAY_LEN(enum_ents); i++) {
    VALUE enum_pos = rb_ary_entry(enum_ents, i);
    enums[i] = enums[NUM2INT(enum_pos)];
  }

  google_protobuf_FileDescriptorProto_resize_message_type(
      file_proto, RARRAY_LEN(msg_ents), arena);
  google_protobuf_FileDescriptorProto_resize_enum_type(
      file_proto, RARRAY_LEN(enum_ents), arena);
}

// -----------------------------------------------------------------------------
// DescriptorPool.
// -----------------------------------------------------------------------------

#define DEFINE_CLASS(name, string_name)                             \
    VALUE c ## name = Qnil;                                         \
    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 = Qnil;

DEFINE_CLASS(DescriptorPool, "Google::Protobuf::DescriptorPool");

void DescriptorPool_mark(void* _self) {
  DescriptorPool* self = _self;
  rb_gc_mark(self->def_to_descriptor);
}

void DescriptorPool_free(void* _self) {
  DescriptorPool* self = _self;

  upb_symtab_free(self->symtab);
  upb_handlercache_free(self->fill_handler_cache);
  upb_handlercache_free(self->pb_serialize_handler_cache);
  upb_handlercache_free(self->json_serialize_handler_cache);
  upb_handlercache_free(self->json_serialize_handler_preserve_cache);
  upb_pbcodecache_free(self->fill_method_cache);
  upb_json_codecache_free(self->json_fill_method_cache);

  xfree(self);
}

/*
 * call-seq:
 *     DescriptorPool.new => pool
 *
 * Creates a new, empty, descriptor pool.
 */
VALUE DescriptorPool_alloc(VALUE klass) {
  DescriptorPool* self = ALLOC(DescriptorPool);
  VALUE ret;

  self->def_to_descriptor = Qnil;
  ret = TypedData_Wrap_Struct(klass, &_DescriptorPool_type, self);

  self->def_to_descriptor = rb_hash_new();
  self->symtab = upb_symtab_new();
  self->fill_handler_cache =
      upb_handlercache_new(add_handlers_for_message, (void*)ret);
  self->pb_serialize_handler_cache = upb_pb_encoder_newcache();
  self->json_serialize_handler_cache = upb_json_printer_newcache(false);
  self->json_serialize_handler_preserve_cache =
      upb_json_printer_newcache(true);
  self->fill_method_cache = upb_pbcodecache_new(self->fill_handler_cache);
  self->json_fill_method_cache = upb_json_codecache_new();

  return ret;
}

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, "build", DescriptorPool_build, -1);
  rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
  rb_define_singleton_method(klass, "generated_pool",
                             DescriptorPool_generated_pool, 0);
  rb_gc_register_address(&cDescriptorPool);
  cDescriptorPool = klass;

  rb_gc_register_address(&generated_pool);
  generated_pool = rb_class_new_instance(0, NULL, klass);
}

/*
 * 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(int argc, VALUE* argv, VALUE _self) {
  VALUE ctx = rb_class_new_instance(1, &_self, cBuilder);
  VALUE block = rb_block_proc();
  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
  Builder_build(ctx);
  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_msgdef* msgdef;
  const upb_enumdef* enumdef;

  msgdef = upb_symtab_lookupmsg(self->symtab, name_str);
  if (msgdef) {
    return get_msgdef_obj(_self, msgdef);
  }

  enumdef = upb_symtab_lookupenum(self->symtab, name_str);
  if (enumdef) {
    return get_enumdef_obj(_self, enumdef);
  }

  return Qnil;
}

/*
 * 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);
  rb_gc_mark(self->descriptor_pool);
  if (self->layout && self->layout->empty_template) {
    layout_mark(self->layout, self->layout->empty_template);
  }
}

void Descriptor_free(void* _self) {
  Descriptor* self = _self;
  if (self->layout) {
    free_layout(self->layout);
  }
  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 = NULL;
  self->klass = Qnil;
  self->descriptor_pool = Qnil;
  self->layout = 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, "initialize", Descriptor_initialize, 3);
  rb_define_method(klass, "each", Descriptor_each, 0);
  rb_define_method(klass, "lookup", Descriptor_lookup, 1);
  rb_define_method(klass, "each_oneof", Descriptor_each_oneof, 0);
  rb_define_method(klass, "lookup_oneof", Descriptor_lookup_oneof, 1);
  rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
  rb_define_method(klass, "name", Descriptor_name, 0);
  rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
  rb_include_module(klass, rb_mEnumerable);
  rb_gc_register_address(&cDescriptor);
  cDescriptor = klass;
}

/*
 * call-seq:
 *    Descriptor.new(c_only_cookie, ptr) => Descriptor
 *
 * Creates a descriptor wrapper object.  May only be called from C.
 */
VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
                            VALUE descriptor_pool, VALUE ptr) {
  DEFINE_SELF(Descriptor, self, _self);

  if (cookie != c_only_cookie) {
    rb_raise(rb_eRuntimeError,
             "Descriptor objects may not be created from Ruby.");
  }

  self->descriptor_pool = descriptor_pool;
  self->msgdef = (const upb_msgdef*)NUM2ULL(ptr);

  return Qnil;
}

/*
 * call-seq:
 *    Descriptor.file_descriptor
 *
 * Returns the FileDescriptor object this message belongs to.
 */
VALUE Descriptor_file_descriptor(VALUE _self) {
  DEFINE_SELF(Descriptor, self, _self);
  return get_filedef_obj(self->descriptor_pool, upb_msgdef_file(self->msgdef));
}

/*
 * call-seq:
 *     Descriptor.name => name
 *
 * Returns the name of this message type as a fully-qualified 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.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_field_iter it;
  for (upb_msg_field_begin(&it, self->msgdef);
       !upb_msg_field_done(&it);
       upb_msg_field_next(&it)) {
    const upb_fielddef* field = upb_msg_iter_field(&it);
    VALUE obj = get_fielddef_obj(self->descriptor_pool, 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_fielddef_obj(self->descriptor_pool, field);
}

/*
 * call-seq:
 *     Descriptor.each_oneof(&block) => nil
 *
 * Invokes the given block for each oneof in this message type, passing the
 * corresponding OneofDescriptor.
 */
VALUE Descriptor_each_oneof(VALUE _self) {
  DEFINE_SELF(Descriptor, self, _self);

  upb_msg_oneof_iter it;
  for (upb_msg_oneof_begin(&it, self->msgdef);
       !upb_msg_oneof_done(&it);
       upb_msg_oneof_next(&it)) {
    const upb_oneofdef* oneof = upb_msg_iter_oneof(&it);
    VALUE obj = get_oneofdef_obj(self->descriptor_pool, oneof);
    rb_yield(obj);
  }
  return Qnil;
}

/*
 * call-seq:
 *     Descriptor.lookup_oneof(name) => OneofDescriptor
 *
 * Returns the oneof descriptor for the oneof with the given name, if present,
 * or nil if none.
 */
VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
  DEFINE_SELF(Descriptor, self, _self);
  const char* s = get_str(name);
  const upb_oneofdef* oneof = upb_msgdef_ntooz(self->msgdef, s);
  if (oneof == NULL) {
    return Qnil;
  }
  return get_oneofdef_obj(self->descriptor_pool, oneof);
}

/*
 * call-seq:
 *     Descriptor.msgclass => message_klass
 *
 * Returns the Ruby class created for this message type.
 */
VALUE Descriptor_msgclass(VALUE _self) {
  DEFINE_SELF(Descriptor, self, _self);
  if (self->klass == Qnil) {
    self->klass = build_class_from_descriptor(_self);
  }
  return self->klass;
}

// -----------------------------------------------------------------------------
// FileDescriptor.
// -----------------------------------------------------------------------------

DEFINE_CLASS(FileDescriptor, "Google::Protobuf::FileDescriptor");

void FileDescriptor_mark(void* _self) {
  FileDescriptor* self = _self;
  rb_gc_mark(self->descriptor_pool);
}

void FileDescriptor_free(void* _self) {
  xfree(_self);
}

VALUE FileDescriptor_alloc(VALUE klass) {
  FileDescriptor* self = ALLOC(FileDescriptor);
  VALUE ret = TypedData_Wrap_Struct(klass, &_FileDescriptor_type, self);
  self->descriptor_pool = Qnil;
  self->filedef = NULL;
  return ret;
}

/*
 * call-seq:
 *     FileDescriptor.new => file
 *
 * Returns a new file descriptor. The syntax must be set before it's passed
 * to a builder.
 */
VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
                                VALUE descriptor_pool, VALUE ptr) {
  DEFINE_SELF(FileDescriptor, self, _self);

  if (cookie != c_only_cookie) {
    rb_raise(rb_eRuntimeError,
             "Descriptor objects may not be created from Ruby.");
  }

  self->descriptor_pool = descriptor_pool;
  self->filedef = (const upb_filedef*)NUM2ULL(ptr);

  return Qnil;
}

void FileDescriptor_register(VALUE module) {
  VALUE klass = rb_define_class_under(
      module, "FileDescriptor", rb_cObject);
  rb_define_alloc_func(klass, FileDescriptor_alloc);
  rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
  rb_define_method(klass, "name", FileDescriptor_name, 0);
  rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
  rb_gc_register_address(&cFileDescriptor);
  cFileDescriptor = klass;
}

/*
 * call-seq:
 *     FileDescriptor.name => name
 *
 * Returns the name of the file.
 */
VALUE FileDescriptor_name(VALUE _self) {
  DEFINE_SELF(FileDescriptor, self, _self);
  const char* name = upb_filedef_name(self->filedef);
  return name == NULL ? Qnil : rb_str_new2(name);
}

/*
 * call-seq:
 *     FileDescriptor.syntax => syntax
 *
 * Returns this file descriptors syntax.
 *
 * Valid syntax versions are:
 *     :proto2 or :proto3.
 */
VALUE FileDescriptor_syntax(VALUE _self) {
  DEFINE_SELF(FileDescriptor, self, _self);

  switch (upb_filedef_syntax(self->filedef)) {
    case UPB_SYNTAX_PROTO3: return ID2SYM(rb_intern("proto3"));
    case UPB_SYNTAX_PROTO2: return ID2SYM(rb_intern("proto2"));
    default: return Qnil;
  }
}

// -----------------------------------------------------------------------------
// FieldDescriptor.
// -----------------------------------------------------------------------------

DEFINE_CLASS(FieldDescriptor, "Google::Protobuf::FieldDescriptor");

void FieldDescriptor_mark(void* _self) {
  FieldDescriptor* self = _self;
  rb_gc_mark(self->descriptor_pool);
}

void FieldDescriptor_free(void* _self) {
  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);
  self->fielddef = NULL;
  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, "initialize", FieldDescriptor_initialize, 3);
  rb_define_method(klass, "name", FieldDescriptor_name, 0);
  rb_define_method(klass, "type", FieldDescriptor_type, 0);
  rb_define_method(klass, "default", FieldDescriptor_default, 0);
  rb_define_method(klass, "label", FieldDescriptor_label, 0);
  rb_define_method(klass, "number", FieldDescriptor_number, 0);
  rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
  rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0);
  rb_define_method(klass, "has?", FieldDescriptor_has, 1);
  rb_define_method(klass, "clear", FieldDescriptor_clear, 1);
  rb_define_method(klass, "get", FieldDescriptor_get, 1);
  rb_define_method(klass, "set", FieldDescriptor_set, 2);
  rb_gc_register_address(&cFieldDescriptor);
  cFieldDescriptor = klass;
}

/*
 * call-seq:
 *    EnumDescriptor.new(c_only_cookie, pool, ptr) => EnumDescriptor
 *
 * Creates a descriptor wrapper object.  May only be called from C.
 */
VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
                                 VALUE descriptor_pool, VALUE ptr) {
  DEFINE_SELF(FieldDescriptor, self, _self);

  if (cookie != c_only_cookie) {
    rb_raise(rb_eRuntimeError,
             "Descriptor objects may not be created from Ruby.");
  }

  self->descriptor_pool = descriptor_pool;
  self->fielddef = (const upb_fielddef*)NUM2ULL(ptr);

  return Qnil;
}

/*
 * 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));
}

upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
  if (TYPE(type) != T_SYMBOL) {
    rb_raise(rb_eArgError, "Expected symbol for field type.");
  }

#define CONVERT(upb, ruby)                                           \
  if (SYM2ID(type) == rb_intern( # ruby )) {                         \
    return 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

  rb_raise(rb_eArgError, "Unknown field type.");
  return 0;
}

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;
}

upb_descriptortype_t ruby_to_descriptortype(VALUE type) {
  if (TYPE(type) != T_SYMBOL) {
    rb_raise(rb_eArgError, "Expected symbol for field type.");
  }

#define CONVERT(upb, ruby)                                           \
  if (SYM2ID(type) == rb_intern( # ruby )) {                         \
    return UPB_DESCRIPTOR_TYPE_ ## upb;                              \
  }

  CONVERT(FLOAT, float);
  CONVERT(DOUBLE, double);
  CONVERT(BOOL, bool);
  CONVERT(STRING, string);
  CONVERT(BYTES, bytes);
  CONVERT(MESSAGE, message);
  CONVERT(GROUP, group);
  CONVERT(ENUM, enum);
  CONVERT(INT32, int32);
  CONVERT(INT64, int64);
  CONVERT(UINT32, uint32);
  CONVERT(UINT64, uint64);
  CONVERT(SINT32, sint32);
  CONVERT(SINT64, sint64);
  CONVERT(FIXED32, fixed32);
  CONVERT(FIXED64, fixed64);
  CONVERT(SFIXED32, sfixed32);
  CONVERT(SFIXED64, sfixed64);

#undef CONVERT

  rb_raise(rb_eArgError, "Unknown field type.");
  return 0;
}

VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
  switch (type) {
#define CONVERT(upb, ruby)                                           \
    case UPB_DESCRIPTOR_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(GROUP, group);
    CONVERT(ENUM, enum);
    CONVERT(INT32, int32);
    CONVERT(INT64, int64);
    CONVERT(UINT32, uint32);
    CONVERT(UINT64, uint64);
    CONVERT(SINT32, sint32);
    CONVERT(SINT64, sint64);
    CONVERT(FIXED32, fixed32);
    CONVERT(FIXED64, fixed64);
    CONVERT(SFIXED32, sfixed32);
    CONVERT(SFIXED64, sfixed64);
#undef CONVERT
  }
  return Qnil;
}

VALUE ruby_to_label(VALUE label) {
  upb_label_t upb_label;
  bool converted = false;

#define CONVERT(upb, ruby)                                           \
  if (SYM2ID(label) == rb_intern( # ruby )) {                        \
    upb_label = UPB_LABEL_ ## upb;                                   \
    converted = true;                                                \
  }

  CONVERT(OPTIONAL, optional);
  CONVERT(REQUIRED, required);
  CONVERT(REPEATED, repeated);

#undef CONVERT

  if (!converted) {
    rb_raise(rb_eArgError, "Unknown field label.");
  }

  return upb_label;
}

/*
 * 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);
  return descriptortype_to_ruby(upb_fielddef_descriptortype(self->fielddef));
}

/*
 * call-seq:
 *     FieldDescriptor.default => default
 *
 * Returns this field's default, as a Ruby object, or nil if not yet set.
 */
VALUE FieldDescriptor_default(VALUE _self) {
  DEFINE_SELF(FieldDescriptor, self, _self);
  return layout_get_default(self->fielddef);
}

/*
 * 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.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.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);
  switch (upb_fielddef_type(self->fielddef)) {
    case UPB_TYPE_ENUM:
      return rb_str_new2(
          upb_enumdef_fullname(upb_fielddef_enumsubdef(self->fielddef)));
    case UPB_TYPE_MESSAGE:
      return rb_str_new2(
          upb_msgdef_fullname(upb_fielddef_msgsubdef(self->fielddef)));
    default:
      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);
  switch (upb_fielddef_type(self->fielddef)) {
    case UPB_TYPE_ENUM:
      return get_enumdef_obj(self->descriptor_pool,
                             upb_fielddef_enumsubdef(self->fielddef));
    case UPB_TYPE_MESSAGE:
      return get_msgdef_obj(self->descriptor_pool,
                            upb_fielddef_msgsubdef(self->fielddef));
    default:
      return Qnil;
  }
}

/*
 * 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(cTypeError, "get method called on wrong message type");
  }
  return layout_get(msg->descriptor->layout, Message_data(msg), self->fielddef);
}

/*
 * call-seq:
 *     FieldDescriptor.has?(message) => boolean
 *
 * Returns whether the value is set on the given message. Raises an
 * exception when calling for fields that do not have presence.
 */
VALUE FieldDescriptor_has(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(cTypeError, "has method called on wrong message type");
  } else if (!upb_fielddef_haspresence(self->fielddef)) {
    rb_raise(rb_eArgError, "does not track presence");
  }

  return layout_has(msg->descriptor->layout, Message_data(msg), self->fielddef);
}

/*
 * call-seq:
 *     FieldDescriptor.clear(message)
 *
 * Clears the field from the message if it's set.
 */
VALUE FieldDescriptor_clear(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(cTypeError, "has method called on wrong message type");
  }

  layout_clear(msg->descriptor->layout, Message_data(msg), self->fielddef);
  return Qnil;
}

/*
 * 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(cTypeError, "set method called on wrong message type");
  }
  layout_set(msg->descriptor->layout, Message_data(msg), self->fielddef, value);
  return Qnil;
}

// -----------------------------------------------------------------------------
// OneofDescriptor.
// -----------------------------------------------------------------------------

DEFINE_CLASS(OneofDescriptor, "Google::Protobuf::OneofDescriptor");

void OneofDescriptor_mark(void* _self) {
  OneofDescriptor* self = _self;
  rb_gc_mark(self->descriptor_pool);
}

void OneofDescriptor_free(void* _self) {
  xfree(_self);
}

/*
 * call-seq:
 *     OneofDescriptor.new => oneof_descriptor
 *
 * Creates a new, empty, oneof descriptor. The oneof may only be modified prior
 * to being added to a message descriptor which is subsequently added to a pool.
 */
VALUE OneofDescriptor_alloc(VALUE klass) {
  OneofDescriptor* self = ALLOC(OneofDescriptor);
  VALUE ret = TypedData_Wrap_Struct(klass, &_OneofDescriptor_type, self);
  self->oneofdef = NULL;
  self->descriptor_pool = Qnil;
  return ret;
}

void OneofDescriptor_register(VALUE module) {
  VALUE klass = rb_define_class_under(
      module, "OneofDescriptor", rb_cObject);
  rb_define_alloc_func(klass, OneofDescriptor_alloc);
  rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
  rb_define_method(klass, "name", OneofDescriptor_name, 0);
  rb_define_method(klass, "each", OneofDescriptor_each, 0);
  rb_include_module(klass, rb_mEnumerable);
  rb_gc_register_address(&cOneofDescriptor);
  cOneofDescriptor = klass;
}

/*
 * call-seq:
 *    OneofDescriptor.new(c_only_cookie, pool, ptr) => OneofDescriptor
 *
 * Creates a descriptor wrapper object.  May only be called from C.
 */
VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
                                 VALUE descriptor_pool, VALUE ptr) {
  DEFINE_SELF(OneofDescriptor, self, _self);

  if (cookie != c_only_cookie) {
    rb_raise(rb_eRuntimeError,
             "Descriptor objects may not be created from Ruby.");
  }

  self->descriptor_pool = descriptor_pool;
  self->oneofdef = (const upb_oneofdef*)NUM2ULL(ptr);

  return Qnil;
}

/*
 * call-seq:
 *     OneofDescriptor.name => name
 *
 * Returns the name of this oneof.
 */
VALUE OneofDescriptor_name(VALUE _self) {
  DEFINE_SELF(OneofDescriptor, self, _self);
  return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef));
}

/*
 * call-seq:
 *     OneofDescriptor.each(&block) => nil
 *
 * Iterates through fields in this oneof, yielding to the block on each one.
 */
VALUE OneofDescriptor_each(VALUE _self) {
  DEFINE_SELF(OneofDescriptor, self, _self);
  upb_oneof_iter it;
  for (upb_oneof_begin(&it, self->oneofdef);
       !upb_oneof_done(&it);
       upb_oneof_next(&it)) {
    const upb_fielddef* f = upb_oneof_iter_field(&it);
    VALUE obj = get_fielddef_obj(self->descriptor_pool, f);
    rb_yield(obj);
  }
  return Qnil;
}

// -----------------------------------------------------------------------------
// EnumDescriptor.
// -----------------------------------------------------------------------------

DEFINE_CLASS(EnumDescriptor, "Google::Protobuf::EnumDescriptor");

void EnumDescriptor_mark(void* _self) {
  EnumDescriptor* self = _self;
  rb_gc_mark(self->module);
  rb_gc_mark(self->descriptor_pool);
}

void EnumDescriptor_free(void* _self) {
  xfree(_self);
}

VALUE EnumDescriptor_alloc(VALUE klass) {
  EnumDescriptor* self = ALLOC(EnumDescriptor);
  VALUE ret = TypedData_Wrap_Struct(klass, &_EnumDescriptor_type, self);
  self->enumdef = NULL;
  self->module = Qnil;
  self->descriptor_pool = Qnil;
  return ret;
}

/*
 * call-seq:
 *    EnumDescriptor.new(c_only_cookie, ptr) => EnumDescriptor
 *
 * Creates a descriptor wrapper object.  May only be called from C.
 */
VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
                                VALUE descriptor_pool, VALUE ptr) {
  DEFINE_SELF(EnumDescriptor, self, _self);

  if (cookie != c_only_cookie) {
    rb_raise(rb_eRuntimeError,
             "Descriptor objects may not be created from Ruby.");
  }

  self->descriptor_pool = descriptor_pool;
  self->enumdef = (const upb_enumdef*)NUM2ULL(ptr);

  return Qnil;
}

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, "initialize", EnumDescriptor_initialize, 3);
  rb_define_method(klass, "name", EnumDescriptor_name, 0);
  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_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
  rb_include_module(klass, rb_mEnumerable);
  rb_gc_register_address(&cEnumDescriptor);
  cEnumDescriptor = klass;
}

/*
 * call-seq:
 *    EnumDescriptor.file_descriptor
 *
 * Returns the FileDescriptor object this enum belongs to.
 */
VALUE EnumDescriptor_file_descriptor(VALUE _self) {
  DEFINE_SELF(EnumDescriptor, self, _self);
  return get_filedef_obj(self->descriptor_pool,
                         upb_enumdef_file(self->enumdef));
}

/*
 * 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.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.
 */
VALUE EnumDescriptor_enummodule(VALUE _self) {
  DEFINE_SELF(EnumDescriptor, self, _self);
  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->file_builder);
}

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->file_builder = 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, 2);
  rb_define_method(klass, "optional", MessageBuilderContext_optional, -1);
  rb_define_method(klass, "proto3_optional", MessageBuilderContext_proto3_optional, -1);
  rb_define_method(klass, "required", MessageBuilderContext_required, -1);
  rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1);
  rb_define_method(klass, "map", MessageBuilderContext_map, -1);
  rb_define_method(klass, "oneof", MessageBuilderContext_oneof, 1);
  rb_gc_register_address(&cMessageBuilderContext);
  cMessageBuilderContext = klass;
}

/*
 * call-seq:
 *     MessageBuilderContext.new(file_builder, name) => context
 *
 * Create a new message builder context around the given message descriptor and
 * builder context. This class is intended to serve as a DSL context to be used
 * with #instance_eval.
 */
VALUE MessageBuilderContext_initialize(VALUE _self,
                                       VALUE _file_builder,
                                       VALUE name) {
  DEFINE_SELF(MessageBuilderContext, self, _self);
  FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
  google_protobuf_FileDescriptorProto* file_proto = file_builder->file_proto;

  self->file_builder = _file_builder;
  self->msg_proto = google_protobuf_FileDescriptorProto_add_message_type(
      file_proto, file_builder->arena);

  google_protobuf_DescriptorProto_set_name(
      self->msg_proto, FileBuilderContext_strdup(_file_builder, name));

  return Qnil;
}

static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name,
                             VALUE type, VALUE number, VALUE type_class,
                             VALUE options, int oneof_index,
                             bool proto3_optional) {
  DEFINE_SELF(MessageBuilderContext, self, msgbuilder_rb);
  FileBuilderContext* file_context =
      ruby_to_FileBuilderContext(self->file_builder);
  google_protobuf_FieldDescriptorProto* field_proto;
  VALUE name_str;

  field_proto = google_protobuf_DescriptorProto_add_field(self->msg_proto,
                                                          file_context->arena);

  Check_Type(name, T_SYMBOL);
  name_str = rb_id2str(SYM2ID(name));

  google_protobuf_FieldDescriptorProto_set_name(
      field_proto, FileBuilderContext_strdup(self->file_builder, name_str));
  google_protobuf_FieldDescriptorProto_set_number(field_proto, NUM2INT(number));
  google_protobuf_FieldDescriptorProto_set_label(field_proto, (int)label);
  google_protobuf_FieldDescriptorProto_set_type(
      field_proto, (int)ruby_to_descriptortype(type));

  if (proto3_optional) {
    google_protobuf_FieldDescriptorProto_set_proto3_optional(field_proto, true);
  }

  if (type_class != Qnil) {
    Check_Type(type_class, T_STRING);

    // Make it an absolute type name by prepending a dot.
    type_class = rb_str_append(rb_str_new2("."), type_class);
    google_protobuf_FieldDescriptorProto_set_type_name(
        field_proto, FileBuilderContext_strdup(self->file_builder, type_class));
  }

  if (options != Qnil) {
    Check_Type(options, T_HASH);

    if (rb_funcall(options, rb_intern("key?"), 1,
                   ID2SYM(rb_intern("default"))) == Qtrue) {
      VALUE default_value =
          rb_hash_lookup(options, ID2SYM(rb_intern("default")));

      /* Call #to_s since all defaults are strings in the descriptor. */
      default_value = rb_funcall(default_value, rb_intern("to_s"), 0);

      google_protobuf_FieldDescriptorProto_set_default_value(
          field_proto,
          FileBuilderContext_strdup(self->file_builder, default_value));
    }
  }

  if (oneof_index >= 0) {
    google_protobuf_FieldDescriptorProto_set_oneof_index(field_proto,
                                                         oneof_index);
  }
}

static VALUE make_mapentry(VALUE _message_builder, VALUE types, int argc,
                           VALUE* argv) {
  DEFINE_SELF(MessageBuilderContext, message_builder, _message_builder);
  VALUE type_class = rb_ary_entry(types, 2);
  FileBuilderContext* file_context =
      ruby_to_FileBuilderContext(message_builder->file_builder);
  google_protobuf_MessageOptions* options =
      google_protobuf_DescriptorProto_mutable_options(
          message_builder->msg_proto, file_context->arena);

  google_protobuf_MessageOptions_set_map_entry(options, true);

  // optional <type> key = 1;
  rb_funcall(_message_builder, rb_intern("optional"), 3,
             ID2SYM(rb_intern("key")), rb_ary_entry(types, 0), INT2NUM(1));

  // optional <type> value = 2;
  if (type_class == Qnil) {
    rb_funcall(_message_builder, rb_intern("optional"), 3,
               ID2SYM(rb_intern("value")), rb_ary_entry(types, 1), INT2NUM(2));
  } else {
    rb_funcall(_message_builder, rb_intern("optional"), 4,
               ID2SYM(rb_intern("value")), rb_ary_entry(types, 1), INT2NUM(2),
               type_class);
  }

  return Qnil;
}

/*
 * call-seq:
 *     MessageBuilderContext.optional(name, type, number, type_class = nil,
 *                                    options = 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) {
  VALUE name, type, number;
  VALUE type_class, options = Qnil;

  rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);

  // Allow passing (name, type, number, options) or
  // (name, type, number, type_class, options)
  if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
    options = type_class;
    type_class = Qnil;
  }

  msgdef_add_field(_self, UPB_LABEL_OPTIONAL, name, type, number, type_class,
                   options, -1, false);

  return Qnil;
}

/*
 * call-seq:
 *     MessageBuilderContext.proto3_optional(name, type, number,
 *                                           type_class = nil, options = nil)
 *
 * Defines a true proto3 optional field (that tracks presence) 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_proto3_optional(int argc, VALUE* argv,
                                            VALUE _self) {
  VALUE name, type, number;
  VALUE type_class, options = Qnil;

  rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);

  // Allow passing (name, type, number, options) or
  // (name, type, number, type_class, options)
  if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
    options = type_class;
    type_class = Qnil;
  }

  msgdef_add_field(_self, UPB_LABEL_OPTIONAL, name, type, number, type_class,
                   options, -1, true);

  return Qnil;
}

/*
 * call-seq:
 *     MessageBuilderContext.required(name, type, number, type_class = nil,
 *                                    options = 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) {
  VALUE name, type, number;
  VALUE type_class, options = Qnil;

  rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);

  // Allow passing (name, type, number, options) or
  // (name, type, number, type_class, options)
  if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
    options = type_class;
    type_class = Qnil;
  }

  msgdef_add_field(_self, UPB_LABEL_REQUIRED, name, type, number, type_class,
                   options, -1, false);

  return Qnil;
}

/*
 * 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) {
  VALUE name, type, number, type_class;

  if (argc < 3) {
    rb_raise(rb_eArgError, "Expected at least 3 arguments.");
  }
  name = argv[0];
  type = argv[1];
  number = argv[2];
  type_class = (argc > 3) ? argv[3] : Qnil;

  msgdef_add_field(_self, UPB_LABEL_REPEATED, name, type, number, type_class,
                   Qnil, -1, false);

  return Qnil;
}

/*
 * call-seq:
 *     MessageBuilderContext.map(name, key_type, value_type, number,
 *                               value_type_class = nil)
 *
 * Defines a new map field on this message type with the given key and value
 * types, tag number, and type class (for message and enum value types). The key
 * type must be :int32/:uint32/:int64/:uint64, :bool, or :string. The value type
 * 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_map(int argc, VALUE* argv, VALUE _self) {
  DEFINE_SELF(MessageBuilderContext, self, _self);
  VALUE name, key_type, value_type, number, type_class;
  VALUE mapentry_desc_name;
  FileBuilderContext* file_builder;
  upb_strview msg_name;

  if (argc < 4) {
    rb_raise(rb_eArgError, "Expected at least 4 arguments.");
  }
  name = argv[0];
  key_type = argv[1];
  value_type = argv[2];
  number = argv[3];
  type_class = (argc > 4) ? argv[4] : Qnil;

  // Validate the key type. We can't accept enums, messages, or floats/doubles
  // as map keys. (We exclude these explicitly, and the field-descriptor setter
  // below then ensures that the type is one of the remaining valid options.)
  if (SYM2ID(key_type) == rb_intern("float") ||
      SYM2ID(key_type) == rb_intern("double") ||
      SYM2ID(key_type) == rb_intern("enum") ||
      SYM2ID(key_type) == rb_intern("message")) {
    rb_raise(rb_eArgError,
             "Cannot add a map field with a float, double, enum, or message "
             "type.");
  }

  file_builder = ruby_to_FileBuilderContext(self->file_builder);

  // TODO(haberman): remove this restriction, maps are supported in proto2.
  if (upb_strview_eql(
          google_protobuf_FileDescriptorProto_syntax(file_builder->file_proto),
          upb_strview_makez("proto2"))) {
    rb_raise(rb_eArgError,
             "Cannot add a native map field using proto2 syntax.");
  }

  // Create a new message descriptor for the map entry message, and create a
  // repeated submessage field here with that type.
  msg_name = google_protobuf_DescriptorProto_name(self->msg_proto);
  mapentry_desc_name = rb_str_new(msg_name.data, msg_name.size);
  mapentry_desc_name = rb_str_cat2(mapentry_desc_name, "_MapEntry_");
  mapentry_desc_name =
      rb_str_cat2(mapentry_desc_name, rb_id2name(SYM2ID(name)));

  {
    // message <msgname>_MapEntry_ { /* ... */ }
    VALUE args[1] = {mapentry_desc_name};
    VALUE types = rb_ary_new3(3, key_type, value_type, type_class);
    rb_block_call(self->file_builder, rb_intern("add_message"), 1, args,
                  make_mapentry, types);
  }

  // If this file is in a package, we need to qualify the map entry type.
  if (google_protobuf_FileDescriptorProto_has_package(file_builder->file_proto)) {
    upb_strview package_view =
        google_protobuf_FileDescriptorProto_package(file_builder->file_proto);
    VALUE package = rb_str_new(package_view.data, package_view.size);
    package = rb_str_cat2(package, ".");
    mapentry_desc_name = rb_str_concat(package, mapentry_desc_name);
  }

  // repeated MapEntry <name> = <number>;
  rb_funcall(_self, rb_intern("repeated"), 4, name,
             ID2SYM(rb_intern("message")), number, mapentry_desc_name);

  return Qnil;
}

/*
 * call-seq:
 *     MessageBuilderContext.oneof(name, &block) => nil
 *
 * Creates a new OneofDescriptor with the given name, creates a
 * OneofBuilderContext attached to that OneofDescriptor, evaluates the given
 * block in the context of that OneofBuilderContext with #instance_eval, and
 * then adds the oneof to the message.
 *
 * This is the recommended, idiomatic way to build oneof definitions.
 */
VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) {
  DEFINE_SELF(MessageBuilderContext, self, _self);
  size_t oneof_count;
  FileBuilderContext* file_context =
      ruby_to_FileBuilderContext(self->file_builder);
  google_protobuf_OneofDescriptorProto* oneof_proto;

  // Existing oneof_count becomes oneof_index.
  google_protobuf_DescriptorProto_oneof_decl(self->msg_proto, &oneof_count);

  // Create oneof_proto and set its name.
  oneof_proto = google_protobuf_DescriptorProto_add_oneof_decl(
      self->msg_proto, file_context->arena);
  google_protobuf_OneofDescriptorProto_set_name(
      oneof_proto, FileBuilderContext_strdup_sym(self->file_builder, name));

  // Evaluate the block with the builder as argument.
  {
    VALUE args[2] = { INT2NUM(oneof_count), _self };
    VALUE ctx = rb_class_new_instance(2, args, cOneofBuilderContext);
    VALUE block = rb_block_proc();
    rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
  }

  return Qnil;
}

void MessageBuilderContext_add_synthetic_oneofs(VALUE _self) {
  DEFINE_SELF(MessageBuilderContext, self, _self);
  FileBuilderContext* file_context =
      ruby_to_FileBuilderContext(self->file_builder);
  size_t field_count, oneof_count;
  google_protobuf_FieldDescriptorProto** fields =
      google_protobuf_DescriptorProto_mutable_field(self->msg_proto, &field_count);
  const google_protobuf_OneofDescriptorProto*const* oneofs =
      google_protobuf_DescriptorProto_oneof_decl(self->msg_proto, &oneof_count);
  VALUE names = rb_hash_new();
  VALUE underscore = rb_str_new2("_");
  size_t i;

  // We have to build a set of all names, to ensure that synthetic oneofs are
  // not creating conflicts.
  for (i = 0; i < field_count; i++) {
    upb_strview name = google_protobuf_FieldDescriptorProto_name(fields[i]);
    rb_hash_aset(names, rb_str_new(name.data, name.size), Qtrue);
  }
  for (i = 0; i < oneof_count; i++) {
    upb_strview name = google_protobuf_OneofDescriptorProto_name(oneofs[i]);
    rb_hash_aset(names, rb_str_new(name.data, name.size), Qtrue);
  }

  for (i = 0; i < field_count; i++) {
    google_protobuf_OneofDescriptorProto* oneof_proto;
    VALUE oneof_name;
    upb_strview field_name;

    if (!google_protobuf_FieldDescriptorProto_proto3_optional(fields[i])) {
      continue;
    }

    // Prepend '_' until we are no longer conflicting.
    field_name = google_protobuf_FieldDescriptorProto_name(fields[i]);
    oneof_name = rb_str_new(field_name.data, field_name.size);
    while (rb_hash_lookup(names, oneof_name) != Qnil) {
      oneof_name = rb_str_plus(underscore, oneof_name);
    }

    rb_hash_aset(names, oneof_name, Qtrue);
    google_protobuf_FieldDescriptorProto_set_oneof_index(fields[i],
                                                         oneof_count++);
    oneof_proto = google_protobuf_DescriptorProto_add_oneof_decl(
        self->msg_proto, file_context->arena);
    google_protobuf_OneofDescriptorProto_set_name(
        oneof_proto, FileBuilderContext_strdup(self->file_builder, oneof_name));
  }
}

// -----------------------------------------------------------------------------
// OneofBuilderContext.
// -----------------------------------------------------------------------------

DEFINE_CLASS(OneofBuilderContext,
    "Google::Protobuf::Internal::OneofBuilderContext");

void OneofBuilderContext_mark(void* _self) {
  OneofBuilderContext* self = _self;
  rb_gc_mark(self->message_builder);
}

void OneofBuilderContext_free(void* _self) {
  xfree(_self);
}

VALUE OneofBuilderContext_alloc(VALUE klass) {
  OneofBuilderContext* self = ALLOC(OneofBuilderContext);
  VALUE ret = TypedData_Wrap_Struct(
      klass, &_OneofBuilderContext_type, self);
  self->oneof_index = 0;
  self->message_builder = Qnil;
  return ret;
}

void OneofBuilderContext_register(VALUE module) {
  VALUE klass = rb_define_class_under(
      module, "OneofBuilderContext", rb_cObject);
  rb_define_alloc_func(klass, OneofBuilderContext_alloc);
  rb_define_method(klass, "initialize",
                   OneofBuilderContext_initialize, 2);
  rb_define_method(klass, "optional", OneofBuilderContext_optional, -1);
  rb_gc_register_address(&cOneofBuilderContext);
  cOneofBuilderContext = klass;
}

/*
 * call-seq:
 *     OneofBuilderContext.new(oneof_index, message_builder) => context
 *
 * Create a new oneof builder context around the given oneof descriptor and
 * builder context. This class is intended to serve as a DSL context to be used
 * with #instance_eval.
 */
VALUE OneofBuilderContext_initialize(VALUE _self,
                                     VALUE oneof_index,
                                     VALUE message_builder) {
  DEFINE_SELF(OneofBuilderContext, self, _self);
  self->oneof_index = NUM2INT(oneof_index);
  self->message_builder = message_builder;
  return Qnil;
}

/*
 * call-seq:
 *     OneofBuilderContext.optional(name, type, number, type_class = nil,
 *                                  default_value = nil)
 *
 * Defines a new optional field in this oneof 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 OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
  DEFINE_SELF(OneofBuilderContext, self, _self);
  VALUE name, type, number;
  VALUE type_class, options = Qnil;

  rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);

  msgdef_add_field(self->message_builder, UPB_LABEL_OPTIONAL, name, type,
                   number, type_class, options, self->oneof_index, false);

  return Qnil;
}

// -----------------------------------------------------------------------------
// EnumBuilderContext.
// -----------------------------------------------------------------------------

DEFINE_CLASS(EnumBuilderContext,
    "Google::Protobuf::Internal::EnumBuilderContext");

void EnumBuilderContext_mark(void* _self) {
  EnumBuilderContext* self = _self;
  rb_gc_mark(self->file_builder);
}

void EnumBuilderContext_free(void* _self) {
  xfree(_self);
}

VALUE EnumBuilderContext_alloc(VALUE klass) {
  EnumBuilderContext* self = ALLOC(EnumBuilderContext);
  VALUE ret = TypedData_Wrap_Struct(
      klass, &_EnumBuilderContext_type, self);
  self->enum_proto = NULL;
  self->file_builder = 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, 2);
  rb_define_method(klass, "value", EnumBuilderContext_value, 2);
  rb_gc_register_address(&cEnumBuilderContext);
  cEnumBuilderContext = klass;
}

/*
 * call-seq:
 *     EnumBuilderContext.new(file_builder) => 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 _file_builder,
                                    VALUE name) {
  DEFINE_SELF(EnumBuilderContext, self, _self);
  FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
  google_protobuf_FileDescriptorProto* file_proto = file_builder->file_proto;

  self->file_builder = _file_builder;
  self->enum_proto = google_protobuf_FileDescriptorProto_add_enum_type(
      file_proto, file_builder->arena);

  google_protobuf_EnumDescriptorProto_set_name(
      self->enum_proto, FileBuilderContext_strdup(_file_builder, name));

  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);
  FileBuilderContext* file_builder =
      ruby_to_FileBuilderContext(self->file_builder);
  google_protobuf_EnumValueDescriptorProto* enum_value;

  enum_value = google_protobuf_EnumDescriptorProto_add_value(
      self->enum_proto, file_builder->arena);

  google_protobuf_EnumValueDescriptorProto_set_name(
      enum_value, FileBuilderContext_strdup_sym(self->file_builder, name));
  google_protobuf_EnumValueDescriptorProto_set_number(enum_value,
                                                      NUM2INT(number));

  return Qnil;
}


// -----------------------------------------------------------------------------
// FileBuilderContext.
// -----------------------------------------------------------------------------

DEFINE_CLASS(FileBuilderContext,
             "Google::Protobuf::Internal::FileBuilderContext");

void FileBuilderContext_mark(void* _self) {
  FileBuilderContext* self = _self;
  rb_gc_mark(self->descriptor_pool);
}

void FileBuilderContext_free(void* _self) {
  FileBuilderContext* self = _self;
  upb_arena_free(self->arena);
  xfree(self);
}

upb_strview FileBuilderContext_strdup2(VALUE _self, const char *str) {
  DEFINE_SELF(FileBuilderContext, self, _self);
  upb_strview ret;
  char *data;

  ret.size = strlen(str);
  data = upb_malloc(upb_arena_alloc(self->arena), ret.size + 1);
  ret.data = data;
  memcpy(data, str, ret.size);
  /* Null-terminate required by rewrite_enum_defaults() above. */
  data[ret.size] = '\0';
  return ret;
}

upb_strview FileBuilderContext_strdup(VALUE _self, VALUE rb_str) {
  return FileBuilderContext_strdup2(_self, get_str(rb_str));
}

upb_strview FileBuilderContext_strdup_sym(VALUE _self, VALUE rb_sym) {
  Check_Type(rb_sym, T_SYMBOL);
  return FileBuilderContext_strdup(_self, rb_id2str(SYM2ID(rb_sym)));
}

VALUE FileBuilderContext_alloc(VALUE klass) {
  FileBuilderContext* self = ALLOC(FileBuilderContext);
  VALUE ret = TypedData_Wrap_Struct(klass, &_FileBuilderContext_type, self);
  self->arena = upb_arena_new();
  self->file_proto = google_protobuf_FileDescriptorProto_new(self->arena);
  self->descriptor_pool = Qnil;
  return ret;
}

void FileBuilderContext_register(VALUE module) {
  VALUE klass = rb_define_class_under(module, "FileBuilderContext", rb_cObject);
  rb_define_alloc_func(klass, FileBuilderContext_alloc);
  rb_define_method(klass, "initialize", FileBuilderContext_initialize, 3);
  rb_define_method(klass, "add_message", FileBuilderContext_add_message, 1);
  rb_define_method(klass, "add_enum", FileBuilderContext_add_enum, 1);
  rb_gc_register_address(&cFileBuilderContext);
  cFileBuilderContext = klass;
}

/*
 * call-seq:
 *     FileBuilderContext.new(descriptor_pool) => context
 *
 * Create a new file builder context for the given file descriptor and
 * builder context. This class is intended to serve as a DSL context to be used
 * with #instance_eval.
 */
VALUE FileBuilderContext_initialize(VALUE _self, VALUE descriptor_pool,
                                    VALUE name, VALUE options) {
  DEFINE_SELF(FileBuilderContext, self, _self);
  self->descriptor_pool = descriptor_pool;

  google_protobuf_FileDescriptorProto_set_name(
      self->file_proto, FileBuilderContext_strdup(_self, name));

  // Default syntax for Ruby is proto3.
  google_protobuf_FileDescriptorProto_set_syntax(
      self->file_proto,
      FileBuilderContext_strdup(_self, rb_str_new2("proto3")));

  if (options != Qnil) {
    VALUE syntax;

    Check_Type(options, T_HASH);
    syntax = rb_hash_lookup2(options, ID2SYM(rb_intern("syntax")), Qnil);

    if (syntax != Qnil) {
      VALUE syntax_str;

      Check_Type(syntax, T_SYMBOL);
      syntax_str = rb_id2str(SYM2ID(syntax));
      google_protobuf_FileDescriptorProto_set_syntax(
          self->file_proto, FileBuilderContext_strdup(_self, syntax_str));
    }
  }

  return Qnil;
}

/*
 * call-seq:
 *     FileBuilderContext.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 FileBuilderContext_add_message(VALUE _self, VALUE name) {
  VALUE args[2] = { _self, name };
  VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
  VALUE block = rb_block_proc();
  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
  MessageBuilderContext_add_synthetic_oneofs(ctx);
  return Qnil;
}

/*
 * call-seq:
 *     FileBuilderContext.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 FileBuilderContext_add_enum(VALUE _self, VALUE name) {
  VALUE args[2] = { _self, name };
  VALUE ctx = rb_class_new_instance(2, args, cEnumBuilderContext);
  VALUE block = rb_block_proc();
  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
  return Qnil;
}

void FileBuilderContext_build(VALUE _self) {
  DEFINE_SELF(FileBuilderContext, self, _self);
  DescriptorPool* pool = ruby_to_DescriptorPool(self->descriptor_pool);
  upb_status status;

  rewrite_enum_defaults(pool->symtab, self->file_proto);
  rewrite_names(_self, self->file_proto);

  upb_status_clear(&status);
  if (!upb_symtab_addfile(pool->symtab, self->file_proto, &status)) {
    rb_raise(cTypeError, "Unable to add defs to DescriptorPool: %s",
             upb_status_errmsg(&status));
  }
}

// -----------------------------------------------------------------------------
// Builder.
// -----------------------------------------------------------------------------

DEFINE_CLASS(Builder, "Google::Protobuf::Internal::Builder");

void Builder_mark(void* _self) {
  Builder* self = _self;
  rb_gc_mark(self->descriptor_pool);
  rb_gc_mark(self->default_file_builder);
}

void Builder_free(void* _self) {
  xfree(_self);
}

VALUE Builder_alloc(VALUE klass) {
  Builder* self = ALLOC(Builder);
  VALUE ret = TypedData_Wrap_Struct(
      klass, &_Builder_type, self);
  self->descriptor_pool = Qnil;
  self->default_file_builder = Qnil;
  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, "initialize", Builder_initialize, 1);
  rb_define_method(klass, "add_file", Builder_add_file, -1);
  rb_define_method(klass, "add_message", Builder_add_message, 1);
  rb_define_method(klass, "add_enum", Builder_add_enum, 1);
  rb_gc_register_address(&cBuilder);
  cBuilder = klass;
}

/*
 * call-seq:
 *     Builder.new(descriptor_pool) => 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_initialize(VALUE _self, VALUE pool) {
  DEFINE_SELF(Builder, self, _self);
  self->descriptor_pool = pool;
  self->default_file_builder = Qnil;  // Created lazily if needed.
  return Qnil;
}

/*
 * call-seq:
 *     Builder.add_file(name, options = nil, &block)
 *
 * Creates a new, file descriptor with the given name and options and invokes
 * the block in the context of a FileBuilderContext on that descriptor. The
 * block can then call FileBuilderContext#add_message or
 * FileBuilderContext#add_enum to define new messages or enums, respectively.
 *
 * This is the recommended, idiomatic way to build file descriptors.
 */
VALUE Builder_add_file(int argc, VALUE* argv, VALUE _self) {
  DEFINE_SELF(Builder, self, _self);
  VALUE name, options;
  VALUE ctx;
  VALUE block;

  rb_scan_args(argc, argv, "11", &name, &options);

  {
    VALUE args[3] = { self->descriptor_pool, name, options };
    ctx = rb_class_new_instance(3, args, cFileBuilderContext);
  }

  block = rb_block_proc();
  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
  FileBuilderContext_build(ctx);

  return Qnil;
}

static VALUE Builder_get_default_file(VALUE _self) {
  DEFINE_SELF(Builder, self, _self);

  /* Lazily create only if legacy builder-level methods are called. */
  if (self->default_file_builder == Qnil) {
    VALUE name = rb_str_new2("ruby_default_file.proto");
    VALUE args [3] = { self->descriptor_pool, name, rb_hash_new() };
    self->default_file_builder =
        rb_class_new_instance(3, args, cFileBuilderContext);
  }

  return self->default_file_builder;
}

/*
 * call-seq:
 *     Builder.add_message(name, &block)
 *
 * Old and deprecated way to create a new descriptor.
 * See FileBuilderContext.add_message for the recommended way.
 *
 * Exists for backwards compatibility to allow building descriptor pool for
 * files generated by protoc which don't add messages within "add_file" block.
 * Descriptors created this way get assigned to a default empty FileDescriptor.
 */
VALUE Builder_add_message(VALUE _self, VALUE name) {
  VALUE file_builder = Builder_get_default_file(_self);
  rb_funcall_with_block(file_builder, rb_intern("add_message"), 1, &name,
                        rb_block_proc());
  return Qnil;
}

/*
 * call-seq:
 *     Builder.add_enum(name, &block)
 *
 * Old and deprecated way to create a new enum descriptor.
 * See FileBuilderContext.add_enum for the recommended way.
 *
 * Exists for backwards compatibility to allow building descriptor pool for
 * files generated by protoc which don't add enums within "add_file" block.
 * Enum descriptors created this way get assigned to a default empty
 * FileDescriptor.
 */
VALUE Builder_add_enum(VALUE _self, VALUE name) {
  VALUE file_builder = Builder_get_default_file(_self);
  rb_funcall_with_block(file_builder, rb_intern("add_enum"), 1, &name,
                        rb_block_proc());
  return Qnil;
}

/* This method is hidden from Ruby, and only called directly from
 * DescriptorPool_build(). */
VALUE Builder_build(VALUE _self) {
  DEFINE_SELF(Builder, self, _self);

  if (self->default_file_builder != Qnil) {
    FileBuilderContext_build(self->default_file_builder);
    self->default_file_builder = Qnil;
  }

  return Qnil;
}

static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
  DEFINE_SELF(DescriptorPool, descriptor_pool, _descriptor_pool);
  VALUE key = ULL2NUM((intptr_t)ptr);
  VALUE def;

  def = rb_hash_aref(descriptor_pool->def_to_descriptor, key);

  if (ptr == NULL) {
    return Qnil;
  }

  if (def == Qnil) {
    // Lazily create wrapper object.
    VALUE args[3] = { c_only_cookie, _descriptor_pool, key };
    def = rb_class_new_instance(3, args, klass);
    rb_hash_aset(descriptor_pool->def_to_descriptor, key, def);

    // For message defs, we now eagerly get/create descriptors for all
    // submessages.  We will need these anyway to parse or serialize this
    // message type.  But more importantly, we must do this now so that
    // add_handlers_for_message() (which calls get_msgdef_obj()) does *not*
    // need to create a Ruby object or insert into a Ruby Hash.  We need to
    // avoid triggering GC, which can switch Ruby threads and re-enter our
    // C extension from a different thread.  This wreaks havoc on our state
    // if we were in the middle of building handlers.
    if (klass == cDescriptor) {
      const upb_msgdef *m = ptr;
      upb_msg_field_iter it;
      for (upb_msg_field_begin(&it, m);
           !upb_msg_field_done(&it);
           upb_msg_field_next(&it)) {
        const upb_fielddef* f = upb_msg_iter_field(&it);
        if (upb_fielddef_issubmsg(f)) {
          get_msgdef_obj(_descriptor_pool, upb_fielddef_msgsubdef(f));
        }
      }
    }
  }

  return def;
}

VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def) {
  return get_def_obj(descriptor_pool, def, cDescriptor);
}

VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def) {
  return get_def_obj(descriptor_pool, def, cEnumDescriptor);
}

VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def) {
  return get_def_obj(descriptor_pool, def, cFieldDescriptor);
}

VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def) {
  return get_def_obj(descriptor_pool, def, cFileDescriptor);
}

VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) {
  return get_def_obj(descriptor_pool, def, cOneofDescriptor);
}
