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

// Mappings and Sequences of descriptors.
// Used by Descriptor.fields_by_name, EnumDescriptor.values...
//
// They avoid the allocation of a full dictionary or a full list: they simply
// store a pointer to the parent descriptor, use the C++ Descriptor methods (see
// google/protobuf/descriptor.h) to retrieve other descriptors, and create
// Python objects on the fly.
//
// The containers fully conform to abc.Mapping and abc.Sequence, and behave just
// like read-only dictionaries and lists.
//
// Because the interface of C++ Descriptors is quite regular, this file actually
// defines only three types, the exact behavior of a container is controlled by
// a DescriptorContainerDef structure, which contains functions that uses the
// public Descriptor API.
//
// Note: This DescriptorContainerDef is similar to the "virtual methods table"
// that a C++ compiler generates for a class. We have to make it explicit
// because the Python API is based on C, and does not play well with C++
// inheritance.

#include <Python.h>

#include <google/protobuf/descriptor.h>
#include <google/protobuf/pyext/descriptor_containers.h>
#include <google/protobuf/pyext/descriptor_pool.h>
#include <google/protobuf/pyext/descriptor.h>
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>

#if PY_MAJOR_VERSION >= 3
  #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
  #define PyString_FromFormat PyUnicode_FromFormat
  #define PyInt_FromLong PyLong_FromLong
  #if PY_VERSION_HEX < 0x03030000
    #error "Python 3.0 - 3.2 are not supported."
  #endif
  #define PyString_AsStringAndSize(ob, charpp, sizep) \
    (PyUnicode_Check(ob)? \
       ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
       PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
#endif

namespace google {
namespace protobuf {
namespace python {

struct PyContainer;

typedef int (*CountMethod)(PyContainer* self);
typedef const void* (*GetByIndexMethod)(PyContainer* self, int index);
typedef const void* (*GetByNameMethod)(PyContainer* self, const string& name);
typedef const void* (*GetByCamelcaseNameMethod)(PyContainer* self,
                                                const string& name);
typedef const void* (*GetByNumberMethod)(PyContainer* self, int index);
typedef PyObject* (*NewObjectFromItemMethod)(const void* descriptor);
typedef const string& (*GetItemNameMethod)(const void* descriptor);
typedef const string& (*GetItemCamelcaseNameMethod)(const void* descriptor);
typedef int (*GetItemNumberMethod)(const void* descriptor);
typedef int (*GetItemIndexMethod)(const void* descriptor);

struct DescriptorContainerDef {
  const char* mapping_name;
  // Returns the number of items in the container.
  CountMethod count_fn;
  // Retrieve item by index (usually the order of declaration in the proto file)
  // Used by sequences, but also iterators. 0 <= index < Count().
  GetByIndexMethod get_by_index_fn;
  // Retrieve item by name (usually a call to some 'FindByName' method).
  // Used by "by_name" mappings.
  GetByNameMethod get_by_name_fn;
  // Retrieve item by camelcase name (usually a call to some
  // 'FindByCamelcaseName' method). Used by "by_camelcase_name" mappings.
  GetByCamelcaseNameMethod get_by_camelcase_name_fn;
  // Retrieve item by declared number (field tag, or enum value).
  // Used by "by_number" mappings.
  GetByNumberMethod get_by_number_fn;
  // Converts a item C++ descriptor to a Python object. Returns a new reference.
  NewObjectFromItemMethod new_object_from_item_fn;
  // Retrieve the name of an item. Used by iterators on "by_name" mappings.
  GetItemNameMethod get_item_name_fn;
  // Retrieve the camelcase name of an item. Used by iterators on
  // "by_camelcase_name" mappings.
  GetItemCamelcaseNameMethod get_item_camelcase_name_fn;
  // Retrieve the number of an item. Used by iterators on "by_number" mappings.
  GetItemNumberMethod get_item_number_fn;
  // Retrieve the index of an item for the container type.
  // Used by "__contains__".
  // If not set, "x in sequence" will do a linear search.
  GetItemIndexMethod get_item_index_fn;
};

struct PyContainer {
  PyObject_HEAD

  // The proto2 descriptor this container belongs to the global DescriptorPool.
  const void* descriptor;

  // A pointer to a static structure with function pointers that control the
  // behavior of the container. Very similar to the table of virtual functions
  // of a C++ class.
  const DescriptorContainerDef* container_def;

  // The kind of container: list, or dict by name or value.
  enum ContainerKind {
    KIND_SEQUENCE,
    KIND_BYNAME,
    KIND_BYCAMELCASENAME,
    KIND_BYNUMBER,
  } kind;
};

struct PyContainerIterator {
  PyObject_HEAD

  // The container we are iterating over. Own a reference.
  PyContainer* container;

  // The current index in the iterator.
  int index;

  // The kind of container: list, or dict by name or value.
  enum IterKind {
    KIND_ITERKEY,
    KIND_ITERVALUE,
    KIND_ITERITEM,
    KIND_ITERVALUE_REVERSED,  // For sequences
  } kind;
};

namespace descriptor {

// Returns the C++ item descriptor for a given Python key.
// When the descriptor is found, return true and set *item.
// When the descriptor is not found, return true, but set *item to NULL.
// On error, returns false with an exception set.
static bool _GetItemByKey(PyContainer* self, PyObject* key, const void** item) {
  switch (self->kind) {
    case PyContainer::KIND_BYNAME:
      {
        char* name;
        Py_ssize_t name_size;
        if (PyString_AsStringAndSize(key, &name, &name_size) < 0) {
          if (PyErr_ExceptionMatches(PyExc_TypeError)) {
            // Not a string, cannot be in the container.
            PyErr_Clear();
            *item = NULL;
            return true;
          }
          return false;
        }
        *item = self->container_def->get_by_name_fn(
            self, string(name, name_size));
        return true;
      }
    case PyContainer::KIND_BYCAMELCASENAME:
      {
        char* camelcase_name;
        Py_ssize_t name_size;
        if (PyString_AsStringAndSize(key, &camelcase_name, &name_size) < 0) {
          if (PyErr_ExceptionMatches(PyExc_TypeError)) {
            // Not a string, cannot be in the container.
            PyErr_Clear();
            *item = NULL;
            return true;
          }
          return false;
        }
        *item = self->container_def->get_by_camelcase_name_fn(
            self, string(camelcase_name, name_size));
        return true;
      }
    case PyContainer::KIND_BYNUMBER:
      {
        Py_ssize_t number = PyNumber_AsSsize_t(key, NULL);
        if (number == -1 && PyErr_Occurred()) {
          if (PyErr_ExceptionMatches(PyExc_TypeError)) {
            // Not a number, cannot be in the container.
            PyErr_Clear();
            *item = NULL;
            return true;
          }
          return false;
        }
        *item = self->container_def->get_by_number_fn(self, number);
        return true;
      }
    default:
      PyErr_SetNone(PyExc_NotImplementedError);
      return false;
  }
}

// Returns the key of the object at the given index.
// Used when iterating over mappings.
static PyObject* _NewKey_ByIndex(PyContainer* self, Py_ssize_t index) {
  const void* item = self->container_def->get_by_index_fn(self, index);
  switch (self->kind) {
    case PyContainer::KIND_BYNAME:
      {
        const string& name(self->container_def->get_item_name_fn(item));
        return PyString_FromStringAndSize(name.c_str(), name.size());
      }
    case PyContainer::KIND_BYCAMELCASENAME:
      {
        const string& name(
            self->container_def->get_item_camelcase_name_fn(item));
        return PyString_FromStringAndSize(name.c_str(), name.size());
      }
    case PyContainer::KIND_BYNUMBER:
      {
        int value = self->container_def->get_item_number_fn(item);
        return PyInt_FromLong(value);
      }
    default:
      PyErr_SetNone(PyExc_NotImplementedError);
      return NULL;
  }
}

// Returns the object at the given index.
// Also used when iterating over mappings.
static PyObject* _NewObj_ByIndex(PyContainer* self, Py_ssize_t index) {
  return self->container_def->new_object_from_item_fn(
      self->container_def->get_by_index_fn(self, index));
}

static Py_ssize_t Length(PyContainer* self) {
  return self->container_def->count_fn(self);
}

// The DescriptorMapping type.

static PyObject* Subscript(PyContainer* self, PyObject* key) {
  const void* item = NULL;
  if (!_GetItemByKey(self, key, &item)) {
    return NULL;
  }
  if (!item) {
    PyErr_SetObject(PyExc_KeyError, key);
    return NULL;
  }
  return self->container_def->new_object_from_item_fn(item);
}

static int AssSubscript(PyContainer* self, PyObject* key, PyObject* value) {
  if (_CalledFromGeneratedFile(0)) {
    return 0;
  }
  PyErr_Format(PyExc_TypeError,
               "'%.200s' object does not support item assignment",
               Py_TYPE(self)->tp_name);
  return -1;
}

static PyMappingMethods MappingMappingMethods = {
  (lenfunc)Length,               // mp_length
  (binaryfunc)Subscript,         // mp_subscript
  (objobjargproc)AssSubscript,   // mp_ass_subscript
};

static int Contains(PyContainer* self, PyObject* key) {
  const void* item = NULL;
  if (!_GetItemByKey(self, key, &item)) {
    return -1;
  }
  if (item) {
    return 1;
  } else {
    return 0;
  }
}

static PyObject* ContainerRepr(PyContainer* self) {
  const char* kind = "";
  switch (self->kind) {
    case PyContainer::KIND_SEQUENCE:
      kind = "sequence";
      break;
    case PyContainer::KIND_BYNAME:
      kind = "mapping by name";
      break;
    case PyContainer::KIND_BYCAMELCASENAME:
      kind = "mapping by camelCase name";
      break;
    case PyContainer::KIND_BYNUMBER:
      kind = "mapping by number";
      break;
  }
  return PyString_FromFormat(
      "<%s %s>", self->container_def->mapping_name, kind);
}

extern PyTypeObject DescriptorMapping_Type;
extern PyTypeObject DescriptorSequence_Type;

// 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 DescriptorSequence_Equal(PyContainer* self, PyObject* other) {
  // Check the identity of C++ pointers.
  if (PyObject_TypeCheck(other, &DescriptorSequence_Type)) {
    PyContainer* other_container = reinterpret_cast<PyContainer*>(other);
    if (self->descriptor == other_container->descriptor &&
        self->container_def == other_container->container_def &&
        self->kind == other_container->kind) {
      return 1;
    } else {
      return 0;
    }
  }

  // If other is a list
  if (PyList_Check(other)) {
    // return list(self) == other
    int size = Length(self);
    if (size != PyList_Size(other)) {
      return false;
    }
    for (int index = 0; index < size; index++) {
      ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index));
      if (value1 == NULL) {
        return -1;
      }
      PyObject* value2 = PyList_GetItem(other, index);
      if (value2 == NULL) {
        return -1;
      }
      int cmp = PyObject_RichCompareBool(value1.get(), value2, Py_EQ);
      if (cmp != 1)  // error or not equal
          return cmp;
    }
    // All items were found and equal
    return 1;
  }

  // Any other object is different.
  return 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 DescriptorMapping_Equal(PyContainer* self, PyObject* other) {
  // Check the identity of C++ pointers.
  if (PyObject_TypeCheck(other, &DescriptorMapping_Type)) {
    PyContainer* other_container = reinterpret_cast<PyContainer*>(other);
    if (self->descriptor == other_container->descriptor &&
        self->container_def == other_container->container_def &&
        self->kind == other_container->kind) {
      return 1;
    } else {
      return 0;
    }
  }

  // If other is a dict
  if (PyDict_Check(other)) {
    // equivalent to dict(self.items()) == other
    int size = Length(self);
    if (size != PyDict_Size(other)) {
      return false;
    }
    for (int index = 0; index < size; index++) {
      ScopedPyObjectPtr key(_NewKey_ByIndex(self, index));
      if (key == NULL) {
        return -1;
      }
      ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index));
      if (value1 == NULL) {
        return -1;
      }
      PyObject* value2 = PyDict_GetItem(other, key.get());
      if (value2 == NULL) {
        // Not found in the other dictionary
        return 0;
      }
      int cmp = PyObject_RichCompareBool(value1.get(), value2, Py_EQ);
      if (cmp != 1)  // error or not equal
          return cmp;
    }
    // All items were found and equal
    return 1;
  }

  // Any other object is different.
  return 0;
}

static PyObject* RichCompare(PyContainer* self, PyObject* other, int opid) {
  if (opid != Py_EQ && opid != Py_NE) {
    Py_INCREF(Py_NotImplemented);
    return Py_NotImplemented;
  }

  int result;

  if (self->kind == PyContainer::KIND_SEQUENCE) {
    result = DescriptorSequence_Equal(self, other);
  } else {
    result = DescriptorMapping_Equal(self, other);
  }
  if (result < 0) {
    return NULL;
  }
  if (result ^ (opid == Py_NE)) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}

static PySequenceMethods MappingSequenceMethods = {
    0,                      // sq_length
    0,                      // sq_concat
    0,                      // sq_repeat
    0,                      // sq_item
    0,                      // sq_slice
    0,                      // sq_ass_item
    0,                      // sq_ass_slice
    (objobjproc)Contains,   // sq_contains
};

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

  const void* item;
  if (!_GetItemByKey(self, key, &item)) {
    return NULL;
  }
  if (item == NULL) {
    Py_INCREF(default_value);
    return default_value;
  }
  return self->container_def->new_object_from_item_fn(item);
}

