// 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: petar@google.com (Petar Petrov)

#include <Python.h>
#include <frameobject.h>
#include <string>

#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/pyext/descriptor.h>
#include <google/protobuf/pyext/descriptor_containers.h>
#include <google/protobuf/pyext/descriptor_pool.h>
#include <google/protobuf/pyext/message.h>
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>

#if PY_MAJOR_VERSION >= 3
  #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
  #define PyString_Check PyUnicode_Check
  #define PyString_InternFromString PyUnicode_InternFromString
  #define PyInt_FromLong PyLong_FromLong
  #define PyInt_FromSize_t PyLong_FromSize_t
  #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 {

// Store interned descriptors, so that the same C++ descriptor yields the same
// Python object. Objects are not immortal: this map does not own the
// references, and items are deleted when the last reference to the object is
// released.
// This is enough to support the "is" operator on live objects.
// All descriptors are stored here.
hash_map<const void*, PyObject*> interned_descriptors;

PyObject* PyString_FromCppString(const string& str) {
  return PyString_FromStringAndSize(str.c_str(), str.size());
}

// Check that the calling Python code is the global scope of a _pb2.py module.
// This function is used to support the current code generated by the proto
// compiler, which creates descriptors, then update some properties.
// For example:
//   message_descriptor = Descriptor(
//       name='Message',
//       fields = [FieldDescriptor(name='field')]
//   message_descriptor.fields[0].containing_type = message_descriptor
//
// This code is still executed, but the descriptors now have no other storage
// than the (const) C++ pointer, and are immutable.
// So we let this code pass, by simply ignoring the new value.
//
// From user code, descriptors still look immutable.
//
// TODO(amauryfa): Change the proto2 compiler to remove the assignments, and
// remove this hack.
bool _CalledFromGeneratedFile(int stacklevel) {
  PyThreadState *state = PyThreadState_GET();
  if (state == NULL) {
    return false;
  }
  PyFrameObject* frame = state->frame;
  if (frame == NULL) {
    return false;
  }
  while (stacklevel-- > 0) {
    frame = frame->f_back;
    if (frame == NULL) {
      return false;
    }
  }
  if (frame->f_globals != frame->f_locals) {
    // Not at global module scope
    return false;
  }

  if (frame->f_code->co_filename == NULL) {
    return false;
  }
  char* filename;
  Py_ssize_t filename_size;
  if (PyString_AsStringAndSize(frame->f_code->co_filename,
                               &filename, &filename_size) < 0) {
    // filename is not a string.
    PyErr_Clear();
    return false;
  }
  if (filename_size < 7) {
    // filename is too short.
    return false;
  }
  if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) {
    // Filename is not ending with _pb2.
    return false;
  }
  return true;
}

// If the calling code is not a _pb2.py file, raise AttributeError.
// To be used in attribute setters.
static int CheckCalledFromGeneratedFile(const char* attr_name) {
  if (_CalledFromGeneratedFile(0)) {
    return 0;
  }
  PyErr_Format(PyExc_AttributeError,
               "attribute is not writable: %s", attr_name);
  return -1;
}


#ifndef PyVarObject_HEAD_INIT
#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
#endif
#ifndef Py_TYPE
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#endif


// Helper functions for descriptor objects.

// A set of templates to retrieve the C++ FileDescriptor of any descriptor.
template<class DescriptorClass>
const FileDescriptor* GetFileDescriptor(const DescriptorClass* descriptor) {
  return descriptor->file();
}
template<>
const FileDescriptor* GetFileDescriptor(const FileDescriptor* descriptor) {
  return descriptor;
}
template<>
const FileDescriptor* GetFileDescriptor(const EnumValueDescriptor* descriptor) {
  return descriptor->type()->file();
}
template<>
const FileDescriptor* GetFileDescriptor(const OneofDescriptor* descriptor) {
  return descriptor->containing_type()->file();
}

