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

// Author: anuraag@google.com (Anuraag Agrawal)
// Author: tibell@google.com (Johan Tibell)

#include <google/protobuf/pyext/repeated_composite_container.h>

#include <memory>

#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/message.h>
#include <google/protobuf/pyext/descriptor.h>
#include <google/protobuf/pyext/descriptor_pool.h>
#include <google/protobuf/pyext/message.h>
#include <google/protobuf/pyext/message_factory.h>
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
#include <google/protobuf/reflection.h>

#if PY_MAJOR_VERSION >= 3
  #define PyInt_Check PyLong_Check
  #define PyInt_AsLong PyLong_AsLong
  #define PyInt_FromLong PyLong_FromLong
#endif

namespace google {
namespace protobuf {
namespace python {

namespace repeated_composite_container {

// TODO(tibell): We might also want to check:
//   GOOGLE_CHECK_NOTNULL((self)->owner.get());
#define GOOGLE_CHECK_ATTACHED(self)                           \
  do {                                                 \
    GOOGLE_CHECK_NOTNULL((self)->message);                 \
    GOOGLE_CHECK_NOTNULL((self)->parent_field_descriptor); \
  } while (0);

#define GOOGLE_CHECK_RELEASED(self)             \
  do {                                   \
    GOOGLE_CHECK((self)->owner.get() == NULL);  \
    GOOGLE_CHECK((self)->message == NULL);      \
    GOOGLE_CHECK((self)->parent_field_descriptor == NULL); \
    GOOGLE_CHECK((self)->parent == NULL);       \
  } while (0);

// ---------------------------------------------------------------------
// len()

static Py_ssize_t Length(PyObject* pself) {
  RepeatedCompositeContainer* self =
      reinterpret_cast<RepeatedCompositeContainer*>(pself);

  Message* message = self->message;
  if (message != NULL) {
    return message->GetReflection()->FieldSize(*message,
                                               self->parent_field_descriptor);
  } else {
    // The container has been released (i.e. by a call to Clear() or
    // ClearField() on the parent) and thus there's no message.
    return PyList_GET_SIZE(self->child_messages);
  }
}

// Returns 0 if successful; returns -1 and sets an exception if
// unsuccessful.
static int UpdateChildMessages(RepeatedCompositeContainer* self) {
  if (self->message == NULL)
    return 0;

  // A MergeFrom on a parent message could have caused extra messages to be
  // added in the underlying protobuf so add them to our list. They can never
  // be removed in such a way so there's no need to worry about that.
  Py_ssize_t message_length = Length(reinterpret_cast<PyObject*>(self));
  Py_ssize_t child_length = PyList_GET_SIZE(self->child_messages);
  Message* message = self->message;
  const Reflection* reflection = message->GetReflection();
  for (Py_ssize_t i = child_length; i < message_length; ++i) {
    const Message& sub_message = reflection->GetRepeatedMessage(
        *(self->message), self->parent_field_descriptor, i);
    CMessage* cmsg = cmessage::NewEmptyMessage(self->child_message_class);
    ScopedPyObjectPtr py_cmsg(reinterpret_cast<PyObject*>(cmsg));
    if (cmsg == NULL) {
      return -1;
    }
    cmsg->owner = self->owner;
    cmsg->message = const_cast<Message*>(&sub_message);
    cmsg->parent = self->parent;
    if (PyList_Append(self->child_messages, py_cmsg.get()) < 0) {
      return -1;
    }
  }
  return 0;
}

// ---------------------------------------------------------------------
// add()

static PyObject* AddToAttached(RepeatedCompositeContainer* self,
                               PyObject* args,
                               PyObject* kwargs) {
  GOOGLE_CHECK_ATTACHED(self);

  if (UpdateChildMessages(self) < 0) {
    return NULL;
  }
  if (cmessage::AssureWritable(self->parent) == -1)
    return NULL;
  Message* message = self->message;

  Message* sub_message =
      message->GetReflection()->AddMessage(
          message,
          self->parent_field_descriptor,
          self->child_message_class->py_message_factory->message_factory);
  CMessage* cmsg = cmessage::NewEmptyMessage(self->child_message_class);
  if (cmsg == NULL)
    return NULL;

  cmsg->owner = self->owner;
  cmsg->message = sub_message;
  cmsg->parent = self->parent;
  if (cmessage::InitAttributes(cmsg, args, kwargs) < 0) {
    message->GetReflection()->RemoveLast(
        message, self->parent_field_descriptor);
    Py_DECREF(cmsg);
    return NULL;
  }

  PyObject* py_cmsg = reinterpret_cast<PyObject*>(cmsg);
  return py_cmsg;
}

static PyObject* AddToReleased(RepeatedCompositeContainer* self,
                               PyObject* args,
                               PyObject* kwargs) {
  GOOGLE_CHECK_RELEASED(self);

  // Create a new Message detached from the rest.
  PyObject* py_cmsg = PyEval_CallObjectWithKeywords(
      self->child_message_class->AsPyObject(), args, kwargs);
  return py_cmsg;
}

PyObject* Add(RepeatedCompositeContainer* self,
              PyObject* args,
              PyObject* kwargs) {
  PyObject* py_cmsg;
  if (self->message == nullptr)
    py_cmsg = AddToReleased(self, args, kwargs);
  else
    py_cmsg = AddToAttached(self, args, kwargs);

  if (py_cmsg == NULL)
    return NULL;

  if (PyList_Append(self->child_messages, py_cmsg) < 0) {
    Py_DECREF(py_cmsg);
    return NULL;
  }
  return py_cmsg;
}

static PyObject* AddMethod(PyObject* self, PyObject* args, PyObject* kwargs) {
  return Add(reinterpret_cast<RepeatedCompositeContainer*>(self), args, kwargs);
}

// ---------------------------------------------------------------------
// append()

static PyObject* AddMessage(RepeatedCompositeContainer* self, PyObject* value) {
  cmessage::AssureWritable(self->parent);
  if (UpdateChildMessages(self) < 0) {
    return nullptr;
  }

  PyObject* py_cmsg;
  if (self->message == nullptr) {
    py_cmsg = AddToReleased(self, nullptr, nullptr);
    if (py_cmsg == nullptr) return nullptr;
    CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
    if (ScopedPyObjectPtr(cmessage::MergeFrom(cmsg, value)) == nullptr) {
      Py_DECREF(cmsg);
      return nullptr;
    }
  } else {
    Message* message = self->message;
    const Reflection* reflection = message->GetReflection();
    py_cmsg = AddToAttached(self, nullptr, nullptr);
    if (py_cmsg == nullptr) return nullptr;
    CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
    if (ScopedPyObjectPtr(cmessage::MergeFrom(cmsg, value)) == nullptr) {
      reflection->RemoveLast(
          message, self->parent_field_descriptor);
      Py_DECREF(cmsg);
      return nullptr;
    }
  }
  return py_cmsg;
}

static PyObject* AppendMethod(PyObject* pself, PyObject* value) {
  RepeatedCompositeContainer* self =
      reinterpret_cast<RepeatedCompositeContainer*>(pself);
  ScopedPyObjectPtr py_cmsg(AddMessage(self, value));
  if (py_cmsg == nullptr) {
    return nullptr;
  }

  if (PyList_Append(self->child_messages, py_cmsg.get()) < 0) {
    return nullptr;
  }

  Py_RETURN_NONE;
}

// ---------------------------------------------------------------------
// insert()
static PyObject* Insert(PyObject* pself, PyObject* args) {
  RepeatedCompositeContainer* self =
      reinterpret_cast<RepeatedCompositeContainer*>(pself);

  Py_ssize_t index;
  PyObject* value;
  if (!PyArg_ParseTuple(args, "nO", &index, &value)) {
    return nullptr;
  }

  ScopedPyObjectPtr py_cmsg(AddMessage(self, value));
  if (py_cmsg == nullptr) {
    return nullptr;
  }

  if (self->message != nullptr) {
    // Swap the element to right position.
    Message* message = self->message;
    const Reflection* reflection = message->GetReflection();
    const FieldDescriptor* field_descriptor = self->parent_field_descriptor;
    Py_ssize_t length = reflection->FieldSize(*message, field_descriptor) - 1;
    Py_ssize_t end_index = index;
    if (end_index < 0) end_index += length;
    if (end_index < 0) end_index = 0;
    for (Py_ssize_t i = length; i > end_index; i --) {
      reflection->SwapElements(message, field_descriptor, i, i - 1);
    }
  }

  if (PyList_Insert(self->child_messages, index, py_cmsg.get()) < 0) {
    return nullptr;
  }
  Py_RETURN_NONE;
}

// ---------------------------------------------------------------------
// extend()

PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value) {
  cmessage::AssureWritable(self->parent);
  if (UpdateChildMessages(self) < 0) {
    return NULL;
  }
  ScopedPyObjectPtr iter(PyObject_GetIter(value));
  if (iter == NULL) {
    PyErr_SetString(PyExc_TypeError, "Value must be iterable");
    return NULL;
  }
  ScopedPyObjectPtr next;
  while ((next.reset(PyIter_Next(iter.get()))) != NULL) {
    if (!PyObject_TypeCheck(next.get(), CMessage_Type)) {
      PyErr_SetString(PyExc_TypeError, "Not a cmessage");
      return NULL;
    }
    ScopedPyObjectPtr new_message(Add(self, NULL, NULL));
    if (new_message == NULL) {
      return NULL;
    }
    CMessage* new_cmessage = reinterpret_cast<CMessage*>(new_message.get());
    if (ScopedPyObjectPtr(cmessage::MergeFrom(new_cmessage, next.get())) ==
        NULL) {
      return NULL;
    }
  }
  if (PyErr_Occurred()) {
    return NULL;
  }
  Py_RETURN_NONE;
}

static PyObject* ExtendMethod(PyObject* self, PyObject* value) {
  return Extend(reinterpret_cast<RepeatedCompositeContainer*>(self), value);
}

PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other) {
  if (UpdateChildMessages(self) < 0) {
    return NULL;
  }
  return Extend(self, other);
}

static PyObject* MergeFromMethod(PyObject* self, PyObject* other) {
  return MergeFrom(reinterpret_cast<RepeatedCompositeContainer*>(self), other);
}

PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice) {
  if (UpdateChildMessages(self) < 0) {
    return NULL;
  }
  // Just forward the call to the subscript-handling function of the
  // list containing the child messages.
  return PyObject_GetItem(self->child_messages, slice);
}

static PyObject* SubscriptMethod(PyObject* self, PyObject* slice) {
  return Subscript(reinterpret_cast<RepeatedCompositeContainer*>(self), slice);
}

int AssignSubscript(RepeatedCompositeContainer* self,
                    PyObject* slice,
                    PyObject* value) {
  if (UpdateChildMessages(self) < 0) {
    return -1;
  }
  if (value != NULL) {
    PyErr_SetString(PyExc_TypeError, "does not support assignment");
    return -1;
  }

  // Delete from the underlying Message, if any.
  if (self->message != nullptr) {
    if (cmessage::InternalDeleteRepeatedField(self->message,
                                              self->parent_field_descriptor,
                                              slice,
                                              self->child_messages) < 0) {
      return -1;
    }
  } else {
    Py_ssize_t from;
    Py_ssize_t to;
    Py_ssize_t step;
    Py_ssize_t length = Length(reinterpret_cast<PyObject*>(self));
    Py_ssize_t slicelength;
    if (PySlice_Check(slice)) {
#if PY_MAJOR_VERSION >= 3
      if (PySlice_GetIndicesEx(slice,
                               length, &from, &to, &step, &slicelength) == -1) {
#else
      if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
                               length, &from, &to, &step, &slicelength) == -1) {
#endif
        return -1;
      }
      return PySequence_DelSlice(self->child_messages, from, to);
    } else if (PyInt_Check(slice) || PyLong_Check(slice)) {
      from = to = PyLong_AsLong(slice);
      if (from < 0) {
        from = to = length + from;
      }
      return PySequence_DelItem(self->child_messages, from);
    }
  }

