// 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"

// -----------------------------------------------------------------------------
// Basic map operations on top of upb's strtable.
//
// Note that we roll our own `Map` container here because, as for
// `RepeatedField`, we want a strongly-typed container. This is so that any user
// errors due to incorrect map key or value types are raised as close as
// possible to the error site, rather than at some deferred point (e.g.,
// serialization).
//
// We build our `Map` on top of upb_strtable so that we're able to take
// advantage of the native_slot storage abstraction, as RepeatedField does.
// (This is not quite a perfect mapping -- see the key conversions below -- but
// gives us full support and error-checking for all value types for free.)
// -----------------------------------------------------------------------------

// Map values are stored using the native_slot abstraction (as with repeated
// field values), but keys are a bit special. Since we use a strtable, we need
// to store keys as sequences of bytes such that equality of those bytes maps
// one-to-one to equality of keys. We store strings directly (i.e., they map to
// their own bytes) and integers as native integers (using the native_slot
// abstraction).

// Note that there is another tradeoff here in keeping string keys as native
// strings rather than Ruby strings: traversing the Map requires conversion to
// Ruby string values on every traversal, potentially creating more garbage. We
// should consider ways to cache a Ruby version of the key if this becomes an
// issue later.

// Forms a key to use with the underlying strtable from a Ruby key value. |buf|
// must point to TABLE_KEY_BUF_LENGTH bytes of temporary space, used to
// construct a key byte sequence if needed. |out_key| and |out_length| provide
// the resulting key data/length.
#define TABLE_KEY_BUF_LENGTH 8  // sizeof(uint64_t)
static void table_key(Map* self, VALUE key,
                      char* buf,
                      const char** out_key,
                      size_t* out_length) {
  switch (self->key_type) {
    case UPB_TYPE_BYTES:
    case UPB_TYPE_STRING:
      // Strings: use string content directly.
      Check_Type(key, T_STRING);
      native_slot_validate_string_encoding(self->key_type, key);
      *out_key = RSTRING_PTR(key);
      *out_length = RSTRING_LEN(key);
      break;

    case UPB_TYPE_BOOL:
    case UPB_TYPE_INT32:
    case UPB_TYPE_INT64:
    case UPB_TYPE_UINT32:
    case UPB_TYPE_UINT64:
      native_slot_set(self->key_type, Qnil, buf, key);
      *out_key = buf;
      *out_length = native_slot_size(self->key_type);
      break;

    default:
      // Map constructor should not allow a Map with another key type to be
      // constructed.
      assert(false);
      break;
  }
}

static VALUE table_key_to_ruby(Map* self, const char* buf, size_t length) {
  switch (self->key_type) {
    case UPB_TYPE_BYTES:
    case UPB_TYPE_STRING: {
      VALUE ret = rb_str_new(buf, length);
      rb_enc_associate(ret,
                       (self->key_type == UPB_TYPE_BYTES) ?
                       kRubyString8bitEncoding : kRubyStringUtf8Encoding);
      return ret;
    }

    case UPB_TYPE_BOOL:
    case UPB_TYPE_INT32:
    case UPB_TYPE_INT64:
    case UPB_TYPE_UINT32:
    case UPB_TYPE_UINT64:
      return native_slot_get(self->key_type, Qnil, buf);

    default:
      assert(false);
      return Qnil;
  }
}

static void* value_memory(upb_value* v) {
  return (void*)(&v->val);
}

// -----------------------------------------------------------------------------
// Map container type.
// -----------------------------------------------------------------------------

const rb_data_type_t Map_type = {
  "Google::Protobuf::Map",
  { Map_mark, Map_free, NULL },
};

VALUE cMap;

Map* ruby_to_Map(VALUE _self) {
  Map* self;
  TypedData_Get_Struct(_self, Map, &Map_type, self);
  return self;
}

void Map_mark(void* _self) {
  Map* self = _self;

  rb_gc_mark(self->value_type_class);

  if (self->value_type == UPB_TYPE_STRING ||
      self->value_type == UPB_TYPE_BYTES ||
      self->value_type == UPB_TYPE_MESSAGE) {
    upb_strtable_iter it;
    for (upb_strtable_begin(&it, &self->table);
         !upb_strtable_done(&it);
         upb_strtable_next(&it)) {
      upb_value v = upb_strtable_iter_value(&it);
      void* mem = value_memory(&v);
      native_slot_mark(self->value_type, mem);
    }
  }
}