// Converts options into a Python protobuf, and cache the result.
//
// This is a bit tricky because options can contain extension fields defined in
// the same proto file. In this case the options parsed from the serialized_pb
// have unkown fields, and we need to parse them again.
//
// Always returns a new reference.
template<class DescriptorClass>
static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) {
  // Options (and their extensions) are completely resolved in the proto file
  // containing the descriptor.
  PyDescriptorPool* pool = GetDescriptorPool_FromPool(
      GetFileDescriptor(descriptor)->pool());

  hash_map<const void*, PyObject*>* descriptor_options =
      pool->descriptor_options;
  // First search in the cache.
  if (descriptor_options->find(descriptor) != descriptor_options->end()) {
    PyObject *value = (*descriptor_options)[descriptor];
    Py_INCREF(value);
    return value;
  }

  // Build the Options object: get its Python class, and make a copy of the C++
  // read-only instance.
  const Message& options(descriptor->options());
  const Descriptor *message_type = options.GetDescriptor();
  PyObject* message_class(cdescriptor_pool::GetMessageClass(
      pool, message_type));
  if (message_class == NULL) {
    // The Options message was not found in the current DescriptorPool.
    // In this case, there cannot be extensions to these options, and we can
    // try to use the basic pool instead.
    PyErr_Clear();
    message_class = cdescriptor_pool::GetMessageClass(
      GetDefaultDescriptorPool(), message_type);
  }
  if (message_class == NULL) {
    PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s",
                 message_type->full_name().c_str());
    return NULL;
  }
  ScopedPyObjectPtr value(PyEval_CallObject(message_class, NULL));
  if (value == NULL) {
    return NULL;
  }
  if (!PyObject_TypeCheck(value.get(), &CMessage_Type)) {
      PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s",
                   message_type->full_name().c_str(),
                   Py_TYPE(value.get())->tp_name);
      return NULL;
  }
  CMessage* cmsg = reinterpret_cast<CMessage*>(value.get());

  const Reflection* reflection = options.GetReflection();
  const UnknownFieldSet& unknown_fields(reflection->GetUnknownFields(options));
  if (unknown_fields.empty()) {
    cmsg->message->CopyFrom(options);
  } else {
    // Reparse options string!  XXX call cmessage::MergeFromString
    string serialized;
    options.SerializeToString(&serialized);
    io::CodedInputStream input(
        reinterpret_cast<const uint8*>(serialized.c_str()), serialized.size());
    input.SetExtensionRegistry(pool->pool, pool->message_factory);
    bool success = cmsg->message->MergePartialFromCodedStream(&input);
    if (!success) {
      PyErr_Format(PyExc_ValueError, "Error parsing Options message");
      return NULL;
    }
  }

  // Cache the result.
  Py_INCREF(value.get());
  (*pool->descriptor_options)[descriptor] = value.get();

  return value.release();
}

// Copy the C++ descriptor to a Python message.
// The Python message is an instance of descriptor_pb2.DescriptorProto
// or similar.
template<class DescriptorProtoClass, class DescriptorClass>
static PyObject* CopyToPythonProto(const DescriptorClass *descriptor,
                                   PyObject *target) {
  const Descriptor* self_descriptor =
      DescriptorProtoClass::default_instance().GetDescriptor();
  CMessage* message = reinterpret_cast<CMessage*>(target);
  if (!PyObject_TypeCheck(target, &CMessage_Type) ||
      message->message->GetDescriptor() != self_descriptor) {
    PyErr_Format(PyExc_TypeError, "Not a %s message",
                 self_descriptor->full_name().c_str());
    return NULL;
  }
  cmessage::AssureWritable(message);
  DescriptorProtoClass* descriptor_message =
      static_cast<DescriptorProtoClass*>(message->message);
  descriptor->CopyTo(descriptor_message);
  Py_RETURN_NONE;
}

// All Descriptors classes share the same memory layout.
typedef struct PyBaseDescriptor {
  PyObject_HEAD

  // Pointer to the C++ proto2 descriptor.
  // Like all descriptors, it is owned by the global DescriptorPool.
  const void* descriptor;

  // Owned reference to the DescriptorPool, to ensure it is kept alive.
  PyDescriptorPool* pool;
} PyBaseDescriptor;


// FileDescriptor structure "inherits" from the base descriptor.
typedef struct PyFileDescriptor {
  PyBaseDescriptor base;

  // The cached version of serialized pb. Either NULL, or a Bytes string.
  // We own the reference.
  PyObject *serialized_pb;
} PyFileDescriptor;


namespace descriptor {

// Creates or retrieve a Python descriptor of the specified type.
// Objects are interned: the same descriptor will return the same object if it
// was kept alive.
// 'was_created' is an optional pointer to a bool, and is set to true if a new
// object was allocated.
// Always return a new reference.
template<class DescriptorClass>
PyObject* NewInternedDescriptor(PyTypeObject* type,
                                const DescriptorClass* descriptor,
                                bool* was_created) {
  if (was_created) {
    *was_created = false;
  }
  if (descriptor == NULL) {
    PyErr_BadInternalCall();
    return NULL;
  }

  // See if the object is in the map of interned descriptors
  hash_map<const void*, PyObject*>::iterator it =
      interned_descriptors.find(descriptor);
  if (it != interned_descriptors.end()) {
    GOOGLE_DCHECK(Py_TYPE(it->second) == type);
    Py_INCREF(it->second);
    return it->second;
  }
  // Create a new descriptor object
  PyBaseDescriptor* py_descriptor = PyObject_New(
      PyBaseDescriptor, type);
  if (py_descriptor == NULL) {
    return NULL;
  }
  py_descriptor->descriptor = descriptor;

  // and cache it.
  interned_descriptors.insert(
      std::make_pair(descriptor, reinterpret_cast<PyObject*>(py_descriptor)));

  // Ensures that the DescriptorPool stays alive.
  PyDescriptorPool* pool = GetDescriptorPool_FromPool(
      GetFileDescriptor(descriptor)->pool());
  if (pool == NULL) {
    // Don't DECREF, the object is not fully initialized.
    PyObject_Del(py_descriptor);
    return NULL;
  }
  Py_INCREF(pool);
  py_descriptor->pool = pool;

  if (was_created) {
    *was_created = true;
  }
  return reinterpret_cast<PyObject*>(py_descriptor);
}

static void Dealloc(PyBaseDescriptor* self) {
  // Remove from interned dictionary
  interned_descriptors.erase(self->descriptor);
  Py_CLEAR(self->pool);
  Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
}

static PyGetSetDef Getters[] = {
  {NULL}
};

PyTypeObject PyBaseDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".DescriptorBase",   // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  (destructor)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
  "Descriptors base class",             // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  0,                                    // tp_methods
  0,                                    // tp_members
  Getters,                              // tp_getset
};

}  // namespace descriptor

