// Protocol Buffers - Google's data interchange format
// Copyright 2008 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 "map.h"

#include <Zend/zend_API.h>
#include <Zend/zend_interfaces.h>

#include <ext/spl/spl_iterators.h>

#include "arena.h"
#include "convert.h"
#include "message.h"
#include "php-upb.h"
#include "protobuf.h"

static void MapFieldIter_make(zval *val, zval *map_field);

// -----------------------------------------------------------------------------
// MapField
// -----------------------------------------------------------------------------

typedef struct {
  zend_object std;
  zval arena;
  upb_Map *map;
  MapField_Type type;
} MapField;

zend_class_entry *MapField_class_entry;
static zend_object_handlers MapField_object_handlers;

static bool MapType_Eq(MapField_Type a, MapField_Type b) {
  return a.key_type == b.key_type && TypeInfo_Eq(a.val_type, b.val_type);
}

static TypeInfo KeyType(MapField_Type type) {
  TypeInfo ret = {type.key_type};
  return ret;
}

MapField_Type MapType_Get(const upb_FieldDef *f) {
  const upb_MessageDef *ent = upb_FieldDef_MessageSubDef(f);
  const upb_FieldDef *key_f = upb_MessageDef_FindFieldByNumber(ent, 1);
  const upb_FieldDef *val_f = upb_MessageDef_FindFieldByNumber(ent, 2);
  MapField_Type type = {
      upb_FieldDef_CType(key_f),
      {upb_FieldDef_CType(val_f), Descriptor_GetFromFieldDef(val_f)}};
  return type;
}

// PHP Object Handlers /////////////////////////////////////////////////////////

/**
 * MapField_create()
 *
 * PHP class entry function to allocate and initialize a new MapField
 * object.
 */
static zend_object* MapField_create(zend_class_entry *class_type) {
  MapField *intern = emalloc(sizeof(MapField));
  zend_object_std_init(&intern->std, class_type);
  intern->std.handlers = &MapField_object_handlers;
  Arena_Init(&intern->arena);
  intern->map = NULL;
  // Skip object_properties_init(), we don't allow derived classes.
  return &intern->std;
}

/**
 * MapField_dtor()
 *
 * Object handler to destroy a MapField. This releases all resources
 * associated with the message. Note that it is possible to access a destroyed
 * object from PHP in rare cases.
 */
static void MapField_destructor(zend_object* obj) {
  MapField* intern = (MapField*)obj;
  ObjCache_Delete(intern->map);
  zval_ptr_dtor(&intern->arena);
  zend_object_std_dtor(&intern->std);
}

/**
 * MapField_compare_objects()
 *
 * Object handler for comparing two repeated field objects. Called whenever PHP
 * code does:
 *
 *   $map1 == $map2
 */
static int MapField_compare_objects(zval *map1, zval *map2) {
  MapField* intern1 = (MapField*)Z_OBJ_P(map1);
  MapField* intern2 = (MapField*)Z_OBJ_P(map2);

  return MapType_Eq(intern1->type, intern2->type) &&
                 MapEq(intern1->map, intern2->map, intern1->type)
             ? 0
             : 1;
}

/**
 * MapField_clone_obj()
 *
 * Object handler for cloning an object in PHP. Called when PHP code does:
 *
 *   $map2 = clone $map1;
 */
static zend_object *MapField_clone_obj(PROTO_VAL *object) {
  MapField* intern = PROTO_VAL_P(object);
  upb_Arena *arena = Arena_Get(&intern->arena);
  upb_Map *clone =
      upb_Map_New(arena, intern->type.key_type, intern->type.val_type.type);
  size_t iter = kUpb_Map_Begin;

  while (upb_MapIterator_Next(intern->map, &iter)) {
    upb_MessageValue key = upb_MapIterator_Key(intern->map, iter);
    upb_MessageValue val = upb_MapIterator_Value(intern->map, iter);
    upb_Map_Set(clone, key, val, arena);
  }

  zval ret;
  MapField_GetPhpWrapper(&ret, clone, intern->type, &intern->arena);
  return Z_OBJ_P(&ret);
}

static zval *Map_GetPropertyPtrPtr(PROTO_VAL *object, PROTO_STR *member,
                                   int type, void **cache_slot) {
  return NULL;  // We don't offer direct references to our properties.
}

static HashTable *Map_GetProperties(PROTO_VAL *object) {
  return NULL;  // We do not have a properties table.
}

// C Functions from map.h //////////////////////////////////////////////////////

// These are documented in the header file.