void Map_free(void* _self) {
  Map* self = _self;
  upb_strtable_uninit(&self->table);
  xfree(self);
}

VALUE Map_alloc(VALUE klass) {
  Map* self = ALLOC(Map);
  memset(self, 0, sizeof(Map));
  self->value_type_class = Qnil;
  return TypedData_Wrap_Struct(klass, &Map_type, self);
}

static bool needs_typeclass(upb_fieldtype_t type) {
  switch (type) {
    case UPB_TYPE_MESSAGE:
    case UPB_TYPE_ENUM:
      return true;
    default:
      return false;
  }
}

/*
 * call-seq:
 *     Map.new(key_type, value_type, value_typeclass = nil, init_hashmap = {})
 *     => new map
 *
 * Allocates a new Map container. This constructor may be called with 2, 3, or 4
 * arguments. The first two arguments are always present and are symbols (taking
 * on the same values as field-type symbols in message descriptors) that
 * indicate the type of the map key and value fields.
 *
 * The supported key types are: :int32, :int64, :uint32, :uint64, :bool,
 * :string, :bytes.
 *
 * The supported value types are: :int32, :int64, :uint32, :uint64, :bool,
 * :string, :bytes, :enum, :message.
 *
 * The third argument, value_typeclass, must be present if value_type is :enum
 * or :message. As in RepeatedField#new, this argument must be a message class
 * (for :message) or enum module (for :enum).
 *
 * The last argument, if present, provides initial content for map. Note that
 * this may be an ordinary Ruby hashmap or another Map instance with identical
 * key and value types. Also note that this argument may be present whether or
 * not value_typeclass is present (and it is unambiguously separate from
 * value_typeclass because value_typeclass's presence is strictly determined by
 * value_type). The contents of this initial hashmap or Map instance are
 * shallow-copied into the new Map: the original map is unmodified, but
 * references to underlying objects will be shared if the value type is a
 * message type.
 */
VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
  Map* self = ruby_to_Map(_self);
  int init_value_arg;

  // We take either two args (:key_type, :value_type), three args (:key_type,
  // :value_type, "ValueMessageType"), or four args (the above plus an initial
  // hashmap).
  if (argc < 2 || argc > 4) {
    rb_raise(rb_eArgError, "Map constructor expects 2, 3 or 4 arguments.");
  }

  self->key_type = ruby_to_fieldtype(argv[0]);
  self->value_type = ruby_to_fieldtype(argv[1]);

  // Check that the key type is an allowed type.
  switch (self->key_type) {
    case UPB_TYPE_INT32:
    case UPB_TYPE_INT64:
    case UPB_TYPE_UINT32:
    case UPB_TYPE_UINT64:
    case UPB_TYPE_BOOL:
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES:
      // These are OK.
      break;
    default:
      rb_raise(rb_eArgError, "Invalid key type for map.");
  }

  init_value_arg = 2;
  if (needs_typeclass(self->value_type) && argc > 2) {
    self->value_type_class = argv[2];
    validate_type_class(self->value_type, self->value_type_class);
    init_value_arg = 3;
  }

  // Table value type is always UINT64: this ensures enough space to store the
  // native_slot value.
  if (!upb_strtable_init(&self->table, UPB_CTYPE_UINT64)) {
    rb_raise(rb_eRuntimeError, "Could not allocate table.");
  }

  if (argc > init_value_arg) {
    Map_merge_into_self(_self, argv[init_value_arg]);
  }

  return Qnil;
}

/*
 * call-seq:
 *     Map.each(&block)
 *
 * Invokes &block on each |key, value| pair in the map, in unspecified order.
 * Note that Map also includes Enumerable; map thus acts like a normal Ruby
 * sequence.
 */