const void* PyDescriptor_AsVoidPtr(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &descriptor::PyBaseDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a BaseDescriptor");
    return NULL;
  }
  return reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor;
}

namespace message_descriptor {

// Unchecked accessor to the C++ pointer.
static const Descriptor* _GetDescriptor(PyBaseDescriptor* self) {
  return reinterpret_cast<const Descriptor*>(self->descriptor);
}

static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->full_name());
}

static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
  return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
}

static PyObject* GetConcreteClass(PyBaseDescriptor* self, void *closure) {
  // Retuns the canonical class for the given descriptor.
  // This is the class that was registered with the primary descriptor pool
  // which contains this descriptor.
  // This might not be the one you expect! For example the returned object does
  // not know about extensions defined in a custom pool.
  PyObject* concrete_class(cdescriptor_pool::GetMessageClass(
      GetDescriptorPool_FromPool(_GetDescriptor(self)->file()->pool()),
      _GetDescriptor(self)));
  Py_XINCREF(concrete_class);
  return concrete_class;
}

static PyObject* GetFieldsByName(PyBaseDescriptor* self, void *closure) {
  return NewMessageFieldsByName(_GetDescriptor(self));
}

static PyObject* GetFieldsByCamelcaseName(PyBaseDescriptor* self,
                                          void *closure) {
  return NewMessageFieldsByCamelcaseName(_GetDescriptor(self));
}

static PyObject* GetFieldsByNumber(PyBaseDescriptor* self, void *closure) {
  return NewMessageFieldsByNumber(_GetDescriptor(self));
}

static PyObject* GetFieldsSeq(PyBaseDescriptor* self, void *closure) {
  return NewMessageFieldsSeq(_GetDescriptor(self));
}

static PyObject* GetNestedTypesByName(PyBaseDescriptor* self, void *closure) {
  return NewMessageNestedTypesByName(_GetDescriptor(self));
}

static PyObject* GetNestedTypesSeq(PyBaseDescriptor* self, void *closure) {
  return NewMessageNestedTypesSeq(_GetDescriptor(self));
}

static PyObject* GetExtensionsByName(PyBaseDescriptor* self, void *closure) {
  return NewMessageExtensionsByName(_GetDescriptor(self));
}

static PyObject* GetExtensions(PyBaseDescriptor* self, void *closure) {
  return NewMessageExtensionsSeq(_GetDescriptor(self));
}

static PyObject* GetEnumsSeq(PyBaseDescriptor* self, void *closure) {
  return NewMessageEnumsSeq(_GetDescriptor(self));
}

static PyObject* GetEnumTypesByName(PyBaseDescriptor* self, void *closure) {
  return NewMessageEnumsByName(_GetDescriptor(self));
}

static PyObject* GetEnumValuesByName(PyBaseDescriptor* self, void *closure) {
  return NewMessageEnumValuesByName(_GetDescriptor(self));
}

static PyObject* GetOneofsByName(PyBaseDescriptor* self, void *closure) {
  return NewMessageOneofsByName(_GetDescriptor(self));
}

static PyObject* GetOneofsSeq(PyBaseDescriptor* self, void *closure) {
  return NewMessageOneofsSeq(_GetDescriptor(self));
}

static PyObject* IsExtendable(PyBaseDescriptor *self, void *closure) {
  if (_GetDescriptor(self)->extension_range_count() > 0) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}

static PyObject* GetExtensionRanges(PyBaseDescriptor *self, void *closure) {
  const Descriptor* descriptor = _GetDescriptor(self);
  PyObject* range_list = PyList_New(descriptor->extension_range_count());

  for (int i = 0; i < descriptor->extension_range_count(); i++) {
    const Descriptor::ExtensionRange* range = descriptor->extension_range(i);
    PyObject* start = PyInt_FromLong(range->start);
    PyObject* end = PyInt_FromLong(range->end);
    PyList_SetItem(range_list, i, PyTuple_Pack(2, start, end));
  }

  return range_list;
}

static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
  const Descriptor* containing_type =
      _GetDescriptor(self)->containing_type();
  if (containing_type) {
    return PyMessageDescriptor_FromDescriptor(containing_type);
  } else {
    Py_RETURN_NONE;
  }
}

static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
                             void *closure) {
  return CheckCalledFromGeneratedFile("containing_type");
}

static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
  const MessageOptions& options(_GetDescriptor(self)->options());
  if (&options != &MessageOptions::default_instance()) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}
static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
                             void *closure) {
  return CheckCalledFromGeneratedFile("has_options");
}