void MapField_GetPhpWrapper(zval *val, upb_Map *map, MapField_Type type,
                            zval *arena) {
  if (!map) {
    ZVAL_NULL(val);
    return;
  }

  if (!ObjCache_Get(map, val)) {
    MapField *intern = emalloc(sizeof(MapField));
    zend_object_std_init(&intern->std, MapField_class_entry);
    intern->std.handlers = &MapField_object_handlers;
    ZVAL_COPY(&intern->arena, arena);
    intern->map = map;
    intern->type = type;
    // Skip object_properties_init(), we don't allow derived classes.
    ObjCache_Add(intern->map, &intern->std);
    ZVAL_OBJ(val, &intern->std);
  }
}

upb_Map *MapField_GetUpbMap(zval *val, MapField_Type type, upb_Arena *arena) {
  if (Z_ISREF_P(val)) {
    ZVAL_DEREF(val);
  }

  if (Z_TYPE_P(val) == IS_ARRAY) {
    upb_Map *map = upb_Map_New(arena, type.key_type, type.val_type.type);
    HashTable *table = HASH_OF(val);
    HashPosition pos;

    zend_hash_internal_pointer_reset_ex(table, &pos);

    while (true) {
      zval php_key;
      zval *php_val;
      upb_MessageValue upb_key;
      upb_MessageValue upb_val;

      zend_hash_get_current_key_zval_ex(table, &php_key, &pos);
      php_val = zend_hash_get_current_data_ex(table, &pos);

      if (!php_val) return map;

      if (!Convert_PhpToUpb(&php_key, &upb_key, KeyType(type), arena) ||
          !Convert_PhpToUpbAutoWrap(php_val, &upb_val, type.val_type, arena)) {
        return NULL;
      }

      upb_Map_Set(map, upb_key, upb_val, arena);
      zend_hash_move_forward_ex(table, &pos);
      zval_dtor(&php_key);
    }
  } else if (Z_TYPE_P(val) == IS_OBJECT &&
             Z_OBJCE_P(val) == MapField_class_entry) {
    MapField *intern = (MapField*)Z_OBJ_P(val);

    if (!MapType_Eq(intern->type, type)) {
      php_error_docref(NULL, E_USER_ERROR, "Wrong type for this map field.");
      return NULL;
    }

    upb_Arena_Fuse(arena, Arena_Get(&intern->arena));
    return intern->map;
  } else {
    php_error_docref(NULL, E_USER_ERROR, "Must be a map");
    return NULL;
  }
}

bool MapEq(const upb_Map *m1, const upb_Map *m2, MapField_Type type) {
  size_t iter = kUpb_Map_Begin;

  if ((m1 == NULL) != (m2 == NULL)) return false;
  if (m1 == NULL) return true;
  if (upb_Map_Size(m1) != upb_Map_Size(m2)) return false;

  while (upb_MapIterator_Next(m1, &iter)) {
    upb_MessageValue key = upb_MapIterator_Key(m1, iter);
    upb_MessageValue val1 = upb_MapIterator_Value(m1, iter);
    upb_MessageValue val2;

    if (!upb_Map_Get(m2, key, &val2)) return false;
    if (!ValueEq(val1, val2, type.val_type)) return false;
  }

  return true;
}


// MapField PHP methods ////////////////////////////////////////////////////////

/**
 * MapField::__construct()
 *
 * Constructs an instance of MapField.
 * @param long Key type.
 * @param long Value type.
 * @param string Message/Enum class (message/enum value types only).
 */
PHP_METHOD(MapField, __construct) {
  MapField *intern = (MapField*)Z_OBJ_P(getThis());
  upb_Arena *arena = Arena_Get(&intern->arena);
  zend_long key_type, val_type;
  zend_class_entry* klass = NULL;

  if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|C", &key_type, &val_type,
                            &klass) != SUCCESS) {
    return;
  }

  intern->type.key_type = pbphp_dtype_to_type(key_type);
  intern->type.val_type.type = pbphp_dtype_to_type(val_type);
  intern->type.val_type.desc = Descriptor_GetFromClassEntry(klass);

  // Check that the key type is an allowed type.
  switch (intern->type.key_type) {
    case kUpb_CType_Int32:
    case kUpb_CType_Int64:
    case kUpb_CType_UInt32:
    case kUpb_CType_UInt64:
    case kUpb_CType_Bool:
    case kUpb_CType_String:
    case kUpb_CType_Bytes:
      // These are OK.
      break;
    default:
      zend_error(E_USER_ERROR, "Invalid key type for map.");
  }

  if (intern->type.val_type.type == kUpb_CType_Message && klass == NULL) {
    php_error_docref(NULL, E_USER_ERROR,
                     "Message/enum type must have concrete class.");
    return;
  }

  intern->map =
      upb_Map_New(arena, intern->type.key_type, intern->type.val_type.type);
  ObjCache_Add(intern->map, &intern->std);
}