VALUE Map_each(VALUE _self) {
  Map* self = ruby_to_Map(_self);

  upb_strtable_iter it;
  for (upb_strtable_begin(&it, &self->table);
       !upb_strtable_done(&it);
       upb_strtable_next(&it)) {

    VALUE key = table_key_to_ruby(
        self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it));

    upb_value v = upb_strtable_iter_value(&it);
    void* mem = value_memory(&v);
    VALUE value = native_slot_get(self->value_type,
                                  self->value_type_class,
                                  mem);

    rb_yield_values(2, key, value);
  }

  return Qnil;
}

/*
 * call-seq:
 *     Map.keys => [list_of_keys]
 *
 * Returns the list of keys contained in the map, in unspecified order.
 */
VALUE Map_keys(VALUE _self) {
  Map* self = ruby_to_Map(_self);

  VALUE ret = rb_ary_new();
  upb_strtable_iter it;
  for (upb_strtable_begin(&it, &self->table);
       !upb_strtable_done(&it);
       upb_strtable_next(&it)) {

    VALUE key = table_key_to_ruby(
        self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it));

    rb_ary_push(ret, key);
  }

  return ret;
}

/*
 * call-seq:
 *     Map.values => [list_of_values]
 *
 * Returns the list of values contained in the map, in unspecified order.
 */
VALUE Map_values(VALUE _self) {
  Map* self = ruby_to_Map(_self);

  VALUE ret = rb_ary_new();
  upb_strtable_iter it;
  for (upb_strtable_begin(&it, &self->table);
       !upb_strtable_done(&it);
       upb_strtable_next(&it)) {

    upb_value v = upb_strtable_iter_value(&it);
    void* mem = value_memory(&v);
    VALUE value = native_slot_get(self->value_type,
                                  self->value_type_class,
                                  mem);

    rb_ary_push(ret, value);
  }

  return ret;
}

/*
 * call-seq:
 *     Map.[](key) => value
 *
 * Accesses the element at the given key. Throws an exception if the key type is
 * incorrect. Returns nil when the key is not present in the map.
 */
VALUE Map_index(VALUE _self, VALUE key) {
  Map* self = ruby_to_Map(_self);

  char keybuf[TABLE_KEY_BUF_LENGTH];
  const char* keyval = NULL;
  size_t length = 0;
  upb_value v;
  table_key(self, key, keybuf, &keyval, &length);

  if (upb_strtable_lookup2(&self->table, keyval, length, &v)) {
    void* mem = value_memory(&v);
    return native_slot_get(self->value_type, self->value_type_class, mem);
  } else {
    return Qnil;
  }
}

/*
 * call-seq:
 *     Map.[]=(key, value) => value
 *
 * Inserts or overwrites the value at the given key with the given new value.
 * Throws an exception if the key type is incorrect. Returns the new value that
 * was just inserted.
 */
VALUE Map_index_set(VALUE _self, VALUE key, VALUE value) {
  Map* self = ruby_to_Map(_self);

  char keybuf[TABLE_KEY_BUF_LENGTH];
  const char* keyval = NULL;
  size_t length = 0;
  upb_value v;
  void* mem;
  table_key(self, key, keybuf, &keyval, &length);

  mem = value_memory(&v);
  native_slot_set(self->value_type, self->value_type_class, mem, value);

  // Replace any existing value by issuing a 'remove' operation first.
  upb_strtable_remove2(&self->table, keyval, length, NULL);
  if (!upb_strtable_insert2(&self->table, keyval, length, v)) {
    rb_raise(rb_eRuntimeError, "Could not insert into table");
  }

  // Ruby hashmap's :[]= method also returns the inserted value.
  return value;
}

/*
 * call-seq:
 *     Map.has_key?(key) => bool
 *
 * Returns true if the given key is present in the map. Throws an exception if
 * the key has the wrong type.
 */
VALUE Map_has_key(VALUE _self, VALUE key) {
  Map* self = ruby_to_Map(_self);

  char keybuf[TABLE_KEY_BUF_LENGTH];
  const char* keyval = NULL;
  size_t length = 0;
  table_key(self, key, keybuf, &keyval, &length);

  if (upb_strtable_lookup2(&self->table, keyval, length, NULL)) {
    return Qtrue;
  } else {
    return Qfalse;
  }
}

/*
 * call-seq:
 *     Map.delete(key) => old_value
 *
 * Deletes the value at the given key, if any, returning either the old value or
 * nil if none was present. Throws an exception if the key is of the wrong type.
 */