static PyObject* GetOptions(PyBaseDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static int SetOptions(PyBaseDescriptor *self, PyObject *value,
                      void *closure) {
  return CheckCalledFromGeneratedFile("_options");
}

static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
  return CopyToPythonProto<DescriptorProto>(_GetDescriptor(self), target);
}

static PyObject* EnumValueName(PyBaseDescriptor *self, PyObject *args) {
  const char *enum_name;
  int number;
  if (!PyArg_ParseTuple(args, "si", &enum_name, &number))
    return NULL;
  const EnumDescriptor *enum_type =
      _GetDescriptor(self)->FindEnumTypeByName(enum_name);
  if (enum_type == NULL) {
    PyErr_SetString(PyExc_KeyError, enum_name);
    return NULL;
  }
  const EnumValueDescriptor *enum_value =
      enum_type->FindValueByNumber(number);
  if (enum_value == NULL) {
    PyErr_Format(PyExc_KeyError, "%d", number);
    return NULL;
  }
  return PyString_FromCppString(enum_value->name());
}

static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) {
  return PyString_InternFromString(
      FileDescriptor::SyntaxName(_GetDescriptor(self)->file()->syntax()));
}

static PyGetSetDef Getters[] = {
  { "name", (getter)GetName, NULL, "Last name"},
  { "full_name", (getter)GetFullName, NULL, "Full name"},
  { "_concrete_class", (getter)GetConcreteClass, NULL, "concrete class"},
  { "file", (getter)GetFile, NULL, "File descriptor"},

  { "fields", (getter)GetFieldsSeq, NULL, "Fields sequence"},
  { "fields_by_name", (getter)GetFieldsByName, NULL, "Fields by name"},
  { "fields_by_camelcase_name", (getter)GetFieldsByCamelcaseName, NULL,
    "Fields by camelCase name"},
  { "fields_by_number", (getter)GetFieldsByNumber, NULL, "Fields by number"},
  { "nested_types", (getter)GetNestedTypesSeq, NULL, "Nested types sequence"},
  { "nested_types_by_name", (getter)GetNestedTypesByName, NULL,
    "Nested types by name"},
  { "extensions", (getter)GetExtensions, NULL, "Extensions Sequence"},
  { "extensions_by_name", (getter)GetExtensionsByName, NULL,
    "Extensions by name"},
  { "extension_ranges", (getter)GetExtensionRanges, NULL, "Extension ranges"},
  { "enum_types", (getter)GetEnumsSeq, NULL, "Enum sequence"},
  { "enum_types_by_name", (getter)GetEnumTypesByName, NULL,
    "Enum types by name"},
  { "enum_values_by_name", (getter)GetEnumValuesByName, NULL,
    "Enum values by name"},
  { "oneofs_by_name", (getter)GetOneofsByName, NULL, "Oneofs by name"},
  { "oneofs", (getter)GetOneofsSeq, NULL, "Oneofs by name"},
  { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
    "Containing type"},
  { "is_extendable", (getter)IsExtendable, (setter)NULL},
  { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
  { "_options", (getter)NULL, (setter)SetOptions, "Options"},
  { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"},
  {NULL}
};

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
  { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
  { "EnumValueName", (PyCFunction)EnumValueName, METH_VARARGS, },
  {NULL}
};

}  // namespace message_descriptor

PyTypeObject PyMessageDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".MessageDescriptor",  // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // 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
  "A Message Descriptor",               // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  message_descriptor::Methods,          // tp_methods
  0,                                    // tp_members
  message_descriptor::Getters,          // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // tp_base
};

PyObject* PyMessageDescriptor_FromDescriptor(
    const Descriptor* message_descriptor) {
  return descriptor::NewInternedDescriptor(
      &PyMessageDescriptor_Type, message_descriptor, NULL);
}

const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyMessageDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a MessageDescriptor");
    return NULL;
  }
  return reinterpret_cast<const Descriptor*>(
      reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
}

namespace field_descriptor {

// Unchecked accessor to the C++ pointer.
static const FieldDescriptor* _GetDescriptor(
    PyBaseDescriptor *self) {
  return reinterpret_cast<const FieldDescriptor*>(self->descriptor);
}

static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->full_name());
}

static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetCamelcaseName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->camelcase_name());
}

static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->type());
}

static PyObject* GetCppType(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->cpp_type());
}

static PyObject* GetLabel(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->label());
}

static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->number());
}

static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->index());
}

static PyObject* GetID(PyBaseDescriptor *self, void *closure) {
  return PyLong_FromVoidPtr(self);
}

static PyObject* IsExtension(PyBaseDescriptor *self, void *closure) {
  return PyBool_FromLong(_GetDescriptor(self)->is_extension());
}

static PyObject* HasDefaultValue(PyBaseDescriptor *self, void *closure) {
  return PyBool_FromLong(_GetDescriptor(self)->has_default_value());
}