/**
 * MapField::offsetExists(): bool
 *
 * Implements the ArrayAccess interface. Invoked when PHP code calls:
 *
 *   isset($map[$idx]);
 *   empty($map[$idx]);
 *
 * @param long The index to be checked.
 * @return bool True if the element at the given index exists.
 */
PHP_METHOD(MapField, offsetExists) {
  MapField *intern = (MapField*)Z_OBJ_P(getThis());
  zval *key;
  upb_MessageValue upb_key;

  if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS ||
      !Convert_PhpToUpb(key, &upb_key, KeyType(intern->type), NULL)) {
    return;
  }

  RETURN_BOOL(upb_Map_Get(intern->map, upb_key, NULL));
}

/**
 * MapField::offsetGet(): mixed
 *
 * Implements the ArrayAccess interface. Invoked when PHP code calls:
 *
 *   $x = $map[$idx];
 *
 * @param long The index of the element to be fetched.
 * @return object The stored element at given index.
 * @exception Invalid type for index.
 * @exception Non-existing index.
 */
PHP_METHOD(MapField, offsetGet) {
  MapField *intern = (MapField*)Z_OBJ_P(getThis());
  zval *key;
  zval ret;
  upb_MessageValue upb_key, upb_val;

  if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS ||
      !Convert_PhpToUpb(key, &upb_key, KeyType(intern->type), NULL)) {
    return;
  }

  if (!upb_Map_Get(intern->map, upb_key, &upb_val)) {
    zend_error(E_USER_ERROR, "Given key doesn't exist.");
    return;
  }

  Convert_UpbToPhp(upb_val, &ret, intern->type.val_type, &intern->arena);
  RETURN_COPY_VALUE(&ret);
}

/**
 * MapField::offsetSet(): void
 *
 * Implements the ArrayAccess interface. Invoked when PHP code calls:
 *
 *   $map[$idx] = $x;
 *
 * @param long The index of the element to be assigned.
 * @param object The element to be assigned.
 * @exception Invalid type for index.
 * @exception Non-existing index.
 * @exception Incorrect type of the element.
 */
PHP_METHOD(MapField, offsetSet) {
  MapField *intern = (MapField*)Z_OBJ_P(getThis());
  upb_Arena *arena = Arena_Get(&intern->arena);
  zval *key, *val;
  upb_MessageValue upb_key, upb_val;

  if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &key, &val) != SUCCESS ||
      !Convert_PhpToUpb(key, &upb_key, KeyType(intern->type), NULL) ||
      !Convert_PhpToUpb(val, &upb_val, intern->type.val_type, arena)) {
    return;
  }

  upb_Map_Set(intern->map, upb_key, upb_val, arena);
}

/**
 * MapField::offsetUnset(): void
 *
 * Implements the ArrayAccess interface. Invoked when PHP code calls:
 *
 *   unset($map[$idx]);
 *
 * @param long The index of the element to be removed.
 * @exception Invalid type for index.
 * @exception The element to be removed is not at the end of the MapField.
 */
PHP_METHOD(MapField, offsetUnset) {
  MapField *intern = (MapField*)Z_OBJ_P(getThis());
  zval *key;
  upb_MessageValue upb_key;

  if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS ||
      !Convert_PhpToUpb(key, &upb_key, KeyType(intern->type), NULL)) {
    return;
  }

  upb_Map_Delete(intern->map, upb_key);
}

/**
 * MapField::count(): int
 *
 * Implements the Countable interface. Invoked when PHP code calls:
 *
 *   $len = count($map);
 * Return the number of stored elements.
 * This will also be called for: count($map)
 * @return long The number of stored elements.
 */
PHP_METHOD(MapField, count) {
  MapField *intern = (MapField*)Z_OBJ_P(getThis());

  if (zend_parse_parameters_none() == FAILURE) {
    return;
  }

  RETURN_LONG(upb_Map_Size(intern->map));
}

/**
 * MapField::getIterator(): Traversable
 *
 * Implements the IteratorAggregate interface. Invoked when PHP code calls:
 *
 *   foreach ($arr) {}
 *
 * @return object Beginning iterator.
 */