static PyObject* Keys(PyContainer* self, PyObject* args) {
  Py_ssize_t count = Length(self);
  ScopedPyObjectPtr list(PyList_New(count));
  if (list == NULL) {
    return NULL;
  }
  for (Py_ssize_t index = 0; index < count; ++index) {
    PyObject* key = _NewKey_ByIndex(self, index);
    if (key == NULL) {
      return NULL;
    }
    PyList_SET_ITEM(list.get(), index, key);
  }
  return list.release();
}

static PyObject* Values(PyContainer* self, PyObject* args) {
  Py_ssize_t count = Length(self);
  ScopedPyObjectPtr list(PyList_New(count));
  if (list == NULL) {
    return NULL;
  }
  for (Py_ssize_t index = 0; index < count; ++index) {
    PyObject* value = _NewObj_ByIndex(self, index);
    if (value == NULL) {
      return NULL;
    }
    PyList_SET_ITEM(list.get(), index, value);
  }
  return list.release();
}

static PyObject* Items(PyContainer* self, PyObject* args) {
  Py_ssize_t count = Length(self);
  ScopedPyObjectPtr list(PyList_New(count));
  if (list == NULL) {
    return NULL;
  }
  for (Py_ssize_t index = 0; index < count; ++index) {
    ScopedPyObjectPtr obj(PyTuple_New(2));
    if (obj == NULL) {
      return NULL;
    }
    PyObject* key = _NewKey_ByIndex(self, index);
    if (key == NULL) {
      return NULL;
    }
    PyTuple_SET_ITEM(obj.get(), 0, key);
    PyObject* value = _NewObj_ByIndex(self, index);
    if (value == NULL) {
      return NULL;
    }
    PyTuple_SET_ITEM(obj.get(), 1, value);
    PyList_SET_ITEM(list.get(), index, obj.release());
  }
  return list.release();
}