static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) {
  PyObject *result;

  switch (_GetDescriptor(self)->cpp_type()) {
    case FieldDescriptor::CPPTYPE_INT32: {
      int32 value = _GetDescriptor(self)->default_value_int32();
      result = PyInt_FromLong(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_INT64: {
      int64 value = _GetDescriptor(self)->default_value_int64();
      result = PyLong_FromLongLong(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_UINT32: {
      uint32 value = _GetDescriptor(self)->default_value_uint32();
      result = PyInt_FromSize_t(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_UINT64: {
      uint64 value = _GetDescriptor(self)->default_value_uint64();
      result = PyLong_FromUnsignedLongLong(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_FLOAT: {
      float value = _GetDescriptor(self)->default_value_float();
      result = PyFloat_FromDouble(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_DOUBLE: {
      double value = _GetDescriptor(self)->default_value_double();
      result = PyFloat_FromDouble(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_BOOL: {
      bool value = _GetDescriptor(self)->default_value_bool();
      result = PyBool_FromLong(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_STRING: {
      string value = _GetDescriptor(self)->default_value_string();
      result = ToStringObject(_GetDescriptor(self), value);
      break;
    }
    case FieldDescriptor::CPPTYPE_ENUM: {
      const EnumValueDescriptor* value =
          _GetDescriptor(self)->default_value_enum();
      result = PyInt_FromLong(value->number());
      break;
    }
    default:
      PyErr_Format(PyExc_NotImplementedError, "default value for %s",
                   _GetDescriptor(self)->full_name().c_str());
      return NULL;
  }
  return result;
}

static PyObject* GetCDescriptor(PyObject *self, void *closure) {
  Py_INCREF(self);
  return self;
}

static PyObject *GetEnumType(PyBaseDescriptor *self, void *closure) {
  const EnumDescriptor* enum_type = _GetDescriptor(self)->enum_type();
  if (enum_type) {
    return PyEnumDescriptor_FromDescriptor(enum_type);
  } else {
    Py_RETURN_NONE;
  }
}

static int SetEnumType(PyBaseDescriptor *self, PyObject *value, void *closure) {
  return CheckCalledFromGeneratedFile("enum_type");
}

static PyObject *GetMessageType(PyBaseDescriptor *self, void *closure) {
  const Descriptor* message_type = _GetDescriptor(self)->message_type();
  if (message_type) {
    return PyMessageDescriptor_FromDescriptor(message_type);
  } else {
    Py_RETURN_NONE;
  }
}

static int SetMessageType(PyBaseDescriptor *self, PyObject *value,
                          void *closure) {
  return CheckCalledFromGeneratedFile("message_type");
}

static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
  const Descriptor* containing_type =
      _GetDescriptor(self)->containing_type();
  if (containing_type) {
    return PyMessageDescriptor_FromDescriptor(containing_type);
  } else {
    Py_RETURN_NONE;
  }
}

static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
                             void *closure) {
  return CheckCalledFromGeneratedFile("containing_type");
}

static PyObject* GetExtensionScope(PyBaseDescriptor *self, void *closure) {
  const Descriptor* extension_scope =
      _GetDescriptor(self)->extension_scope();
  if (extension_scope) {
    return PyMessageDescriptor_FromDescriptor(extension_scope);
  } else {
    Py_RETURN_NONE;
  }
}

static PyObject* GetContainingOneof(PyBaseDescriptor *self, void *closure) {
  const OneofDescriptor* containing_oneof =
      _GetDescriptor(self)->containing_oneof();
  if (containing_oneof) {
    return PyOneofDescriptor_FromDescriptor(containing_oneof);
  } else {
    Py_RETURN_NONE;
  }
}

static int SetContainingOneof(PyBaseDescriptor *self, PyObject *value,
                              void *closure) {
  return CheckCalledFromGeneratedFile("containing_oneof");
}

static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
  const FieldOptions& options(_GetDescriptor(self)->options());
  if (&options != &FieldOptions::default_instance()) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}
static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
                         void *closure) {
  return CheckCalledFromGeneratedFile("has_options");
}

static PyObject* GetOptions(PyBaseDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static int SetOptions(PyBaseDescriptor *self, PyObject *value,
                      void *closure) {
  return CheckCalledFromGeneratedFile("_options");
}


static PyGetSetDef Getters[] = {
  { "full_name", (getter)GetFullName, NULL, "Full name"},
  { "name", (getter)GetName, NULL, "Unqualified name"},
  { "camelcase_name", (getter)GetCamelcaseName, NULL, "Camelcase name"},
  { "type", (getter)GetType, NULL, "C++ Type"},
  { "cpp_type", (getter)GetCppType, NULL, "C++ Type"},
  { "label", (getter)GetLabel, NULL, "Label"},
  { "number", (getter)GetNumber, NULL, "Number"},
  { "index", (getter)GetIndex, NULL, "Index"},
  { "default_value", (getter)GetDefaultValue, NULL, "Default Value"},
  { "has_default_value", (getter)HasDefaultValue},
  { "is_extension", (getter)IsExtension, NULL, "ID"},
  { "id", (getter)GetID, NULL, "ID"},
  { "_cdescriptor", (getter)GetCDescriptor, NULL, "HAACK REMOVE ME"},

  { "message_type", (getter)GetMessageType, (setter)SetMessageType,
    "Message type"},
  { "enum_type", (getter)GetEnumType, (setter)SetEnumType, "Enum type"},
  { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
    "Containing type"},
  { "extension_scope", (getter)GetExtensionScope, (setter)NULL,
    "Extension scope"},
  { "containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof,
    "Containing oneof"},
  { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
  { "_options", (getter)NULL, (setter)SetOptions, "Options"},
  {NULL}
};

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
  {NULL}
};

}  // namespace field_descriptor

PyTypeObject PyFieldDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".FieldDescriptor",  // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // 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
  "A Field Descriptor",                 // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  field_descriptor::Methods,            // tp_methods
  0,                                    // tp_members
  field_descriptor::Getters,            // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // tp_base
};

PyObject* PyFieldDescriptor_FromDescriptor(
    const FieldDescriptor* field_descriptor) {
  return descriptor::NewInternedDescriptor(
      &PyFieldDescriptor_Type, field_descriptor, NULL);
}

const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyFieldDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a FieldDescriptor");
    return NULL;
  }
  return reinterpret_cast<const FieldDescriptor*>(
      reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
}

namespace enum_descriptor {

// Unchecked accessor to the C++ pointer.
static const EnumDescriptor* _GetDescriptor(
    PyBaseDescriptor *self) {
  return reinterpret_cast<const EnumDescriptor*>(self->descriptor);
}

static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->full_name());
}

static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
  return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
}

static PyObject* GetEnumvaluesByName(PyBaseDescriptor* self, void *closure) {
  return NewEnumValuesByName(_GetDescriptor(self));
}

static PyObject* GetEnumvaluesByNumber(PyBaseDescriptor* self, void *closure) {
  return NewEnumValuesByNumber(_GetDescriptor(self));
}

static PyObject* GetEnumvaluesSeq(PyBaseDescriptor* self, void *closure) {
  return NewEnumValuesSeq(_GetDescriptor(self));
}

static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
  const Descriptor* containing_type =
      _GetDescriptor(self)->containing_type();
  if (containing_type) {
    return PyMessageDescriptor_FromDescriptor(containing_type);
  } else {
    Py_RETURN_NONE;
  }
}

static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
                             void *closure) {
  return CheckCalledFromGeneratedFile("containing_type");
}


static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
  const EnumOptions& options(_GetDescriptor(self)->options());
  if (&options != &EnumOptions::default_instance()) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}
static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
                         void *closure) {
  return CheckCalledFromGeneratedFile("has_options");
}

static PyObject* GetOptions(PyBaseDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static int SetOptions(PyBaseDescriptor *self, PyObject *value,
                      void *closure) {
  return CheckCalledFromGeneratedFile("_options");
}

static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
  return CopyToPythonProto<EnumDescriptorProto>(_GetDescriptor(self), target);
}

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
  { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
  {NULL}
};

static PyGetSetDef Getters[] = {
  { "full_name", (getter)GetFullName, NULL, "Full name"},
  { "name", (getter)GetName, NULL, "last name"},
  { "file", (getter)GetFile, NULL, "File descriptor"},
  { "values", (getter)GetEnumvaluesSeq, NULL, "values"},
  { "values_by_name", (getter)GetEnumvaluesByName, NULL,
    "Enum values by name"},
  { "values_by_number", (getter)GetEnumvaluesByNumber, NULL,
    "Enum values by number"},

  { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
    "Containing type"},
  { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
  { "_options", (getter)NULL, (setter)SetOptions, "Options"},
  {NULL}
};

}  // namespace enum_descriptor

PyTypeObject PyEnumDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".EnumDescriptor",   // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // 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
  "A Enum Descriptor",                  // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  enum_descriptor::Methods,             // tp_getset
  0,                                    // tp_members
  enum_descriptor::Getters,             // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // tp_base
};

PyObject* PyEnumDescriptor_FromDescriptor(
    const EnumDescriptor* enum_descriptor) {
  return descriptor::NewInternedDescriptor(
      &PyEnumDescriptor_Type, enum_descriptor, NULL);
}

const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyEnumDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not an EnumDescriptor");
    return NULL;
  }
  return reinterpret_cast<const EnumDescriptor*>(
      reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
}