VALUE Map_delete(VALUE _self, VALUE key) {
  Map* self = ruby_to_Map(_self);

  char keybuf[TABLE_KEY_BUF_LENGTH];
  const char* keyval = NULL;
  size_t length = 0;
  upb_value v;
  table_key(self, key, keybuf, &keyval, &length);

  if (upb_strtable_remove2(&self->table, keyval, length, &v)) {
    void* mem = value_memory(&v);
    return native_slot_get(self->value_type, self->value_type_class, mem);
  } else {
    return Qnil;
  }
}

/*
 * call-seq:
 *     Map.clear
 *
 * Removes all entries from the map.
 */
VALUE Map_clear(VALUE _self) {
  Map* self = ruby_to_Map(_self);

  // Uninit and reinit the table -- this is faster than iterating and doing a
  // delete-lookup on each key.
  upb_strtable_uninit(&self->table);
  if (!upb_strtable_init(&self->table, UPB_CTYPE_INT64)) {
    rb_raise(rb_eRuntimeError, "Unable to re-initialize table");
  }
  return Qnil;
}

/*
 * call-seq:
 *     Map.length
 *
 * Returns the number of entries (key-value pairs) in the map.
 */
VALUE Map_length(VALUE _self) {
  Map* self = ruby_to_Map(_self);
  return ULL2NUM(upb_strtable_count(&self->table));
}

static VALUE Map_new_this_type(VALUE _self) {
  Map* self = ruby_to_Map(_self);
  VALUE new_map = Qnil;
  VALUE key_type = fieldtype_to_ruby(self->key_type);
  VALUE value_type = fieldtype_to_ruby(self->value_type);
  if (self->value_type_class != Qnil) {
    new_map = rb_funcall(CLASS_OF(_self), rb_intern("new"), 3,
                         key_type, value_type, self->value_type_class);
  } else {
    new_map = rb_funcall(CLASS_OF(_self), rb_intern("new"), 2,
                         key_type, value_type);
  }
  return new_map;
}

/*
 * call-seq:
 *     Map.dup => new_map
 *
 * Duplicates this map with a shallow copy. References to all non-primitive
 * element objects (e.g., submessages) are shared.
 */
VALUE Map_dup(VALUE _self) {
  Map* self = ruby_to_Map(_self);
  VALUE new_map = Map_new_this_type(_self);
  Map* new_self = ruby_to_Map(new_map);

  upb_strtable_iter it;
  for (upb_strtable_begin(&it, &self->table);
       !upb_strtable_done(&it);
       upb_strtable_next(&it)) {

    upb_value v = upb_strtable_iter_value(&it);
    void* mem = value_memory(&v);
    upb_value dup;
    void* dup_mem = value_memory(&dup);
    native_slot_dup(self->value_type, dup_mem, mem);

    if (!upb_strtable_insert2(&new_self->table,
                              upb_strtable_iter_key(&it),
                              upb_strtable_iter_keylength(&it),
                              dup)) {
      rb_raise(rb_eRuntimeError, "Error inserting value into new table");
    }
  }

  return new_map;
}

// Used by Google::Protobuf.deep_copy but not exposed directly.
VALUE Map_deep_copy(VALUE _self) {
  Map* self = ruby_to_Map(_self);
  VALUE new_map = Map_new_this_type(_self);
  Map* new_self = ruby_to_Map(new_map);

  upb_strtable_iter it;
  for (upb_strtable_begin(&it, &self->table);
       !upb_strtable_done(&it);
       upb_strtable_next(&it)) {

    upb_value v = upb_strtable_iter_value(&it);
    void* mem = value_memory(&v);
    upb_value dup;
    void* dup_mem = value_memory(&dup);
    native_slot_deep_copy(self->value_type, dup_mem, mem);

    if (!upb_strtable_insert2(&new_self->table,
                              upb_strtable_iter_key(&it),
                              upb_strtable_iter_keylength(&it),
                              dup)) {
      rb_raise(rb_eRuntimeError, "Error inserting value into new table");
    }
  }

  return new_map;
}