static PyObject* NewContainerIterator(PyContainer* mapping,
                                      PyContainerIterator::IterKind kind);

static PyObject* Iter(PyContainer* self) {
  return NewContainerIterator(self, PyContainerIterator::KIND_ITERKEY);
}
static PyObject* IterKeys(PyContainer* self, PyObject* args) {
  return NewContainerIterator(self, PyContainerIterator::KIND_ITERKEY);
}
static PyObject* IterValues(PyContainer* self, PyObject* args) {
  return NewContainerIterator(self, PyContainerIterator::KIND_ITERVALUE);
}
static PyObject* IterItems(PyContainer* self, PyObject* args) {
  return NewContainerIterator(self, PyContainerIterator::KIND_ITERITEM);
}

static PyMethodDef MappingMethods[] = {
  { "get", (PyCFunction)Get, METH_VARARGS, },
  { "keys", (PyCFunction)Keys, METH_NOARGS, },
  { "values", (PyCFunction)Values, METH_NOARGS, },
  { "items", (PyCFunction)Items, METH_NOARGS, },
  { "iterkeys", (PyCFunction)IterKeys, METH_NOARGS, },
  { "itervalues", (PyCFunction)IterValues, METH_NOARGS, },
  { "iteritems", (PyCFunction)IterItems, METH_NOARGS, },
  {NULL}
};