namespace enumvalue_descriptor {

// Unchecked accessor to the C++ pointer.
static const EnumValueDescriptor* _GetDescriptor(
    PyBaseDescriptor *self) {
  return reinterpret_cast<const EnumValueDescriptor*>(self->descriptor);
}

static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->number());
}

static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->index());
}

static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
  return PyEnumDescriptor_FromDescriptor(_GetDescriptor(self)->type());
}

static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
  const EnumValueOptions& options(_GetDescriptor(self)->options());
  if (&options != &EnumValueOptions::default_instance()) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}
static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
                         void *closure) {
  return CheckCalledFromGeneratedFile("has_options");
}

static PyObject* GetOptions(PyBaseDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static int SetOptions(PyBaseDescriptor *self, PyObject *value,
                      void *closure) {
  return CheckCalledFromGeneratedFile("_options");
}


static PyGetSetDef Getters[] = {
  { "name", (getter)GetName, NULL, "name"},
  { "number", (getter)GetNumber, NULL, "number"},
  { "index", (getter)GetIndex, NULL, "index"},
  { "type", (getter)GetType, NULL, "index"},

  { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
  { "_options", (getter)NULL, (setter)SetOptions, "Options"},
  {NULL}
};

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
  {NULL}
};

}  // namespace enumvalue_descriptor