/*
 * call-seq:
 *     Map.==(other) => boolean
 *
 * Compares this map to another. Maps are equal if they have identical key sets,
 * and for each key, the values in both maps compare equal. Elements are
 * compared as per normal Ruby semantics, by calling their :== methods (or
 * performing a more efficient comparison for primitive types).
 *
 * Maps with dissimilar key types or value types/typeclasses are never equal,
 * even if value comparison (for example, between integers and floats) would
 * have otherwise indicated that every element has equal value.
 */
VALUE Map_eq(VALUE _self, VALUE _other) {
  Map* self = ruby_to_Map(_self);
  Map* other;
  upb_strtable_iter it;

  // Allow comparisons to Ruby hashmaps by converting to a temporary Map
  // instance. Slow, but workable.
  if (TYPE(_other) == T_HASH) {
    VALUE other_map = Map_new_this_type(_self);
    Map_merge_into_self(other_map, _other);
    _other = other_map;
  }

  other = ruby_to_Map(_other);

  if (self == other) {
    return Qtrue;
  }
  if (self->key_type != other->key_type ||
      self->value_type != other->value_type ||
      self->value_type_class != other->value_type_class) {
    return Qfalse;
  }
  if (upb_strtable_count(&self->table) != upb_strtable_count(&other->table)) {
    return Qfalse;
  }

  // For each member of self, check that an equal member exists at the same key
  // in other.
  for (upb_strtable_begin(&it, &self->table);
       !upb_strtable_done(&it);
       upb_strtable_next(&it)) {

    upb_value v = upb_strtable_iter_value(&it);
    void* mem = value_memory(&v);
    upb_value other_v;
    void* other_mem = value_memory(&other_v);

    if (!upb_strtable_lookup2(&other->table,
                              upb_strtable_iter_key(&it),
                              upb_strtable_iter_keylength(&it),
                              &other_v)) {
      // Not present in other map.
      return Qfalse;
    }

    if (!native_slot_eq(self->value_type, mem, other_mem)) {
      // Present, but value not equal.
      return Qfalse;
    }
  }

  return Qtrue;
}

/*
 * call-seq:
 *     Map.hash => hash_value
 *
 * Returns a hash value based on this map's contents.
 */
VALUE Map_hash(VALUE _self) {
  Map* self = ruby_to_Map(_self);

  st_index_t h = rb_hash_start(0);
  VALUE hash_sym = rb_intern("hash");

  upb_strtable_iter it;
  for (upb_strtable_begin(&it, &self->table);
       !upb_strtable_done(&it);
       upb_strtable_next(&it)) {
    VALUE key = table_key_to_ruby(
        self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it));

    upb_value v = upb_strtable_iter_value(&it);
    void* mem = value_memory(&v);
    VALUE value = native_slot_get(self->value_type,
                                  self->value_type_class,
                                  mem);

    h = rb_hash_uint(h, NUM2LONG(rb_funcall(key, hash_sym, 0)));
    h = rb_hash_uint(h, NUM2LONG(rb_funcall(value, hash_sym, 0)));
  }

  return INT2FIX(h);
}

/*
 * call-seq:
 *     Map.inspect => string
 *
 * Returns a string representing this map's elements. It will be formatted as
 * "{key => value, key => value, ...}", with each key and value string
 * representation computed by its own #inspect method.
 */
VALUE Map_inspect(VALUE _self) {
  Map* self = ruby_to_Map(_self);

  VALUE str = rb_str_new2("{");

  bool first = true;
  VALUE inspect_sym = rb_intern("inspect");

  upb_strtable_iter it;
  for (upb_strtable_begin(&it, &self->table);
       !upb_strtable_done(&it);
       upb_strtable_next(&it)) {
    VALUE key = table_key_to_ruby(
        self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it));

    upb_value v = upb_strtable_iter_value(&it);
    void* mem = value_memory(&v);
    VALUE value = native_slot_get(self->value_type,
                                  self->value_type_class,
                                  mem);

    if (!first) {
      str = rb_str_cat2(str, ", ");
    } else {
      first = false;
    }
    str = rb_str_append(str, rb_funcall(key, inspect_sym, 0));
    str = rb_str_cat2(str, "=>");
    str = rb_str_append(str, rb_funcall(value, inspect_sym, 0));
  }

  str = rb_str_cat2(str, "}");
  return str;
}