PyTypeObject DescriptorMapping_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  "DescriptorMapping",                  // tp_name
  sizeof(PyContainer),                  // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // tp_dealloc
  0,                                    // tp_print
  0,                                    // tp_getattr
  0,                                    // tp_setattr
  0,                                    // tp_compare
  (reprfunc)ContainerRepr,              // tp_repr
  0,                                    // tp_as_number
  &MappingSequenceMethods,              // tp_as_sequence
  &MappingMappingMethods,               // tp_as_mapping
  0,                                    // tp_hash
  0,                                    // tp_call
  0,                                    // tp_str
  0,                                    // tp_getattro
  0,                                    // tp_setattro
  0,                                    // tp_as_buffer
  Py_TPFLAGS_DEFAULT,                   // tp_flags
  0,                                    // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  (richcmpfunc)RichCompare,             // tp_richcompare
  0,                                    // tp_weaklistoffset
  (getiterfunc)Iter,                    // tp_iter
  0,                                    // tp_iternext
  MappingMethods,                       // tp_methods
  0,                                    // tp_members
  0,                                    // tp_getset
  0,                                    // tp_base
  0,                                    // tp_dict
  0,                                    // tp_descr_get
  0,                                    // tp_descr_set
  0,                                    // tp_dictoffset
  0,                                    // tp_init
  0,                                    // tp_alloc
  0,                                    // tp_new
  0,                                    // tp_free
};

// The DescriptorSequence type.

static PyObject* GetItem(PyContainer* self, Py_ssize_t index) {
  if (index < 0) {
    index += Length(self);
  }
  if (index < 0 || index >= Length(self)) {
    PyErr_SetString(PyExc_IndexError, "index out of range");
    return NULL;
  }
  return _NewObj_ByIndex(self, index);
}

// Returns the position of the item in the sequence, of -1 if not found.
// This function never fails.
int Find(PyContainer* self, PyObject* item) {
  // The item can only be in one position: item.index.
  // Check that self[item.index] == item, it's faster than a linear search.
  //
  // This assumes that sequences are only defined by syntax of the .proto file:
  // a specific item belongs to only one sequence, depending on its position in
  // the .proto file definition.
  const void* descriptor_ptr = PyDescriptor_AsVoidPtr(item);
  if (descriptor_ptr == NULL) {
    // Not a descriptor, it cannot be in the list.
    return -1;
  }
  if (self->container_def->get_item_index_fn) {
    int index = self->container_def->get_item_index_fn(descriptor_ptr);
    if (index < 0 || index >= Length(self)) {
      // This index is not from this collection.
      return -1;
    }
    if (self->container_def->get_by_index_fn(self, index) != descriptor_ptr) {
      // The descriptor at this index is not the same.
      return -1;
    }
    // self[item.index] == item, so return the index.
    return index;
  } else {
    // Fall back to linear search.
    int length = Length(self);
    for (int index=0; index < length; index++) {
      if (self->container_def->get_by_index_fn(self, index) == descriptor_ptr) {
        return index;
      }
    }
    // Not found
    return -1;
  }
}

// Implements list.index(): the position of the item is in the sequence.
static PyObject* Index(PyContainer* self, PyObject* item) {
  int position = Find(self, item);
  if (position < 0) {
    // Not found
    PyErr_SetNone(PyExc_ValueError);
    return NULL;
  } else {
    return PyInt_FromLong(position);
  }
}
// Implements "list.__contains__()": is the object in the sequence.
static int SeqContains(PyContainer* self, PyObject* item) {
  int position = Find(self, item);
  if (position < 0) {
    return 0;
  } else {
    return 1;
  }
}

// Implements list.count(): number of occurrences of the item in the sequence.
// An item can only appear once in a sequence. If it exists, return 1.
static PyObject* Count(PyContainer* self, PyObject* item) {
  int position = Find(self, item);
  if (position < 0) {
    return PyInt_FromLong(0);
  } else {
    return PyInt_FromLong(1);
  }
}

static PyObject* Append(PyContainer* self, PyObject* args) {
  if (_CalledFromGeneratedFile(0)) {
    Py_RETURN_NONE;
  }
  PyErr_Format(PyExc_TypeError,
               "'%.200s' object is not a mutable sequence",
               Py_TYPE(self)->tp_name);
  return NULL;
}

static PyObject* Reversed(PyContainer* self, PyObject* args) {
  return NewContainerIterator(self,
                              PyContainerIterator::KIND_ITERVALUE_REVERSED);
}

static PyMethodDef SeqMethods[] = {
  { "index", (PyCFunction)Index, METH_O, },
  { "count", (PyCFunction)Count, METH_O, },
  { "append", (PyCFunction)Append, METH_O, },
  { "__reversed__", (PyCFunction)Reversed, METH_NOARGS, },
  {NULL}
};

static PySequenceMethods SeqSequenceMethods = {
    (lenfunc)Length,          // sq_length
    0,                        // sq_concat
    0,                        // sq_repeat
    (ssizeargfunc)GetItem,    // sq_item
    0,                        // sq_slice
    0,                        // sq_ass_item
    0,                        // sq_ass_slice
    (objobjproc)SeqContains,  // sq_contains
};

PyTypeObject DescriptorSequence_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  "DescriptorSequence",                 // tp_name
  sizeof(PyContainer),                  // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // tp_dealloc
  0,                                    // tp_print
  0,                                    // tp_getattr
  0,                                    // tp_setattr
  0,                                    // tp_compare
  (reprfunc)ContainerRepr,              // tp_repr
  0,                                    // tp_as_number
  &SeqSequenceMethods,                  // tp_as_sequence
  0,                                    // tp_as_mapping
  0,                                    // tp_hash
  0,                                    // tp_call
  0,                                    // tp_str
  0,                                    // tp_getattro
  0,                                    // tp_setattro
  0,                                    // tp_as_buffer
  Py_TPFLAGS_DEFAULT,                   // tp_flags
  0,                                    // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  (richcmpfunc)RichCompare,             // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  SeqMethods,                           // tp_methods
  0,                                    // tp_members
  0,                                    // tp_getset
  0,                                    // tp_base
  0,                                    // tp_dict
  0,                                    // tp_descr_get
  0,                                    // tp_descr_set
  0,                                    // tp_dictoffset
  0,                                    // tp_init
  0,                                    // tp_alloc
  0,                                    // tp_new
  0,                                    // tp_free
};