PyTypeObject PyEnumValueDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".EnumValueDescriptor",  // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // 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
  "A EnumValue Descriptor",             // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  enumvalue_descriptor::Methods,        // tp_methods
  0,                                    // tp_members
  enumvalue_descriptor::Getters,        // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // tp_base
};

PyObject* PyEnumValueDescriptor_FromDescriptor(
    const EnumValueDescriptor* enumvalue_descriptor) {
  return descriptor::NewInternedDescriptor(
      &PyEnumValueDescriptor_Type, enumvalue_descriptor, NULL);
}

namespace file_descriptor {

// Unchecked accessor to the C++ pointer.
static const FileDescriptor* _GetDescriptor(PyFileDescriptor *self) {
  return reinterpret_cast<const FileDescriptor*>(self->base.descriptor);
}

static void Dealloc(PyFileDescriptor* self) {
  Py_XDECREF(self->serialized_pb);
  descriptor::Dealloc(&self->base);
}

static PyObject* GetPool(PyFileDescriptor *self, void *closure) {
  PyObject* pool = reinterpret_cast<PyObject*>(
      GetDescriptorPool_FromPool(_GetDescriptor(self)->pool()));
  Py_XINCREF(pool);
  return pool;
}

static PyObject* GetName(PyFileDescriptor *self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetPackage(PyFileDescriptor *self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->package());
}

static PyObject* GetSerializedPb(PyFileDescriptor *self, void *closure) {
  PyObject *serialized_pb = self->serialized_pb;
  if (serialized_pb != NULL) {
    Py_INCREF(serialized_pb);
    return serialized_pb;
  }
  FileDescriptorProto file_proto;
  _GetDescriptor(self)->CopyTo(&file_proto);
  string contents;
  file_proto.SerializePartialToString(&contents);
  self->serialized_pb = PyBytes_FromStringAndSize(
      contents.c_str(), contents.size());
  if (self->serialized_pb == NULL) {
    return NULL;
  }
  Py_INCREF(self->serialized_pb);
  return self->serialized_pb;
}

static PyObject* GetMessageTypesByName(PyFileDescriptor* self, void *closure) {
  return NewFileMessageTypesByName(_GetDescriptor(self));
}

static PyObject* GetEnumTypesByName(PyFileDescriptor* self, void *closure) {
  return NewFileEnumTypesByName(_GetDescriptor(self));
}

static PyObject* GetExtensionsByName(PyFileDescriptor* self, void *closure) {
  return NewFileExtensionsByName(_GetDescriptor(self));
}

static PyObject* GetDependencies(PyFileDescriptor* self, void *closure) {
  return NewFileDependencies(_GetDescriptor(self));
}

static PyObject* GetPublicDependencies(PyFileDescriptor* self, void *closure) {
  return NewFilePublicDependencies(_GetDescriptor(self));
}

static PyObject* GetHasOptions(PyFileDescriptor *self, void *closure) {
  const FileOptions& options(_GetDescriptor(self)->options());
  if (&options != &FileOptions::default_instance()) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}
static int SetHasOptions(PyFileDescriptor *self, PyObject *value,
                         void *closure) {
  return CheckCalledFromGeneratedFile("has_options");
}

static PyObject* GetOptions(PyFileDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static int SetOptions(PyFileDescriptor *self, PyObject *value,
                      void *closure) {
  return CheckCalledFromGeneratedFile("_options");
}

static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) {
  return PyString_InternFromString(
      FileDescriptor::SyntaxName(_GetDescriptor(self)->syntax()));
}

static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) {
  return CopyToPythonProto<FileDescriptorProto>(_GetDescriptor(self), target);
}

static PyGetSetDef Getters[] = {
  { "pool", (getter)GetPool, NULL, "pool"},
  { "name", (getter)GetName, NULL, "name"},
  { "package", (getter)GetPackage, NULL, "package"},
  { "serialized_pb", (getter)GetSerializedPb},
  { "message_types_by_name", (getter)GetMessageTypesByName, NULL,
    "Messages by name"},
  { "enum_types_by_name", (getter)GetEnumTypesByName, NULL, "Enums by name"},
  { "extensions_by_name", (getter)GetExtensionsByName, NULL,
    "Extensions by name"},
  { "dependencies", (getter)GetDependencies, NULL, "Dependencies"},
  { "public_dependencies", (getter)GetPublicDependencies, NULL, "Dependencies"},

  { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
  { "_options", (getter)NULL, (setter)SetOptions, "Options"},
  { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"},
  {NULL}
};

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
  { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
  {NULL}
};

}  // namespace file_descriptor

PyTypeObject PyFileDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".FileDescriptor",   // tp_name
  sizeof(PyFileDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  (destructor)file_descriptor::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
  "A File Descriptor",                  // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  file_descriptor::Methods,             // tp_methods
  0,                                    // tp_members
  file_descriptor::Getters,             // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // 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
  PyObject_Del,                         // tp_free
};

PyObject* PyFileDescriptor_FromDescriptor(
    const FileDescriptor* file_descriptor) {
  return PyFileDescriptor_FromDescriptorWithSerializedPb(file_descriptor,
                                                         NULL);
}

PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb(
    const FileDescriptor* file_descriptor, PyObject *serialized_pb) {
  bool was_created;
  PyObject* py_descriptor = descriptor::NewInternedDescriptor(
      &PyFileDescriptor_Type, file_descriptor, &was_created);
  if (py_descriptor == NULL) {
    return NULL;
  }
  if (was_created) {
    PyFileDescriptor* cfile_descriptor =
        reinterpret_cast<PyFileDescriptor*>(py_descriptor);
    Py_XINCREF(serialized_pb);
    cfile_descriptor->serialized_pb = serialized_pb;
  }
  // TODO(amauryfa): In the case of a cached object, check that serialized_pb
  // is the same as before.

  return py_descriptor;
}

const FileDescriptor* PyFileDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyFileDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a FileDescriptor");
    return NULL;
  }
  return reinterpret_cast<const FileDescriptor*>(
      reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
}