PHP_METHOD(MapField, getIterator) {
  zval ret;
  MapFieldIter_make(&ret, getThis());
  RETURN_COPY_VALUE(&ret);
}

ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 2)
  ZEND_ARG_INFO(0, key_type)
  ZEND_ARG_INFO(0, value_type)
  ZEND_ARG_INFO(0, value_class)
ZEND_END_ARG_INFO()


ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_offsetGet, 0, 0, IS_MIXED, 1)
  ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()

PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_offsetSet, 0, 2, IS_VOID, 0)
  ZEND_ARG_INFO(0, index)
  ZEND_ARG_INFO(0, newval)
ZEND_END_ARG_INFO()

PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_offsetUnset, 0, 0, IS_VOID, 0)
  ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()

PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_offsetExists, 0, 0, _IS_BOOL, 0)
  ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_getIterator, 0, 0, Traversable, 0)
ZEND_END_ARG_INFO()

PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_count, 0, 0, IS_LONG, 0)
ZEND_END_ARG_INFO()

static zend_function_entry MapField_methods[] = {
  PHP_ME(MapField, __construct,  arginfo_construct,    ZEND_ACC_PUBLIC)
  PHP_ME(MapField, offsetExists, arginfo_offsetExists, ZEND_ACC_PUBLIC)
  PHP_ME(MapField, offsetGet,    arginfo_offsetGet,    ZEND_ACC_PUBLIC)
  PHP_ME(MapField, offsetSet,    arginfo_offsetSet,    ZEND_ACC_PUBLIC)
  PHP_ME(MapField, offsetUnset,  arginfo_offsetUnset,  ZEND_ACC_PUBLIC)
  PHP_ME(MapField, count,        arginfo_count,        ZEND_ACC_PUBLIC)
  PHP_ME(MapField, getIterator,  arginfo_getIterator,  ZEND_ACC_PUBLIC)
  ZEND_FE_END
};

// -----------------------------------------------------------------------------
// MapFieldIter
// -----------------------------------------------------------------------------

typedef struct {
  zend_object std;
  zval map_field;
  size_t position;
} MapFieldIter;

zend_class_entry *MapFieldIter_class_entry;
static zend_object_handlers MapFieldIter_object_handlers;

/**
 * MapFieldIter_create()
 *
 * PHP class entry function to allocate and initialize a new MapFieldIter
 * object.
 */
zend_object* MapFieldIter_create(zend_class_entry *class_type) {
  MapFieldIter *intern = emalloc(sizeof(MapFieldIter));
  zend_object_std_init(&intern->std, class_type);
  intern->std.handlers = &MapFieldIter_object_handlers;
  ZVAL_NULL(&intern->map_field);
  intern->position = 0;
  // Skip object_properties_init(), we don't allow derived classes.
  return &intern->std;
}

/**
 * MapFieldIter_dtor()
 *
 * Object handler to destroy a MapFieldIter. This releases all resources
 * associated with the message. Note that it is possible to access a destroyed
 * object from PHP in rare cases.
 */
static void map_field_iter_dtor(zend_object* obj) {
  MapFieldIter* intern = (MapFieldIter*)obj;
  zval_ptr_dtor(&intern->map_field);
  zend_object_std_dtor(&intern->std);
}

/**
 * MapFieldIter_make()
 *
 * Function to create a MapFieldIter directly from C.
 */
static void MapFieldIter_make(zval *val, zval *map_field) {
  MapFieldIter *iter;
  ZVAL_OBJ(val,
           MapFieldIter_class_entry->create_object(MapFieldIter_class_entry));
  iter = (MapFieldIter*)Z_OBJ_P(val);
  ZVAL_COPY(&iter->map_field, map_field);
}

// -----------------------------------------------------------------------------
// PHP MapFieldIter Methods
// -----------------------------------------------------------------------------

/*
 * When a user writes:
 *
 *   foreach($arr as $key => $val) {}
 *
 * PHP translates this into:
 *
 *   $iter = $arr->getIterator();
 *   for ($iter->rewind(); $iter->valid(); $iter->next()) {
 *     $key = $iter->key();
 *     $val = $iter->current();
 *   }
 */

/**
 * MapFieldIter::rewind(): void
 *
 * Implements the Iterator interface. Sets the iterator to the first element.
 */
PHP_METHOD(MapFieldIter, rewind) {
  MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis());
  MapField *map_field = (MapField*)Z_OBJ_P(&intern->map_field);
  intern->position = kUpb_Map_Begin;
  upb_MapIterator_Next(map_field->map, &intern->position);
}