static PyObject* NewMappingByName(
    DescriptorContainerDef* container_def, const void* descriptor) {
  PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
  if (self == NULL) {
    return NULL;
  }
  self->descriptor = descriptor;
  self->container_def = container_def;
  self->kind = PyContainer::KIND_BYNAME;
  return reinterpret_cast<PyObject*>(self);
}

static PyObject* NewMappingByCamelcaseName(
    DescriptorContainerDef* container_def, const void* descriptor) {
  PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
  if (self == NULL) {
    return NULL;
  }
  self->descriptor = descriptor;
  self->container_def = container_def;
  self->kind = PyContainer::KIND_BYCAMELCASENAME;
  return reinterpret_cast<PyObject*>(self);
}

static PyObject* NewMappingByNumber(
    DescriptorContainerDef* container_def, const void* descriptor) {
  if (container_def->get_by_number_fn == NULL ||
      container_def->get_item_number_fn == NULL) {
    PyErr_SetNone(PyExc_NotImplementedError);
    return NULL;
  }
  PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
  if (self == NULL) {
    return NULL;
  }
  self->descriptor = descriptor;
  self->container_def = container_def;
  self->kind = PyContainer::KIND_BYNUMBER;
  return reinterpret_cast<PyObject*>(self);
}

static PyObject* NewSequence(
    DescriptorContainerDef* container_def, const void* descriptor) {
  PyContainer* self = PyObject_New(PyContainer, &DescriptorSequence_Type);
  if (self == NULL) {
    return NULL;
  }
  self->descriptor = descriptor;
  self->container_def = container_def;
  self->kind = PyContainer::KIND_SEQUENCE;
  return reinterpret_cast<PyObject*>(self);
}

// Implement iterators over PyContainers.

static void Iterator_Dealloc(PyContainerIterator* self) {
  Py_CLEAR(self->container);
  Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
}

static PyObject* Iterator_Next(PyContainerIterator* self) {
  int count = self->container->container_def->count_fn(self->container);
  if (self->index >= count) {
    // Return NULL with no exception to indicate the end.
    return NULL;
  }
  int index = self->index;
  self->index += 1;
  switch (self->kind) {
    case PyContainerIterator::KIND_ITERKEY:
      return _NewKey_ByIndex(self->container, index);
    case PyContainerIterator::KIND_ITERVALUE:
      return _NewObj_ByIndex(self->container, index);
    case PyContainerIterator::KIND_ITERVALUE_REVERSED:
      return _NewObj_ByIndex(self->container, count - index - 1);
    case PyContainerIterator::KIND_ITERITEM:
      {
        PyObject* obj = PyTuple_New(2);
        if (obj == NULL) {
          return NULL;
        }
        PyObject* key = _NewKey_ByIndex(self->container, index);
        if (key == NULL) {
          Py_DECREF(obj);
          return NULL;
        }
        PyTuple_SET_ITEM(obj, 0, key);
        PyObject* value = _NewObj_ByIndex(self->container, index);
        if (value == NULL) {
          Py_DECREF(obj);
          return NULL;
        }
        PyTuple_SET_ITEM(obj, 1, value);
        return obj;
      }
    default:
      PyErr_SetNone(PyExc_NotImplementedError);
      return NULL;
  }
}

static PyTypeObject ContainerIterator_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  "DescriptorContainerIterator",        // tp_name
  sizeof(PyContainerIterator),          // tp_basicsize
  0,                                    // tp_itemsize
  (destructor)Iterator_Dealloc,         // tp_dealloc
  0,                                    // tp_print
  0,                                    // tp_getattr
  0,                                    // tp_setattr
  0,                                    // tp_compare
  0,                                    // tp_repr
  0,                                    // tp_as_number
  0,                                    // tp_as_sequence
  0,                                    // tp_as_mapping
  0,                                    // tp_hash
  0,                                    // tp_call
  0,                                    // tp_str
  0,                                    // tp_getattro
  0,                                    // tp_setattro
  0,                                    // tp_as_buffer
  Py_TPFLAGS_DEFAULT,                   // tp_flags
  0,                                    // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  PyObject_SelfIter,                    // tp_iter
  (iternextfunc)Iterator_Next,          // tp_iternext
  0,                                    // tp_methods
  0,                                    // tp_members
  0,                                    // tp_getset
  0,                                    // tp_base
  0,                                    // tp_dict
  0,                                    // tp_descr_get
  0,                                    // tp_descr_set
  0,                                    // tp_dictoffset
  0,                                    // tp_init
  0,                                    // tp_alloc
  0,                                    // tp_new
  0,                                    // tp_free
};

static PyObject* NewContainerIterator(PyContainer* container,
                                      PyContainerIterator::IterKind kind) {
  PyContainerIterator* self = PyObject_New(PyContainerIterator,
                                           &ContainerIterator_Type);
  if (self == NULL) {
    return NULL;
  }
  Py_INCREF(container);
  self->container = container;
  self->kind = kind;
  self->index = 0;

  return reinterpret_cast<PyObject*>(self);
}

}  // namespace descriptor

// Now define the real collections!

namespace message_descriptor {

typedef const Descriptor* ParentDescriptor;

static ParentDescriptor GetDescriptor(PyContainer* self) {
  return reinterpret_cast<ParentDescriptor>(self->descriptor);
}

namespace fields {

typedef const FieldDescriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  return GetDescriptor(self)->field_count();
}

static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  return GetDescriptor(self)->FindFieldByName(name);
}