  return 0;
}

static int AssignSubscriptMethod(PyObject* self, PyObject* slice,
                                 PyObject* value) {
  return AssignSubscript(reinterpret_cast<RepeatedCompositeContainer*>(self),
                         slice, value);
}

static PyObject* Remove(PyObject* pself, PyObject* value) {
  RepeatedCompositeContainer* self =
      reinterpret_cast<RepeatedCompositeContainer*>(pself);

  if (UpdateChildMessages(self) < 0) {
    return NULL;
  }
  Py_ssize_t index = PySequence_Index(self->child_messages, value);
  if (index == -1) {
    return NULL;
  }
  ScopedPyObjectPtr py_index(PyLong_FromLong(index));
  if (AssignSubscript(self, py_index.get(), NULL) < 0) {
    return NULL;
  }
  Py_RETURN_NONE;
}

static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) {
  RepeatedCompositeContainer* self =
      reinterpret_cast<RepeatedCompositeContainer*>(pself);

  if (UpdateChildMessages(self) < 0) {
    return NULL;
  }
  if (!PyObject_TypeCheck(other, &RepeatedCompositeContainer_Type)) {
    PyErr_SetString(PyExc_TypeError,
                    "Can only compare repeated composite fields "
                    "against other repeated composite fields.");
    return NULL;
  }
  if (opid == Py_EQ || opid == Py_NE) {
    // TODO(anuraag): Don't make new lists just for this...
    ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
    if (full_slice == NULL) {
      return NULL;
    }
    ScopedPyObjectPtr list(Subscript(self, full_slice.get()));
    if (list == NULL) {
      return NULL;
    }
    ScopedPyObjectPtr other_list(
        Subscript(reinterpret_cast<RepeatedCompositeContainer*>(other),
                  full_slice.get()));
    if (other_list == NULL) {
      return NULL;
    }
    return PyObject_RichCompare(list.get(), other_list.get(), opid);
  } else {
    Py_INCREF(Py_NotImplemented);
    return Py_NotImplemented;
  }
}