/**
 * MapFieldIter::current(): mixed
 *
 * Implements the Iterator interface. Returns the current value.
 */
PHP_METHOD(MapFieldIter, current) {
  MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis());
  MapField *field = (MapField*)Z_OBJ_P(&intern->map_field);
  upb_MessageValue upb_val = upb_MapIterator_Value(field->map, intern->position);
  zval ret;
  Convert_UpbToPhp(upb_val, &ret, field->type.val_type, &field->arena);
  RETURN_COPY_VALUE(&ret);
}

/**
 * MapFieldIter::key()
 *
 * Implements the Iterator interface. Returns the current key.
 */
PHP_METHOD(MapFieldIter, key) {
  MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis());
  MapField *field = (MapField*)Z_OBJ_P(&intern->map_field);
  upb_MessageValue upb_key = upb_MapIterator_Key(field->map, intern->position);
  zval ret;
  Convert_UpbToPhp(upb_key, &ret, KeyType(field->type), NULL);
  RETURN_COPY_VALUE(&ret);
}

/**
 * MapFieldIter::next(): void
 *
 * Implements the Iterator interface. Advances to the next element.
 */
PHP_METHOD(MapFieldIter, next) {
  MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis());
  MapField *field = (MapField*)Z_OBJ_P(&intern->map_field);
  upb_MapIterator_Next(field->map, &intern->position);
}

/**
 * MapFieldIter::valid(): bool
 *
 * Implements the Iterator interface. Returns true if this is a valid element.
 */
PHP_METHOD(MapFieldIter, valid) {
  MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis());
  MapField *field = (MapField*)Z_OBJ_P(&intern->map_field);
  bool done = upb_MapIterator_Done(field->map, intern->position);
  RETURN_BOOL(!done);
}

PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rewind, 0, 0, IS_VOID, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_current, 0, 0, IS_MIXED, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_key, 0, 0, IS_MIXED, 0)
ZEND_END_ARG_INFO()

PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_next, 0, 0, IS_VOID, 0)
ZEND_END_ARG_INFO()

PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_valid, 0, 0, _IS_BOOL, 0)
ZEND_END_ARG_INFO()

static zend_function_entry map_field_iter_methods[] = {
  PHP_ME(MapFieldIter, rewind,      arginfo_rewind,  ZEND_ACC_PUBLIC)
  PHP_ME(MapFieldIter, current,     arginfo_current, ZEND_ACC_PUBLIC)
  PHP_ME(MapFieldIter, key,         arginfo_key,     ZEND_ACC_PUBLIC)
  PHP_ME(MapFieldIter, next,        arginfo_next,    ZEND_ACC_PUBLIC)
  PHP_ME(MapFieldIter, valid,       arginfo_valid,   ZEND_ACC_PUBLIC)
  ZEND_FE_END
};

// -----------------------------------------------------------------------------
// Module init.
// -----------------------------------------------------------------------------

/**
 * Map_ModuleInit()
 *
 * Called when the C extension is loaded to register all types.
 */

void Map_ModuleInit() {
  zend_class_entry tmp_ce;
  zend_object_handlers *h;

  INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\MapField",
                   MapField_methods);

  MapField_class_entry = zend_register_internal_class(&tmp_ce);
  zend_class_implements(MapField_class_entry, 3, zend_ce_arrayaccess,
                        zend_ce_aggregate, zend_ce_countable);
  MapField_class_entry->ce_flags |= ZEND_ACC_FINAL;
  MapField_class_entry->create_object = MapField_create;

  h = &MapField_object_handlers;
  memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
  h->dtor_obj = MapField_destructor;
#if PHP_VERSION_ID < 80000
  h->compare_objects = MapField_compare_objects;
#else
  h->compare = MapField_compare_objects;
#endif
  h->clone_obj = MapField_clone_obj;
  h->get_properties = Map_GetProperties;
  h->get_property_ptr_ptr = Map_GetPropertyPtrPtr;

  INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\MapFieldIter",
                   map_field_iter_methods);

  MapFieldIter_class_entry = zend_register_internal_class(&tmp_ce);
  zend_class_implements(MapFieldIter_class_entry, 1, zend_ce_iterator);
  MapFieldIter_class_entry->ce_flags |= ZEND_ACC_FINAL;
  MapFieldIter_class_entry->ce_flags |= ZEND_ACC_FINAL;
  MapFieldIter_class_entry->create_object = MapFieldIter_create;

  h = &MapFieldIter_object_handlers;
  memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
  h->dtor_obj = map_field_iter_dtor;
}