static ItemDescriptor GetByCamelcaseName(PyContainer* self,
                                         const string& name) {
  return GetDescriptor(self)->FindFieldByCamelcaseName(name);
}

static ItemDescriptor GetByNumber(PyContainer* self, int number) {
  return GetDescriptor(self)->FindFieldByNumber(number);
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  return GetDescriptor(self)->field(index);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyFieldDescriptor_FromDescriptor(item);
}

static const string& GetItemName(ItemDescriptor item) {
  return item->name();
}

static const string& GetItemCamelcaseName(ItemDescriptor item) {
  return item->camelcase_name();
}

static int GetItemNumber(ItemDescriptor item) {
  return item->number();
}

static int GetItemIndex(ItemDescriptor item) {
  return item->index();
}

static DescriptorContainerDef ContainerDef = {
  "MessageFields",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)GetByName,
  (GetByCamelcaseNameMethod)GetByCamelcaseName,
  (GetByNumberMethod)GetByNumber,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)GetItemName,
  (GetItemCamelcaseNameMethod)GetItemCamelcaseName,
  (GetItemNumberMethod)GetItemNumber,
  (GetItemIndexMethod)GetItemIndex,
};

}  // namespace fields

PyObject* NewMessageFieldsByName(ParentDescriptor descriptor) {
  return descriptor::NewMappingByName(&fields::ContainerDef, descriptor);
}

PyObject* NewMessageFieldsByCamelcaseName(ParentDescriptor descriptor) {
  return descriptor::NewMappingByCamelcaseName(&fields::ContainerDef,
                                               descriptor);
}

PyObject* NewMessageFieldsByNumber(ParentDescriptor descriptor) {
  return descriptor::NewMappingByNumber(&fields::ContainerDef, descriptor);
}

PyObject* NewMessageFieldsSeq(ParentDescriptor descriptor) {
  return descriptor::NewSequence(&fields::ContainerDef, descriptor);
}

namespace nested_types {

typedef const Descriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  return GetDescriptor(self)->nested_type_count();
}

static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  return GetDescriptor(self)->FindNestedTypeByName(name);
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  return GetDescriptor(self)->nested_type(index);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyMessageDescriptor_FromDescriptor(item);
}

static const string& GetItemName(ItemDescriptor item) {
  return item->name();
}

static int GetItemIndex(ItemDescriptor item) {
  return item->index();
}

static DescriptorContainerDef ContainerDef = {
  "MessageNestedTypes",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)GetByName,
  (GetByCamelcaseNameMethod)NULL,
  (GetByNumberMethod)NULL,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)GetItemName,
  (GetItemCamelcaseNameMethod)NULL,
  (GetItemNumberMethod)NULL,
  (GetItemIndexMethod)GetItemIndex,
};

}  // namespace nested_types

PyObject* NewMessageNestedTypesSeq(ParentDescriptor descriptor) {
  return descriptor::NewSequence(&nested_types::ContainerDef, descriptor);
}

PyObject* NewMessageNestedTypesByName(ParentDescriptor descriptor) {
  return descriptor::NewMappingByName(&nested_types::ContainerDef, descriptor);
}

namespace enums {

typedef const EnumDescriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  return GetDescriptor(self)->enum_type_count();
}

static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  return GetDescriptor(self)->FindEnumTypeByName(name);
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  return GetDescriptor(self)->enum_type(index);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyEnumDescriptor_FromDescriptor(item);
}

static const string& GetItemName(ItemDescriptor item) {
  return item->name();
}

static int GetItemIndex(ItemDescriptor item) {
  return item->index();
}

static DescriptorContainerDef ContainerDef = {
  "MessageNestedEnums",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)GetByName,
  (GetByCamelcaseNameMethod)NULL,
  (GetByNumberMethod)NULL,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)GetItemName,
  (GetItemCamelcaseNameMethod)NULL,
  (GetItemNumberMethod)NULL,
  (GetItemIndexMethod)GetItemIndex,
};

}  // namespace enums

PyObject* NewMessageEnumsByName(ParentDescriptor descriptor) {
  return descriptor::NewMappingByName(&enums::ContainerDef, descriptor);
}

PyObject* NewMessageEnumsSeq(ParentDescriptor descriptor) {
  return descriptor::NewSequence(&enums::ContainerDef, descriptor);
}

namespace enumvalues {

// This is the "enum_values_by_name" mapping, which collects values from all
// enum types in a message.
//
// Note that the behavior of the C++ descriptor is different: it will search and
// return the first value that matches the name, whereas the Python
// implementation retrieves the last one.

typedef const EnumValueDescriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  int count = 0;
  for (int i = 0; i < GetDescriptor(self)->enum_type_count(); ++i) {
    count += GetDescriptor(self)->enum_type(i)->value_count();
  }
  return count;
}

static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  return GetDescriptor(self)->FindEnumValueByName(name);
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  // This is not optimal, but the number of enums *types* in a given message
  // is small.  This function is only used when iterating over the mapping.
  const EnumDescriptor* enum_type = NULL;
  int enum_type_count = GetDescriptor(self)->enum_type_count();
  for (int i = 0; i < enum_type_count; ++i) {
    enum_type = GetDescriptor(self)->enum_type(i);
    int enum_value_count = enum_type->value_count();
    if (index < enum_value_count) {
      // Found it!
      break;
    }
    index -= enum_value_count;
  }
  // The next statement cannot overflow, because this function is only called by
  // internal iterators which ensure that 0 <= index < Count().
  return enum_type->value(index);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyEnumValueDescriptor_FromDescriptor(item);
}

static const string& GetItemName(ItemDescriptor item) {
  return item->name();
}