static PyObject* ToStr(PyObject* pself) {
  ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
  if (full_slice == NULL) {
    return NULL;
  }
  ScopedPyObjectPtr list(Subscript(
      reinterpret_cast<RepeatedCompositeContainer*>(pself), full_slice.get()));
  if (list == NULL) {
    return NULL;
  }
  return PyObject_Repr(list.get());
}

// ---------------------------------------------------------------------
// sort()

static void ReorderAttached(RepeatedCompositeContainer* self) {
  Message* message = self->message;
  const Reflection* reflection = message->GetReflection();
  const FieldDescriptor* descriptor = self->parent_field_descriptor;
  const Py_ssize_t length = Length(reinterpret_cast<PyObject*>(self));

  // Since Python protobuf objects are never arena-allocated, adding and
  // removing message pointers to the underlying array is just updating
  // pointers.
  for (Py_ssize_t i = 0; i < length; ++i)
    reflection->ReleaseLast(message, descriptor);

  for (Py_ssize_t i = 0; i < length; ++i) {
    CMessage* py_cmsg = reinterpret_cast<CMessage*>(
        PyList_GET_ITEM(self->child_messages, i));
    reflection->AddAllocatedMessage(message, descriptor, py_cmsg->message);
  }
}

// Returns 0 if successful; returns -1 and sets an exception if
// unsuccessful.
static int SortPythonMessages(RepeatedCompositeContainer* self,
                               PyObject* args,
                               PyObject* kwds) {
  ScopedPyObjectPtr m(PyObject_GetAttrString(self->child_messages, "sort"));
  if (m == NULL)
    return -1;
  if (ScopedPyObjectPtr(PyObject_Call(m.get(), args, kwds)) == NULL)
    return -1;
  if (self->message != NULL) {
    ReorderAttached(self);
  }
  return 0;
}