/*
 * call-seq:
 *     Map.merge(other_map) => map
 *
 * Copies key/value pairs from other_map into a copy of this map. If a key is
 * set in other_map and this map, the value from other_map overwrites the value
 * in the new copy of this map. Returns the new copy of this map with merged
 * contents.
 */
VALUE Map_merge(VALUE _self, VALUE hashmap) {
  VALUE dupped = Map_dup(_self);
  return Map_merge_into_self(dupped, hashmap);
}

static int merge_into_self_callback(VALUE key, VALUE value, VALUE self) {
  Map_index_set(self, key, value);
  return ST_CONTINUE;
}

// Used only internally -- shared by #merge and #initialize.
VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
  if (TYPE(hashmap) == T_HASH) {
    rb_hash_foreach(hashmap, merge_into_self_callback, _self);
  } else if (RB_TYPE_P(hashmap, T_DATA) && RTYPEDDATA_P(hashmap) &&
             RTYPEDDATA_TYPE(hashmap) == &Map_type) {

    Map* self = ruby_to_Map(_self);
    Map* other = ruby_to_Map(hashmap);
    upb_strtable_iter it;

    if (self->key_type != other->key_type ||
        self->value_type != other->value_type ||
        self->value_type_class != other->value_type_class) {
      rb_raise(rb_eArgError, "Attempt to merge Map with mismatching types");
    }

    for (upb_strtable_begin(&it, &other->table);
         !upb_strtable_done(&it);
         upb_strtable_next(&it)) {

      // Replace any existing value by issuing a 'remove' operation first.
      upb_value v;
      upb_value oldv;
      upb_strtable_remove2(&self->table,
                           upb_strtable_iter_key(&it),
                           upb_strtable_iter_keylength(&it),
                           &oldv);

      v = upb_strtable_iter_value(&it);
      upb_strtable_insert2(&self->table,
                           upb_strtable_iter_key(&it),
                           upb_strtable_iter_keylength(&it),
                           v);
    }
  } else {
    rb_raise(rb_eArgError, "Unknown type merging into Map");
  }
  return _self;
}

// Internal method: map iterator initialization (used for serialization).
void Map_begin(VALUE _self, Map_iter* iter) {
  Map* self = ruby_to_Map(_self);
  iter->self = self;
  upb_strtable_begin(&iter->it, &self->table);
}

void Map_next(Map_iter* iter) {
  upb_strtable_next(&iter->it);
}

bool Map_done(Map_iter* iter) {
  return upb_strtable_done(&iter->it);
}

VALUE Map_iter_key(Map_iter* iter) {
  return table_key_to_ruby(
      iter->self,
      upb_strtable_iter_key(&iter->it),
      upb_strtable_iter_keylength(&iter->it));
}

VALUE Map_iter_value(Map_iter* iter) {
  upb_value v = upb_strtable_iter_value(&iter->it);
  void* mem = value_memory(&v);
  return native_slot_get(iter->self->value_type,
                         iter->self->value_type_class,
                         mem);
}

void Map_register(VALUE module) {
  VALUE klass = rb_define_class_under(module, "Map", rb_cObject);
  rb_define_alloc_func(klass, Map_alloc);
  cMap = klass;
  rb_gc_register_address(&cMap);

  rb_define_method(klass, "initialize", Map_init, -1);
  rb_define_method(klass, "each", Map_each, 0);
  rb_define_method(klass, "keys", Map_keys, 0);
  rb_define_method(klass, "values", Map_values, 0);
  rb_define_method(klass, "[]", Map_index, 1);
  rb_define_method(klass, "[]=", Map_index_set, 2);
  rb_define_method(klass, "has_key?", Map_has_key, 1);
  rb_define_method(klass, "delete", Map_delete, 1);
  rb_define_method(klass, "clear", Map_clear, 0);
  rb_define_method(klass, "length", Map_length, 0);
  rb_define_method(klass, "dup", Map_dup, 0);
  rb_define_method(klass, "==", Map_eq, 1);
  rb_define_method(klass, "hash", Map_hash, 0);
  rb_define_method(klass, "inspect", Map_inspect, 0);
  rb_define_method(klass, "merge", Map_merge, 1);
  rb_include_module(klass, rb_mEnumerable);
}