static DescriptorContainerDef ContainerDef = {
  "MessageEnumValues",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)GetByName,
  (GetByCamelcaseNameMethod)NULL,
  (GetByNumberMethod)NULL,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)GetItemName,
  (GetItemCamelcaseNameMethod)NULL,
  (GetItemNumberMethod)NULL,
  (GetItemIndexMethod)NULL,
};

}  // namespace enumvalues

PyObject* NewMessageEnumValuesByName(ParentDescriptor descriptor) {
  return descriptor::NewMappingByName(&enumvalues::ContainerDef, descriptor);
}

namespace extensions {

typedef const FieldDescriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  return GetDescriptor(self)->extension_count();
}

static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  return GetDescriptor(self)->FindExtensionByName(name);
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  return GetDescriptor(self)->extension(index);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyFieldDescriptor_FromDescriptor(item);
}

static const string& GetItemName(ItemDescriptor item) {
  return item->name();
}

static int GetItemIndex(ItemDescriptor item) {
  return item->index();
}

static DescriptorContainerDef ContainerDef = {
  "MessageExtensions",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)GetByName,
  (GetByCamelcaseNameMethod)NULL,
  (GetByNumberMethod)NULL,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)GetItemName,
  (GetItemCamelcaseNameMethod)NULL,
  (GetItemNumberMethod)NULL,
  (GetItemIndexMethod)GetItemIndex,
};

}  // namespace extensions

PyObject* NewMessageExtensionsByName(ParentDescriptor descriptor) {
  return descriptor::NewMappingByName(&extensions::ContainerDef, descriptor);
}

PyObject* NewMessageExtensionsSeq(ParentDescriptor descriptor) {
  return descriptor::NewSequence(&extensions::ContainerDef, descriptor);
}

namespace oneofs {

typedef const OneofDescriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  return GetDescriptor(self)->oneof_decl_count();
}

static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  return GetDescriptor(self)->FindOneofByName(name);
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  return GetDescriptor(self)->oneof_decl(index);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyOneofDescriptor_FromDescriptor(item);
}

static const string& GetItemName(ItemDescriptor item) {
  return item->name();
}

static int GetItemIndex(ItemDescriptor item) {
  return item->index();
}

static DescriptorContainerDef ContainerDef = {
  "MessageOneofs",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)GetByName,
  (GetByCamelcaseNameMethod)NULL,
  (GetByNumberMethod)NULL,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)GetItemName,
  (GetItemCamelcaseNameMethod)NULL,
  (GetItemNumberMethod)NULL,
  (GetItemIndexMethod)GetItemIndex,
};

}  // namespace oneofs

PyObject* NewMessageOneofsByName(ParentDescriptor descriptor) {
  return descriptor::NewMappingByName(&oneofs::ContainerDef, descriptor);
}

PyObject* NewMessageOneofsSeq(ParentDescriptor descriptor) {
  return descriptor::NewSequence(&oneofs::ContainerDef, descriptor);
}

}  // namespace message_descriptor

namespace enum_descriptor {

typedef const EnumDescriptor* ParentDescriptor;

static ParentDescriptor GetDescriptor(PyContainer* self) {
  return reinterpret_cast<ParentDescriptor>(self->descriptor);
}

namespace enumvalues {

typedef const EnumValueDescriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  return GetDescriptor(self)->value_count();
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  return GetDescriptor(self)->value(index);
}

static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  return GetDescriptor(self)->FindValueByName(name);
}

static ItemDescriptor GetByNumber(PyContainer* self, int number) {
  return GetDescriptor(self)->FindValueByNumber(number);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyEnumValueDescriptor_FromDescriptor(item);
}

static const string& GetItemName(ItemDescriptor item) {
  return item->name();
}

static int GetItemNumber(ItemDescriptor item) {
  return item->number();
}

static int GetItemIndex(ItemDescriptor item) {
  return item->index();
}

static DescriptorContainerDef ContainerDef = {
  "EnumValues",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)GetByName,
  (GetByCamelcaseNameMethod)NULL,
  (GetByNumberMethod)GetByNumber,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)GetItemName,
  (GetItemCamelcaseNameMethod)NULL,
  (GetItemNumberMethod)GetItemNumber,
  (GetItemIndexMethod)GetItemIndex,
};

}  // namespace enumvalues

PyObject* NewEnumValuesByName(ParentDescriptor descriptor) {
  return descriptor::NewMappingByName(&enumvalues::ContainerDef, descriptor);
}

PyObject* NewEnumValuesByNumber(ParentDescriptor descriptor) {
  return descriptor::NewMappingByNumber(&enumvalues::ContainerDef, descriptor);
}

PyObject* NewEnumValuesSeq(ParentDescriptor descriptor) {
  return descriptor::NewSequence(&enumvalues::ContainerDef, descriptor);
}

}  // namespace enum_descriptor

namespace oneof_descriptor {

typedef const OneofDescriptor* ParentDescriptor;

static ParentDescriptor GetDescriptor(PyContainer* self) {
  return reinterpret_cast<ParentDescriptor>(self->descriptor);
}

namespace fields {

typedef const FieldDescriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  return GetDescriptor(self)->field_count();
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  return GetDescriptor(self)->field(index);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyFieldDescriptor_FromDescriptor(item);
}

static int GetItemIndex(ItemDescriptor item) {
  return item->index_in_oneof();
}

static DescriptorContainerDef ContainerDef = {
  "OneofFields",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)NULL,
  (GetByCamelcaseNameMethod)NULL,
  (GetByNumberMethod)NULL,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)NULL,
  (GetItemCamelcaseNameMethod)NULL,
  (GetItemNumberMethod)NULL,
  (GetItemIndexMethod)GetItemIndex,
};

}  // namespace fields