static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) {
  RepeatedCompositeContainer* self =
      reinterpret_cast<RepeatedCompositeContainer*>(pself);

  // Support the old sort_function argument for backwards
  // compatibility.
  if (kwds != NULL) {
    PyObject* sort_func = PyDict_GetItemString(kwds, "sort_function");
    if (sort_func != NULL) {
      // Must set before deleting as sort_func is a borrowed reference
      // and kwds might be the only thing keeping it alive.
      PyDict_SetItemString(kwds, "cmp", sort_func);
      PyDict_DelItemString(kwds, "sort_function");
    }
  }

  if (UpdateChildMessages(self) < 0) {
    return NULL;
  }
  if (SortPythonMessages(self, args, kwds) < 0) {
    return NULL;
  }
  Py_RETURN_NONE;
}

// ---------------------------------------------------------------------

static PyObject* Item(PyObject* pself, Py_ssize_t index) {
  RepeatedCompositeContainer* self =
      reinterpret_cast<RepeatedCompositeContainer*>(pself);

  if (UpdateChildMessages(self) < 0) {
    return NULL;
  }
  Py_ssize_t length = Length(pself);
  if (index < 0) {
    index = length + index;
  }
  PyObject* item = PyList_GetItem(self->child_messages, index);
  if (item == NULL) {
    return NULL;
  }
  Py_INCREF(item);
  return item;
}

