/*
 * Copyright (c) 2009-2021, Google LLC
 * All rights reserved.
 *
 * 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 LLC 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 Google LLC 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 "descriptor_containers.h"

#include "upb/def.h"

#include "protobuf.h"
#include "descriptor.h"

// -----------------------------------------------------------------------------
// DescriptorIterator
// -----------------------------------------------------------------------------

typedef struct {
  PyObject_HEAD
  const PyUpb_GenericSequence_Funcs *funcs;
  const void *parent;    // upb_msgdef*, upb_symtab*, etc.
  PyObject *parent_obj;  // Python object that keeps parent alive, we own a ref.
  int index;             // Current iterator index.
} PyUpb_DescriptorIterator;

PyUpb_DescriptorIterator *PyUpb_DescriptorIterator_Self(PyObject *obj) {
  assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->descriptor_iterator_type);
  return (PyUpb_DescriptorIterator*)obj;
}

static void PyUpb_DescriptorIterator_Dealloc(PyObject *_self) {
  PyUpb_DescriptorIterator *self = PyUpb_DescriptorIterator_Self(_self);
  Py_DECREF(self->parent_obj);
  PyUpb_Dealloc(self);
}

PyObject *PyUpb_DescriptorIterator_New(const PyUpb_GenericSequence_Funcs *funcs,
                                       const void *parent,
                                       PyObject *parent_obj) {
  PyUpb_ModuleState *s = PyUpb_ModuleState_Get();
  PyUpb_DescriptorIterator *iter =
      (void *)PyType_GenericAlloc(s->descriptor_iterator_type, 0);
  iter->funcs = funcs;
  iter->parent = parent;
  iter->parent_obj = parent_obj;
  iter->index = 0;
  Py_INCREF(iter->parent_obj);
  return &iter->ob_base;
}

PyObject* PyUpb_DescriptorIterator_IterNext(PyObject* _self) {
  PyUpb_DescriptorIterator *self = PyUpb_DescriptorIterator_Self(_self);
  int size = self->funcs->get_elem_count(self->parent);
  if (self->index >= size) return NULL;
  const void *elem = self->funcs->index(self->parent, self->index);
  self->index++;
  return self->funcs->get_elem_wrapper(elem);
}

static PyType_Slot PyUpb_DescriptorIterator_Slots[] = {
  {Py_tp_dealloc, PyUpb_DescriptorIterator_Dealloc},
  {Py_tp_iter, PyObject_SelfIter},
  {Py_tp_iternext, PyUpb_DescriptorIterator_IterNext},
  {0, NULL}
};

static PyType_Spec PyUpb_DescriptorIterator_Spec = {
  PYUPB_MODULE_NAME ".DescriptorIterator",   // tp_name
  sizeof(PyUpb_DescriptorIterator),          // tp_basicsize
  0,                                         // tp_itemsize
  Py_TPFLAGS_DEFAULT,                        // tp_flags
  PyUpb_DescriptorIterator_Slots,
};

// -----------------------------------------------------------------------------
// GenericSequence
// -----------------------------------------------------------------------------

typedef struct {
  PyObject_HEAD
  const PyUpb_GenericSequence_Funcs *funcs;
  const void *parent;    // upb_msgdef*, upb_symtab*, etc.
  PyObject *parent_obj;  // Python object that keeps parent alive, we own a ref.
} PyUpb_GenericSequence;

PyUpb_GenericSequence *PyUpb_GenericSequence_Self(PyObject *obj) {
  assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->generic_sequence_type);
  return (PyUpb_GenericSequence*)obj;
}

static void PyUpb_GenericSequence_Dealloc(PyObject *_self) {
  PyUpb_GenericSequence *self = PyUpb_GenericSequence_Self(_self);
  Py_CLEAR(self->parent_obj);
  PyUpb_Dealloc(self);
}

PyObject *PyUpb_GenericSequence_New(
    const PyUpb_GenericSequence_Funcs *funcs, const void *parent,
    PyObject *parent_obj) {
  PyUpb_ModuleState *s = PyUpb_ModuleState_Get();
  PyUpb_GenericSequence *seq =
      (PyUpb_GenericSequence *)PyType_GenericAlloc(s->generic_sequence_type, 0);
  seq->funcs = funcs;
  seq->parent = parent;
  seq->parent_obj = parent_obj;
  Py_INCREF(parent_obj);
  return &seq->ob_base;
}

static Py_ssize_t PyUpb_GenericSequence_Length(PyObject* _self) {
  PyUpb_GenericSequence *self = PyUpb_GenericSequence_Self(_self);
  return self->funcs->get_elem_count(self->parent);
}

static PyObject *PyUpb_GenericSequence_GetItem(PyObject *_self,
                                               Py_ssize_t index) {
  PyUpb_GenericSequence *self = PyUpb_GenericSequence_Self(_self);
  Py_ssize_t size = self->funcs->get_elem_count(self->parent);
  if (index < 0 || index >= size) {
    PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index);
    return NULL;
  }
  const void *elem = self->funcs->index(self->parent, index);
  return self->funcs->get_elem_wrapper(elem);
}

// A sequence container can only be equal to another sequence container, or (for
// backward compatibility) to a list containing the same items.
// Returns 1 if equal, 0 if unequal, -1 on error.
static int PyUpb_GenericSequence_IsEqual(PyUpb_GenericSequence *self,
                                         PyObject *other) {
  // Check the identity of C++ pointers.
  if (PyObject_TypeCheck(other, Py_TYPE(self))) {
    PyUpb_GenericSequence *other_seq = (void *)other;
    return self->parent == other_seq->parent && self->funcs == other_seq->funcs;
  }

  if (!PyList_Check(other)) return 0;

  // return list(self) == other
  // We can clamp `i` to int because GenericSequence uses int for size (this
  // is useful when we do int iteration below).
  int n = PyUpb_GenericSequence_Length((PyObject*)self);
  if ((Py_ssize_t)n != PyList_Size(other)) {
    return false;
  }

  PyObject *item1;
  for (int i = 0; i < n; i++) {
    item1 = PyUpb_GenericSequence_GetItem((PyObject*)self, i);
    PyObject* item2 = PyList_GetItem(other, i);
    if (!item1 || !item2) goto error;
    int cmp = PyObject_RichCompareBool(item1, item2, Py_EQ);
    Py_DECREF(item1);
    if (cmp != 1) return cmp;
  }
  // All items were found and equal
  return 1;

error:
  Py_XDECREF(item1);
  return -1;
}

static PyObject *PyUpb_GenericSequence_RichCompare(PyObject *_self,
                                                   PyObject *other, int opid) {
  PyUpb_GenericSequence *self = PyUpb_GenericSequence_Self(_self);
  if (opid != Py_EQ && opid != Py_NE) {
    Py_RETURN_NOTIMPLEMENTED;
  }
  bool ret = PyUpb_GenericSequence_IsEqual(self, other);
  if (opid == Py_NE) ret = !ret;
  return PyBool_FromLong(ret);
}

// Linear search.  Could optimize this in some cases (defs that have index),
// but not all (FileDescriptor.dependencies).
static int PyUpb_GenericSequence_Find(PyObject *_self, PyObject *item) {
  PyUpb_GenericSequence *self = PyUpb_GenericSequence_Self(_self);
  const void *item_ptr = PyUpb_AnyDescriptor_GetDef(item);
  int count = self->funcs->get_elem_count(self->parent);
  for (int i = 0; i < count; i++) {
    if (self->funcs->index(self->parent, i) == item_ptr) {
      return i;
    }
  }
  return -1;
}

static PyObject* PyUpb_GenericSequence_Index(PyObject* self, PyObject* item) {
  int position = PyUpb_GenericSequence_Find(self, item);
  if (position < 0) {
    PyErr_SetNone(PyExc_ValueError);
    return NULL;
  } else {
    return PyLong_FromLong(position);
  }
}

static PyObject *PyUpb_GenericSequence_Count(PyObject *_self, PyObject *item) {
  PyUpb_GenericSequence *self = PyUpb_GenericSequence_Self(_self);
  const void *item_ptr = PyUpb_AnyDescriptor_GetDef(item);
  int n = self->funcs->get_elem_count(self->parent);
  int count = 0;
  for (int i = 0; i < n; i++) {
    if (self->funcs->index(self->parent, i) == item_ptr) {
      count++;
    }
  }
  return PyLong_FromLong(count);
}

static PyObject *PyUpb_GenericSequence_Append(PyObject *self, PyObject *args) {
  PyErr_Format(PyExc_TypeError, "'%R' is not a mutable sequence", self);
  return NULL;
}

static PyMethodDef PyUpb_GenericSequence_Methods[] = {
    {"index", PyUpb_GenericSequence_Index, METH_O},
    {"count", PyUpb_GenericSequence_Count, METH_O},
    {"append", PyUpb_GenericSequence_Append, METH_O},
    // This was implemented for Python/C++ but so far has not been required.
    //{ "__reversed__", (PyCFunction)Reversed, METH_NOARGS, },
    {NULL}};

static PyType_Slot PyUpb_GenericSequence_Slots[] = {
  {Py_tp_dealloc, &PyUpb_GenericSequence_Dealloc},
  {Py_tp_methods, &PyUpb_GenericSequence_Methods},
  {Py_sq_length, PyUpb_GenericSequence_Length},
  {Py_sq_item, PyUpb_GenericSequence_GetItem},
  {Py_tp_richcompare, &PyUpb_GenericSequence_RichCompare},
  // These were implemented for Python/C++ but so far have not been required.
  // {Py_tp_repr, &PyUpb_GenericSequence_Repr},
  // {Py_sq_contains, PyUpb_GenericSequence_Contains},
  // {Py_mp_subscript, PyUpb_GenericSequence_Subscript},
  // {Py_mp_ass_subscript, PyUpb_GenericSequence_AssignSubscript},
  {0, NULL},
};

static PyType_Spec PyUpb_GenericSequence_Spec = {
  PYUPB_MODULE_NAME "._GenericSequence", // tp_name
  sizeof(PyUpb_GenericSequence),         // tp_basicsize
  0,                                     // tp_itemsize
  Py_TPFLAGS_DEFAULT,                    // tp_flags
  PyUpb_GenericSequence_Slots,
};

// -----------------------------------------------------------------------------
// ByNameMap
// -----------------------------------------------------------------------------

typedef struct {
  PyObject_HEAD
  const PyUpb_ByNameMap_Funcs *funcs;
  const void *parent;    // upb_msgdef*, upb_symtab*, etc.
  PyObject *parent_obj;  // Python object that keeps parent alive, we own a ref.
} PyUpb_ByNameMap;

PyUpb_ByNameMap *PyUpb_ByNameMap_Self(PyObject *obj) {
  assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->by_name_map_type);
  return (PyUpb_ByNameMap*)obj;
}

static void PyUpb_ByNameMap_Dealloc(PyObject *_self) {
  PyUpb_ByNameMap *self = PyUpb_ByNameMap_Self(_self);
  Py_DECREF(self->parent_obj);
  PyUpb_Dealloc(self);
}

PyObject *PyUpb_ByNameMap_New(const PyUpb_ByNameMap_Funcs *funcs,
                              const void *parent, PyObject *parent_obj) {
  PyUpb_ModuleState *s = PyUpb_ModuleState_Get();
  PyUpb_ByNameMap *map = (void*)PyType_GenericAlloc(s->by_name_map_type, 0);
  map->funcs = funcs;
  map->parent = parent;
  map->parent_obj = parent_obj;
  Py_INCREF(parent_obj);
  return &map->ob_base;
}

static Py_ssize_t PyUpb_ByNameMap_Length(PyObject* _self) {
  PyUpb_ByNameMap *self = PyUpb_ByNameMap_Self(_self);
  return self->funcs->base.get_elem_count(self->parent);
}

static PyObject *PyUpb_ByNameMap_Subscript(PyObject *_self, PyObject *key) {
  PyUpb_ByNameMap *self = PyUpb_ByNameMap_Self(_self);
  const char *name = PyUpb_GetStrData(key);
  const void *elem = name ? self->funcs->lookup(self->parent, name) : NULL;

  if (elem) {
    return self->funcs->base.get_elem_wrapper(elem);
  } else {
    PyErr_SetObject(PyExc_KeyError, key);
    return NULL;
  }
}

static int PyUpb_ByNameMap_AssignSubscript(PyObject *self, PyObject *key,
                                           PyObject *value) {
  PyErr_Format(PyExc_TypeError, PYUPB_MODULE_NAME
               ".ByNameMap' object does not support item assignment");
  return -1;
}

static int PyUpb_ByNameMap_Contains(PyObject *_self, PyObject *key) {
  PyUpb_ByNameMap *self = PyUpb_ByNameMap_Self(_self);
  const char *name = PyUpb_GetStrData(key);
  const void *elem = name ? self->funcs->lookup(self->parent, name) : NULL;
  return elem ? 1 : 0;
}

static PyObject *PyUpb_ByNameMap_Get(PyObject *_self, PyObject *args) {
  PyUpb_ByNameMap *self = PyUpb_ByNameMap_Self(_self);
  PyObject* key;
  PyObject* default_value = Py_None;
  if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) {
    return NULL;
  }

  const char *name = PyUpb_GetStrData(key);
  const void *elem = name ? self->funcs->lookup(self->parent, name) : NULL;

  if (elem) {
    return self->funcs->base.get_elem_wrapper(elem);
  } else {
    Py_INCREF(default_value);
    return default_value;
  }
}

static PyObject *PyUpb_ByNameMap_GetIter(PyObject *_self) {
  PyUpb_ByNameMap *self = PyUpb_ByNameMap_Self(_self);
  return PyUpb_DescriptorIterator_New(&self->funcs->base, self->parent,
                                      self->parent_obj);
}

static PyObject *PyUpb_ByNameMap_Keys(PyObject *_self, PyObject *args) {
  PyUpb_ByNameMap *self = PyUpb_ByNameMap_Self(_self);
  int n = self->funcs->base.get_elem_count(self->parent);
  PyObject *ret = PyList_New(n);
  if (!ret) return NULL;
  for (int i = 0; i < n; i++) {
    const void *elem = self->funcs->base.index(self->parent, i);
    PyObject *key = PyUnicode_FromString(self->funcs->get_elem_name(elem));
    if (!key) goto error;
    PyList_SetItem(ret, i, key);
  }
  return ret;

error:
  Py_XDECREF(ret);
  return NULL;
}

static PyObject *PyUpb_ByNameMap_Values(PyObject *_self, PyObject *args) {
  PyUpb_ByNameMap *self = PyUpb_ByNameMap_Self(_self);
  int n = self->funcs->base.get_elem_count(self->parent);
  PyObject *ret = PyList_New(n);
  if (!ret) return NULL;
  for (int i = 0; i < n; i++) {
    const void *elem = self->funcs->base.index(self->parent, i);
    PyObject *py_elem = self->funcs->base.get_elem_wrapper(elem);
    if (!py_elem) goto error;
    PyList_SetItem(ret, i, py_elem);
  }
  return ret;

error:
  Py_XDECREF(ret);
  return NULL;
}

static PyObject *PyUpb_ByNameMap_Items(PyObject *_self, PyObject *args) {
  PyUpb_ByNameMap *self = (PyUpb_ByNameMap *)_self;
  int n = self->funcs->base.get_elem_count(self->parent);
  PyObject *ret = PyList_New(n);
  PyObject *item;
  PyObject *py_elem;
  if (!ret) return NULL;
  for (int i = 0; i < n; i++) {
    const void *elem = self->funcs->base.index(self->parent, i);
    item = PyTuple_New(2);
    py_elem = self->funcs->base.get_elem_wrapper(elem);
    if (!item || !py_elem) goto error;
    PyTuple_SetItem(item, 0,
                    PyUnicode_FromString(self->funcs->get_elem_name(elem)));
    PyTuple_SetItem(item, 1, py_elem);
    PyList_SetItem(ret, i, item);
  }
  return ret;

error:
  Py_XDECREF(py_elem);
  Py_XDECREF(item);
  Py_XDECREF(ret);
  return NULL;
}

// A mapping container can only be equal to another mapping container, or (for
// backward compatibility) to a dict containing the same items.
// Returns 1 if equal, 0 if unequal, -1 on error.
static int PyUpb_ByNameMap_IsEqual(PyUpb_ByNameMap* self, PyObject* other) {
  // Check the identity of C++ pointers.
  if (PyObject_TypeCheck(other, Py_TYPE(self))) {
    PyUpb_ByNameMap *other_map = (void *)other;
    return self->parent == other_map->parent && self->funcs == other_map->funcs;
  }

  if (!PyDict_Check(other)) return 0;

  PyObject *self_dict = PyDict_New();
  PyDict_Merge(self_dict, (PyObject*)self, 0);
  int eq = PyObject_RichCompareBool(self_dict, other, Py_EQ);
  Py_DECREF(self_dict);
  return eq;
}

static PyObject *PyUpb_ByNameMap_RichCompare(PyObject *_self, PyObject *other,
                                             int opid) {
  PyUpb_ByNameMap *self = PyUpb_ByNameMap_Self(_self);
  if (opid != Py_EQ && opid != Py_NE) {
    Py_RETURN_NOTIMPLEMENTED;
  }
  bool ret = PyUpb_ByNameMap_IsEqual(self, other);
  if (opid == Py_NE) ret = !ret;
  return PyBool_FromLong(ret);
}

static PyMethodDef PyUpb_ByNameMap_Methods[] = {
    {"get", (PyCFunction)&PyUpb_ByNameMap_Get, METH_VARARGS},
    {"keys", PyUpb_ByNameMap_Keys, METH_NOARGS},
    {"values", PyUpb_ByNameMap_Values, METH_NOARGS},
    {"items", PyUpb_ByNameMap_Items, METH_NOARGS},
    {NULL}};

static PyType_Slot PyUpb_ByNameMap_Slots[] = {
    {Py_mp_ass_subscript, PyUpb_ByNameMap_AssignSubscript},
    {Py_mp_length, PyUpb_ByNameMap_Length},
    {Py_mp_subscript, PyUpb_ByNameMap_Subscript},
    {Py_sq_contains, &PyUpb_ByNameMap_Contains},
    {Py_tp_dealloc, &PyUpb_ByNameMap_Dealloc},
    {Py_tp_iter, PyUpb_ByNameMap_GetIter},
    {Py_tp_methods, &PyUpb_ByNameMap_Methods},
    {Py_tp_richcompare, &PyUpb_ByNameMap_RichCompare},
    {0, NULL},
};

static PyType_Spec PyUpb_ByNameMap_Spec = {
  PYUPB_MODULE_NAME "._ByNameMap",       // tp_name
  sizeof(PyUpb_ByNameMap),               // tp_basicsize
  0,                                     // tp_itemsize
  Py_TPFLAGS_DEFAULT,                    // tp_flags
  PyUpb_ByNameMap_Slots,
};

// -----------------------------------------------------------------------------
// ByNumberMap
// -----------------------------------------------------------------------------

typedef struct {
  PyObject_HEAD
  const PyUpb_ByNumberMap_Funcs *funcs;
  const void *parent;    // upb_msgdef*, upb_symtab*, etc.
  PyObject *parent_obj;  // Python object that keeps parent alive, we own a ref.
} PyUpb_ByNumberMap;

PyUpb_ByNumberMap *PyUpb_ByNumberMap_Self(PyObject *obj) {
  assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->by_number_map_type);
  return (PyUpb_ByNumberMap*)obj;
}

PyObject *PyUpb_ByNumberMap_New(const PyUpb_ByNumberMap_Funcs *funcs,
                                const void *parent, PyObject *parent_obj) {
  PyUpb_ModuleState *s = PyUpb_ModuleState_Get();
  PyUpb_ByNumberMap *map = (void*)PyType_GenericAlloc(s->by_number_map_type, 0);
  map->funcs = funcs;
  map->parent = parent;
  map->parent_obj = parent_obj;
  Py_INCREF(parent_obj);
  return &map->ob_base;
}

static void PyUpb_ByNumberMap_Dealloc(PyObject *_self) {
  PyUpb_ByNumberMap *self = PyUpb_ByNumberMap_Self(_self);
  Py_DECREF(self->parent_obj);
  PyUpb_Dealloc(self);
}

static Py_ssize_t PyUpb_ByNumberMap_Length(PyObject* _self) {
  PyUpb_ByNumberMap *self = PyUpb_ByNumberMap_Self(_self);
  return self->funcs->base.get_elem_count(self->parent);
}

static const void *PyUpb_ByNumberMap_LookupHelper(PyUpb_ByNumberMap *self,
                                                  PyObject *key) {
  long num = PyLong_AsLong(key);
  if (num == -1 && PyErr_Occurred()) {
    PyErr_Clear();
    return NULL;
  } else {
    return self->funcs->lookup(self->parent, num);
  }
}

static PyObject *PyUpb_ByNumberMap_Subscript(PyObject *_self, PyObject *key) {
  PyUpb_ByNumberMap *self = PyUpb_ByNumberMap_Self(_self);
  const void *elem = PyUpb_ByNumberMap_LookupHelper(self, key);
  if (elem) {
    return self->funcs->base.get_elem_wrapper(elem);
  } else {
    PyErr_SetObject(PyExc_KeyError, key);
    return NULL;
  }
}

static int PyUpb_ByNumberMap_AssignSubscript(PyObject *self, PyObject *key,
                                             PyObject *value) {
  PyErr_Format(PyExc_TypeError, PYUPB_MODULE_NAME
               ".ByNumberMap' object does not support item assignment");
  return -1;
}

static PyObject *PyUpb_ByNumberMap_Get(PyObject *_self, PyObject *args) {
  PyUpb_ByNumberMap *self = PyUpb_ByNumberMap_Self(_self);
  PyObject* key;
  PyObject* default_value = Py_None;
  if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) {
    return NULL;
  }

  const void *elem = PyUpb_ByNumberMap_LookupHelper(self, key);
  if (elem) {
    return self->funcs->base.get_elem_wrapper(elem);
  } else {
    return PyUpb_NewRef(default_value);
  }
}

static PyObject *PyUpb_ByNumberMap_GetIter(PyObject *_self) {
  PyUpb_ByNumberMap *self = PyUpb_ByNumberMap_Self(_self);
  return PyUpb_DescriptorIterator_New(&self->funcs->base, self->parent,
                                      self->parent_obj);
}

static PyObject *PyUpb_ByNumberMap_Keys(PyObject *_self, PyObject *args) {
  PyUpb_ByNumberMap *self = PyUpb_ByNumberMap_Self(_self);
  int n = self->funcs->base.get_elem_count(self->parent);
  PyObject *ret = PyList_New(n);
  if (!ret) return NULL;
  for (int i = 0; i < n; i++) {
    const void *elem = self->funcs->base.index(self->parent, i);
    PyObject *key = PyLong_FromLong(self->funcs->get_elem_num(elem));
    if (!key) goto error;
    PyList_SetItem(ret, i, key);
  }
  return ret;

error:
  Py_XDECREF(ret);
  return NULL;
}

static PyObject *PyUpb_ByNumberMap_Values(PyObject *_self, PyObject *args) {
  PyUpb_ByNumberMap *self = PyUpb_ByNumberMap_Self(_self);
  int n = self->funcs->base.get_elem_count(self->parent);
  PyObject *ret = PyList_New(n);
  if (!ret) return NULL;
  for (int i = 0; i < n; i++) {
    const void *elem = self->funcs->base.index(self->parent, i);
    PyObject *py_elem = self->funcs->base.get_elem_wrapper(elem);
    if (!py_elem) goto error;
    PyList_SetItem(ret, i, py_elem);
  }
  return ret;

error:
  Py_XDECREF(ret);
  return NULL;
}

static PyObject *PyUpb_ByNumberMap_Items(PyObject *_self, PyObject *args) {
  PyUpb_ByNumberMap *self = PyUpb_ByNumberMap_Self(_self);
  int n = self->funcs->base.get_elem_count(self->parent);
  PyObject *ret = PyList_New(n);
  PyObject *item;
  PyObject *py_elem;
  if (!ret) return NULL;
  for (int i = 0; i < n; i++) {
    const void *elem = self->funcs->base.index(self->parent, i);
    int number = self->funcs->get_elem_num(elem);
    item = PyTuple_New(2);
    py_elem = self->funcs->base.get_elem_wrapper(elem);
    if (!item || ! py_elem) goto error;
    PyTuple_SetItem(item, 0, PyLong_FromLong(number));
    PyTuple_SetItem(item, 1, py_elem);
    PyList_SetItem(ret, i, item);
  }
  return ret;

error:
  Py_XDECREF(py_elem);
  Py_XDECREF(item);
  Py_XDECREF(ret);
  return NULL;
}

static int PyUpb_ByNumberMap_Contains(PyObject *_self, PyObject *key) {
  PyUpb_ByNumberMap *self = PyUpb_ByNumberMap_Self(_self);
  const void *elem = PyUpb_ByNumberMap_LookupHelper(self, key);
  return elem ? 1 : 0;
}

// A mapping container can only be equal to another mapping container, or (for
// backward compatibility) to a dict containing the same items.
// Returns 1 if equal, 0 if unequal, -1 on error.
static int PyUpb_ByNumberMap_IsEqual(PyUpb_ByNumberMap* self, PyObject* other) {
  // Check the identity of C++ pointers.
  if (PyObject_TypeCheck(other, Py_TYPE(self))) {
    PyUpb_ByNumberMap *other_map = (void *)other;
    return self->parent == other_map->parent && self->funcs == other_map->funcs;
  }

  if (!PyDict_Check(other)) return 0;

  PyObject *self_dict = PyDict_New();
  PyDict_Merge(self_dict, (PyObject*)self, 0);
  int eq = PyObject_RichCompareBool(self_dict, other, Py_EQ);
  Py_DECREF(self_dict);
  return eq;
}

static PyObject *PyUpb_ByNumberMap_RichCompare(PyObject *_self, PyObject *other,
                                               int opid) {
  PyUpb_ByNumberMap *self = PyUpb_ByNumberMap_Self(_self);
  if (opid != Py_EQ && opid != Py_NE) {
    Py_RETURN_NOTIMPLEMENTED;
  }
  bool ret = PyUpb_ByNumberMap_IsEqual(self, other);
  if (opid == Py_NE) ret = !ret;
  return PyBool_FromLong(ret);
}

static PyMethodDef PyUpb_ByNumberMap_Methods[] = {
    {"get", (PyCFunction)&PyUpb_ByNumberMap_Get, METH_VARARGS},
    {"keys", PyUpb_ByNumberMap_Keys, METH_NOARGS},
    {"values", PyUpb_ByNumberMap_Values, METH_NOARGS},
    {"items", PyUpb_ByNumberMap_Items, METH_NOARGS},
    {NULL}};

static PyType_Slot PyUpb_ByNumberMap_Slots[] = {
    {Py_mp_ass_subscript, PyUpb_ByNumberMap_AssignSubscript},
    {Py_mp_length, PyUpb_ByNumberMap_Length},
    {Py_mp_subscript, PyUpb_ByNumberMap_Subscript},
    {Py_sq_contains, &PyUpb_ByNumberMap_Contains},
    {Py_tp_dealloc, &PyUpb_ByNumberMap_Dealloc},
    {Py_tp_iter, PyUpb_ByNumberMap_GetIter},
    {Py_tp_methods, &PyUpb_ByNumberMap_Methods},
    {Py_tp_richcompare, &PyUpb_ByNumberMap_RichCompare},
    {0, NULL},
};

static PyType_Spec PyUpb_ByNumberMap_Spec = {
  PYUPB_MODULE_NAME "._ByNumberMap",     // tp_name
  sizeof(PyUpb_ByNumberMap),             // tp_basicsize
  0,                                     // tp_itemsize
  Py_TPFLAGS_DEFAULT,                    // tp_flags
  PyUpb_ByNumberMap_Slots,
};

// -----------------------------------------------------------------------------
// Top Level
// -----------------------------------------------------------------------------

bool PyUpb_InitDescriptorContainers(PyObject* m) {
  PyUpb_ModuleState *s = PyUpb_ModuleState_GetFromModule(m);

  s->by_name_map_type = PyUpb_AddClass(m, &PyUpb_ByNameMap_Spec);
  s->by_number_map_type = PyUpb_AddClass(m, &PyUpb_ByNumberMap_Spec);
  s->descriptor_iterator_type =
      PyUpb_AddClass(m, &PyUpb_DescriptorIterator_Spec);
  s->generic_sequence_type =
      PyUpb_AddClass(m, &PyUpb_GenericSequence_Spec);

  return s->by_name_map_type && s->by_number_map_type &&
         s->descriptor_iterator_type && s->generic_sequence_type;
}