PyObject* NewOneofFieldsSeq(ParentDescriptor descriptor) {
  return descriptor::NewSequence(&fields::ContainerDef, descriptor);
}

}  // namespace oneof_descriptor

namespace file_descriptor {

typedef const FileDescriptor* ParentDescriptor;

static ParentDescriptor GetDescriptor(PyContainer* self) {
  return reinterpret_cast<ParentDescriptor>(self->descriptor);
}

namespace messages {

typedef const Descriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  return GetDescriptor(self)->message_type_count();
}

static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  return GetDescriptor(self)->FindMessageTypeByName(name);
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  return GetDescriptor(self)->message_type(index);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyMessageDescriptor_FromDescriptor(item);
}

static const string& GetItemName(ItemDescriptor item) {
  return item->name();
}

static int GetItemIndex(ItemDescriptor item) {
  return item->index();
}

static DescriptorContainerDef ContainerDef = {
  "FileMessages",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)GetByName,
  (GetByCamelcaseNameMethod)NULL,
  (GetByNumberMethod)NULL,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)GetItemName,
  (GetItemCamelcaseNameMethod)NULL,
  (GetItemNumberMethod)NULL,
  (GetItemIndexMethod)GetItemIndex,
};

}  // namespace messages

PyObject* NewFileMessageTypesByName(const FileDescriptor* descriptor) {
  return descriptor::NewMappingByName(&messages::ContainerDef, descriptor);
}

namespace enums {

typedef const EnumDescriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  return GetDescriptor(self)->enum_type_count();
}

static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  return GetDescriptor(self)->FindEnumTypeByName(name);
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  return GetDescriptor(self)->enum_type(index);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyEnumDescriptor_FromDescriptor(item);
}

static const string& GetItemName(ItemDescriptor item) {
  return item->name();
}

static int GetItemIndex(ItemDescriptor item) {
  return item->index();
}

static DescriptorContainerDef ContainerDef = {
  "FileEnums",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)GetByName,
  (GetByCamelcaseNameMethod)NULL,
  (GetByNumberMethod)NULL,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)GetItemName,
  (GetItemCamelcaseNameMethod)NULL,
  (GetItemNumberMethod)NULL,
  (GetItemIndexMethod)GetItemIndex,
};

}  // namespace enums

PyObject* NewFileEnumTypesByName(const FileDescriptor* descriptor) {
  return descriptor::NewMappingByName(&enums::ContainerDef, descriptor);
}

namespace extensions {

typedef const FieldDescriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  return GetDescriptor(self)->extension_count();
}

static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  return GetDescriptor(self)->FindExtensionByName(name);
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  return GetDescriptor(self)->extension(index);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyFieldDescriptor_FromDescriptor(item);
}

static const string& GetItemName(ItemDescriptor item) {
  return item->name();
}

static int GetItemIndex(ItemDescriptor item) {
  return item->index();
}

static DescriptorContainerDef ContainerDef = {
  "FileExtensions",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)GetByName,
  (GetByCamelcaseNameMethod)NULL,
  (GetByNumberMethod)NULL,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)GetItemName,
  (GetItemCamelcaseNameMethod)NULL,
  (GetItemNumberMethod)NULL,
  (GetItemIndexMethod)GetItemIndex,
};

}  // namespace extensions

PyObject* NewFileExtensionsByName(const FileDescriptor* descriptor) {
  return descriptor::NewMappingByName(&extensions::ContainerDef, descriptor);
}

namespace dependencies {

typedef const FileDescriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  return GetDescriptor(self)->dependency_count();
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  return GetDescriptor(self)->dependency(index);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyFileDescriptor_FromDescriptor(item);
}

static DescriptorContainerDef ContainerDef = {
  "FileDependencies",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)NULL,
  (GetByCamelcaseNameMethod)NULL,
  (GetByNumberMethod)NULL,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)NULL,
  (GetItemCamelcaseNameMethod)NULL,
  (GetItemNumberMethod)NULL,
  (GetItemIndexMethod)NULL,
};

}  // namespace dependencies

PyObject* NewFileDependencies(const FileDescriptor* descriptor) {
  return descriptor::NewSequence(&dependencies::ContainerDef, descriptor);
}

namespace public_dependencies {

typedef const FileDescriptor* ItemDescriptor;

static int Count(PyContainer* self) {
  return GetDescriptor(self)->public_dependency_count();
}

static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  return GetDescriptor(self)->public_dependency(index);
}

static PyObject* NewObjectFromItem(ItemDescriptor item) {
  return PyFileDescriptor_FromDescriptor(item);
}

static DescriptorContainerDef ContainerDef = {
  "FilePublicDependencies",
  (CountMethod)Count,
  (GetByIndexMethod)GetByIndex,
  (GetByNameMethod)NULL,
  (GetByCamelcaseNameMethod)NULL,
  (GetByNumberMethod)NULL,
  (NewObjectFromItemMethod)NewObjectFromItem,
  (GetItemNameMethod)NULL,
  (GetItemCamelcaseNameMethod)NULL,
  (GetItemNumberMethod)NULL,
  (GetItemIndexMethod)NULL,
};

}  // namespace public_dependencies

PyObject* NewFilePublicDependencies(const FileDescriptor* descriptor) {
  return descriptor::NewSequence(&public_dependencies::ContainerDef,
                                 descriptor);
}

}  // namespace file_descriptor


// Register all implementations

bool InitDescriptorMappingTypes() {
  if (PyType_Ready(&descriptor::DescriptorMapping_Type) < 0)
    return false;
  if (PyType_Ready(&descriptor::DescriptorSequence_Type) < 0)
    return false;
  if (PyType_Ready(&descriptor::ContainerIterator_Type) < 0)
    return false;
  return true;
}

}  // namespace python
}  // namespace protobuf
}  // namespace google