static PyObject* Pop(PyObject* pself, PyObject* args) {
  RepeatedCompositeContainer* self =
      reinterpret_cast<RepeatedCompositeContainer*>(pself);

  Py_ssize_t index = -1;
  if (!PyArg_ParseTuple(args, "|n", &index)) {
    return NULL;
  }
  PyObject* item = Item(pself, index);
  if (item == NULL) {
    PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index);
    return NULL;
  }
  ScopedPyObjectPtr py_index(PyLong_FromSsize_t(index));
  if (AssignSubscript(self, py_index.get(), NULL) < 0) {
    return NULL;
  }
  return item;
}

// Release field of parent message and transfer the ownership to target.
void ReleaseLastTo(Message* message,
                   const FieldDescriptor* field,
                   CMessage* target) {
  GOOGLE_CHECK(message != nullptr);
  GOOGLE_CHECK(field != nullptr);
  GOOGLE_CHECK(target != nullptr);

  CMessage::OwnerRef released_message(
      message->GetReflection()->ReleaseLast(message, field));
  // TODO(tibell): Deal with proto1.

  target->parent = NULL;
  target->parent_field_descriptor = NULL;
  target->message = released_message.get();
  target->read_only = false;
  cmessage::SetOwner(target, released_message);
}

// Called to release a container using
// ClearField('container_field_name') on the parent.
int Release(RepeatedCompositeContainer* self) {
  if (UpdateChildMessages(self) < 0) {
    PyErr_WriteUnraisable(PyBytes_FromString("Failed to update released "
                                             "messages"));
    return -1;
  }

  Message* message = self->message;
  const FieldDescriptor* field = self->parent_field_descriptor;

  // The reflection API only lets us release the last message in a
  // repeated field.  Therefore we iterate through the children
  // starting with the last one.
  const Py_ssize_t size = PyList_GET_SIZE(self->child_messages);
  GOOGLE_DCHECK_EQ(size, message->GetReflection()->FieldSize(*message, field));
  for (Py_ssize_t i = size - 1; i >= 0; --i) {
    CMessage* child_cmessage = reinterpret_cast<CMessage*>(
        PyList_GET_ITEM(self->child_messages, i));
    ReleaseLastTo(message, field, child_cmessage);
  }

  // Detach from containing message.
  self->parent = NULL;
  self->parent_field_descriptor = NULL;
  self->message = NULL;
  self->owner.reset();

  return 0;
}

PyObject* DeepCopy(PyObject* pself, PyObject* arg) {
  RepeatedCompositeContainer* self =
      reinterpret_cast<RepeatedCompositeContainer*>(pself);

  ScopedPyObjectPtr cloneObj(
      PyType_GenericAlloc(&RepeatedCompositeContainer_Type, 0));
  if (cloneObj == NULL) {
    return NULL;
  }
  RepeatedCompositeContainer* clone =
      reinterpret_cast<RepeatedCompositeContainer*>(cloneObj.get());

  Message* new_message = self->message->New();
  clone->parent = NULL;
  clone->parent_field_descriptor = self->parent_field_descriptor;
  clone->message = new_message;
  clone->owner.reset(new_message);
  Py_INCREF(self->child_message_class);
  clone->child_message_class = self->child_message_class;
  clone->child_messages = PyList_New(0);

  new_message->GetReflection()
      ->GetMutableRepeatedFieldRef<Message>(new_message,
                                            self->parent_field_descriptor)
      .MergeFrom(self->message->GetReflection()->GetRepeatedFieldRef<Message>(
          *self->message, self->parent_field_descriptor));
  return cloneObj.release();
}

int SetOwner(RepeatedCompositeContainer* self,
             const CMessage::OwnerRef& new_owner) {
  GOOGLE_CHECK_ATTACHED(self);

  self->owner = new_owner;
  const Py_ssize_t n = PyList_GET_SIZE(self->child_messages);
  for (Py_ssize_t i = 0; i < n; ++i) {
    PyObject* msg = PyList_GET_ITEM(self->child_messages, i);
    if (cmessage::SetOwner(reinterpret_cast<CMessage*>(msg), new_owner) == -1) {
      return -1;
    }
  }
  return 0;
}