namespace oneof_descriptor {

// Unchecked accessor to the C++ pointer.
static const OneofDescriptor* _GetDescriptor(
    PyBaseDescriptor *self) {
  return reinterpret_cast<const OneofDescriptor*>(self->descriptor);
}

static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->full_name());
}

static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->index());
}

static PyObject* GetFields(PyBaseDescriptor* self, void *closure) {
  return NewOneofFieldsSeq(_GetDescriptor(self));
}

static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
  const Descriptor* containing_type =
      _GetDescriptor(self)->containing_type();
  if (containing_type) {
    return PyMessageDescriptor_FromDescriptor(containing_type);
  } else {
    Py_RETURN_NONE;
  }
}

static PyGetSetDef Getters[] = {
  { "name", (getter)GetName, NULL, "Name"},
  { "full_name", (getter)GetFullName, NULL, "Full name"},
  { "index", (getter)GetIndex, NULL, "Index"},

  { "containing_type", (getter)GetContainingType, NULL, "Containing type"},
  { "fields", (getter)GetFields, NULL, "Fields"},
  {NULL}
};

}  // namespace oneof_descriptor

PyTypeObject PyOneofDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".OneofDescriptor",  // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // 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
  "A Oneof Descriptor",                 // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  0,                                    // tp_methods
  0,                                    // tp_members
  oneof_descriptor::Getters,            // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // tp_base
};

PyObject* PyOneofDescriptor_FromDescriptor(
    const OneofDescriptor* oneof_descriptor) {
  return descriptor::NewInternedDescriptor(
      &PyOneofDescriptor_Type, oneof_descriptor, NULL);
}

// Add a enum values to a type dictionary.
static bool AddEnumValues(PyTypeObject *type,
                          const EnumDescriptor* enum_descriptor) {
  for (int i = 0; i < enum_descriptor->value_count(); ++i) {
    const EnumValueDescriptor* value = enum_descriptor->value(i);
    ScopedPyObjectPtr obj(PyInt_FromLong(value->number()));
    if (obj == NULL) {
      return false;
    }
    if (PyDict_SetItemString(type->tp_dict, value->name().c_str(), obj.get()) <
        0) {
      return false;
    }
  }
  return true;
}

static bool AddIntConstant(PyTypeObject *type, const char* name, int value) {
  ScopedPyObjectPtr obj(PyInt_FromLong(value));
  if (PyDict_SetItemString(type->tp_dict, name, obj.get()) < 0) {
    return false;
  }
  return true;
}


bool InitDescriptor() {
  if (PyType_Ready(&PyMessageDescriptor_Type) < 0)
    return false;

  if (PyType_Ready(&PyFieldDescriptor_Type) < 0)
    return false;

  if (!AddEnumValues(&PyFieldDescriptor_Type,
                     FieldDescriptorProto::Label_descriptor())) {
    return false;
  }
  if (!AddEnumValues(&PyFieldDescriptor_Type,
                     FieldDescriptorProto::Type_descriptor())) {
    return false;
  }
#define ADD_FIELDDESC_CONSTANT(NAME) AddIntConstant( \
    &PyFieldDescriptor_Type, #NAME, FieldDescriptor::NAME)
  if (!ADD_FIELDDESC_CONSTANT(CPPTYPE_INT32) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_INT64) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT32) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT64) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_DOUBLE) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_FLOAT) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_BOOL) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_ENUM) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_STRING) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_MESSAGE)) {
    return false;
  }
#undef ADD_FIELDDESC_CONSTANT

  if (PyType_Ready(&PyEnumDescriptor_Type) < 0)
    return false;

  if (PyType_Ready(&PyEnumValueDescriptor_Type) < 0)
    return false;

  if (PyType_Ready(&PyFileDescriptor_Type) < 0)
    return false;

  if (PyType_Ready(&PyOneofDescriptor_Type) < 0)
    return false;

  if (!InitDescriptorMappingTypes())
    return false;

  return true;
}

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