// The private constructor of RepeatedCompositeContainer objects.
PyObject *NewContainer(
    CMessage* parent,
    const FieldDescriptor* parent_field_descriptor,
    CMessageClass* concrete_class) {
  if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) {
    return NULL;
  }

  RepeatedCompositeContainer* self =
      reinterpret_cast<RepeatedCompositeContainer*>(
          PyType_GenericAlloc(&RepeatedCompositeContainer_Type, 0));
  if (self == NULL) {
    return NULL;
  }

  self->message = parent->message;
  self->parent = parent;
  self->parent_field_descriptor = parent_field_descriptor;
  self->owner = parent->owner;
  Py_INCREF(concrete_class);
  self->child_message_class = concrete_class;
  self->child_messages = PyList_New(0);

  return reinterpret_cast<PyObject*>(self);
}

static void Dealloc(PyObject* pself) {
  RepeatedCompositeContainer* self =
      reinterpret_cast<RepeatedCompositeContainer*>(pself);

  Py_CLEAR(self->child_messages);
  Py_CLEAR(self->child_message_class);
  // TODO(tibell): Do we need to call delete on these objects to make
  // sure their destructors are called?
  self->owner.reset();

  Py_TYPE(self)->tp_free(pself);
}

static PySequenceMethods SqMethods = {
  Length,                 /* sq_length */
  0,                      /* sq_concat */
  0,                      /* sq_repeat */
  Item                    /* sq_item */
};

static PyMappingMethods MpMethods = {
  Length,                 /* mp_length */
  SubscriptMethod,        /* mp_subscript */
  AssignSubscriptMethod,  /* mp_ass_subscript */
};

static PyMethodDef Methods[] = {
  { "__deepcopy__", DeepCopy, METH_VARARGS,
    "Makes a deep copy of the class." },
  { "add", (PyCFunction)AddMethod, METH_VARARGS | METH_KEYWORDS,
    "Adds an object to the repeated container." },
  { "append", AppendMethod, METH_O,
    "Appends a message to the end of the repeated container."},
  { "insert", Insert, METH_VARARGS,
    "Inserts a message before the specified index." },
  { "extend", ExtendMethod, METH_O,
    "Adds objects to the repeated container." },
  { "pop", Pop, METH_VARARGS,
    "Removes an object from the repeated container and returns it." },
  { "remove", Remove, METH_O,
    "Removes an object from the repeated container." },
  { "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS,
    "Sorts the repeated container." },
  { "MergeFrom", MergeFromMethod, METH_O,
    "Adds objects to the repeated container." },
  { NULL, NULL }
};

}  // namespace repeated_composite_container

PyTypeObject RepeatedCompositeContainer_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".RepeatedCompositeContainer",  // tp_name
  sizeof(RepeatedCompositeContainer),  // tp_basicsize
  0,                                   //  tp_itemsize
  repeated_composite_container::Dealloc,  //  tp_dealloc
  0,                                   //  tp_print
  0,                                   //  tp_getattr
  0,                                   //  tp_setattr
  0,                                   //  tp_compare
  repeated_composite_container::ToStr,      //  tp_repr
  0,                                   //  tp_as_number
  &repeated_composite_container::SqMethods,   //  tp_as_sequence
  &repeated_composite_container::MpMethods,   //  tp_as_mapping
  PyObject_HashNotImplemented,         //  tp_hash
  0,                                   //  tp_call
  0,                                   //  tp_str
  0,                                   //  tp_getattro
  0,                                   //  tp_setattro
  0,                                   //  tp_as_buffer
  Py_TPFLAGS_DEFAULT,                  //  tp_flags
  "A Repeated scalar container",       //  tp_doc
  0,                                   //  tp_traverse
  0,                                   //  tp_clear
  repeated_composite_container::RichCompare,  //  tp_richcompare
  0,                                   //  tp_weaklistoffset
  0,                                   //  tp_iter
  0,                                   //  tp_iternext
  repeated_composite_container::Methods,   //  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
};

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