15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc.  All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: petar@google.com (Petar Petrov)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <Python.h>
343d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch#include <string>
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/pyext/python_descriptor.h>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.pb.h>
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define C(str) const_cast<char*>(str)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace python {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
453d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void CFieldDescriptorDealloc(CFieldDescriptor* self);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static google::protobuf::DescriptorPool* g_descriptor_pool = NULL;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PyObject* CFieldDescriptor_GetFullName(
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CFieldDescriptor* self, void *closure) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_XINCREF(self->full_name);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return self->full_name;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PyObject* CFieldDescriptor_GetName(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CFieldDescriptor *self, void *closure) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_XINCREF(self->name);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return self->name;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PyObject* CFieldDescriptor_GetCppType(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CFieldDescriptor *self, void *closure) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_XINCREF(self->cpp_type);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return self->cpp_type;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PyObject* CFieldDescriptor_GetLabel(
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CFieldDescriptor *self, void *closure) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_XINCREF(self->label);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return self->label;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PyObject* CFieldDescriptor_GetID(
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CFieldDescriptor *self, void *closure) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_XINCREF(self->id);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return self->id;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PyGetSetDef CFieldDescriptorGetters[] = {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { C("full_name"),
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (getter)CFieldDescriptor_GetFullName, NULL, "Full name", NULL},
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { C("name"),
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (getter)CFieldDescriptor_GetName, NULL, "last name", NULL},
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { C("cpp_type"),
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (getter)CFieldDescriptor_GetCppType, NULL, "C++ Type", NULL},
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { C("label"),
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (getter)CFieldDescriptor_GetLabel, NULL, "Label", NULL},
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { C("id"),
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (getter)CFieldDescriptor_GetID, NULL, "ID", NULL},
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {NULL}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PyTypeObject CFieldDescriptor_Type = {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PyObject_HEAD_INIT(&PyType_Type)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,
983d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  C("google.protobuf.internal."
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "_net_proto2___python."
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "CFieldDescriptor"),                // tp_name
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sizeof(CFieldDescriptor),             // tp_basicsize
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_itemsize
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (destructor)CFieldDescriptorDealloc,  // tp_dealloc
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_print
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_getattr
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_setattr
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_compare
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_repr
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_as_number
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_as_sequence
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_as_mapping
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_hash
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_call
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_str
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_getattro
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_setattro
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_as_buffer
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_TPFLAGS_DEFAULT,                   // tp_flags
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C("A Field Descriptor"),              // tp_doc
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_traverse
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_clear
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_richcompare
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_weaklistoffset
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_iter
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_iternext
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_methods
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_members
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFieldDescriptorGetters,              // tp_getset
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_base
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_dict
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_descr_get
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_descr_set
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_dictoffset
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                    // tp_init
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PyType_GenericAlloc,                  // tp_alloc
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PyType_GenericNew,                    // tp_new
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PyObject_Del,                         // tp_free
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void CFieldDescriptorDealloc(CFieldDescriptor* self) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_DECREF(self->full_name);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_DECREF(self->name);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_DECREF(self->cpp_type);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_DECREF(self->label);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_DECREF(self->id);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self->ob_type->tp_free(reinterpret_cast<PyObject*>(self));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PyObject_HEAD
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const google::protobuf::DescriptorPool* pool;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} CDescriptorPool;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void CDescriptorPoolDealloc(CDescriptorPool* self);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PyObject* CDescriptorPool_NewCDescriptor(
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const google::protobuf::FieldDescriptor* field_descriptor) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFieldDescriptor* cfield_descriptor = PyObject_New(
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CFieldDescriptor, &CFieldDescriptor_Type);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cfield_descriptor == NULL) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cfield_descriptor->descriptor = field_descriptor;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cfield_descriptor->full_name = PyString_FromString(
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      field_descriptor->full_name().c_str());
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cfield_descriptor->name = PyString_FromString(
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      field_descriptor->name().c_str());
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cfield_descriptor->cpp_type = PyLong_FromLong(field_descriptor->cpp_type());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cfield_descriptor->label = PyLong_FromLong(field_descriptor->label());
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cfield_descriptor->id = PyLong_FromVoidPtr(cfield_descriptor);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return reinterpret_cast<PyObject*>(cfield_descriptor);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PyObject* CDescriptorPool_FindFieldByName(
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CDescriptorPool* self, PyObject* arg) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* full_field_name = PyString_AsString(arg);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (full_field_name == NULL) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const google::protobuf::FieldDescriptor* field_descriptor = NULL;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  field_descriptor = self->pool->FindFieldByName(full_field_name);
1863d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1873d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (field_descriptor == NULL) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s",
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 full_field_name);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CDescriptorPool_NewCDescriptor(field_descriptor);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PyObject* CDescriptorPool_FindExtensionByName(
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CDescriptorPool* self, PyObject* arg) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* full_field_name = PyString_AsString(arg);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (full_field_name == NULL) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const google::protobuf::FieldDescriptor* field_descriptor =
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self->pool->FindExtensionByName(full_field_name);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (field_descriptor == NULL) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s",
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 full_field_name);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CDescriptorPool_NewCDescriptor(field_descriptor);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PyMethodDef CDescriptorPoolMethods[] = {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { C("FindFieldByName"),
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (PyCFunction)CDescriptorPool_FindFieldByName,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    METH_O,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    C("Searches for a field descriptor by full name.") },
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { C("FindExtensionByName"),
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (PyCFunction)CDescriptorPool_FindExtensionByName,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    METH_O,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    C("Searches for extension descriptor by full name.") },
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {NULL}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PyTypeObject CDescriptorPool_Type = {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PyObject_HEAD_INIT(&PyType_Type)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,
2303d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  C("google.protobuf.internal."
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "_net_proto2___python."
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "CFieldDescriptor"),               // tp_name
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sizeof(CDescriptorPool),             // tp_basicsize
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_itemsize
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (destructor)CDescriptorPoolDealloc,  // tp_dealloc
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_print
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_getattr
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_setattr
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_compare
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_repr
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_as_number
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_as_sequence
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_as_mapping
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_hash
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_call
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_str
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_getattro
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_setattro
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_as_buffer
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_TPFLAGS_DEFAULT,                  // tp_flags
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C("A Descriptor Pool"),              // tp_doc
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_traverse
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_clear
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_richcompare
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_weaklistoffset
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_iter
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_iternext
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CDescriptorPoolMethods,              // tp_methods
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_members
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_getset
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_base
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_dict
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_descr_get
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_descr_set
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_dictoffset
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0,                                   // tp_init
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PyType_GenericAlloc,                 // tp_alloc
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PyType_GenericNew,                   // tp_new
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PyObject_Del,                        // tp_free
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void CDescriptorPoolDealloc(CDescriptorPool* self) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self->ob_type->tp_free(reinterpret_cast<PyObject*>(self));
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)google::protobuf::DescriptorPool* GetDescriptorPool() {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_descriptor_pool == NULL) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_descriptor_pool = new google::protobuf::DescriptorPool(
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        google::protobuf::DescriptorPool::generated_pool());
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_descriptor_pool;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CDescriptorPool* cdescriptor_pool = PyObject_New(
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CDescriptorPool, &CDescriptorPool_Type);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cdescriptor_pool == NULL) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cdescriptor_pool->pool = GetDescriptorPool();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return reinterpret_cast<PyObject*>(cdescriptor_pool);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PyObject* Python_BuildFile(PyObject* ignored, PyObject* arg) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* message_type;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_ssize_t message_len;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (PyString_AsStringAndSize(arg, &message_type, &message_len) < 0) {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  google::protobuf::FileDescriptorProto file_proto;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!file_proto.ParseFromArray(message_type, message_len)) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!");
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_proto.name()) != NULL) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Py_RETURN_NONE;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const google::protobuf::FileDescriptor* descriptor = GetDescriptorPool()->BuildFile(
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_proto);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (descriptor == NULL) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PyErr_SetString(PyExc_TypeError,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    "Couldn't build proto file into descriptor pool!");
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Py_RETURN_NONE;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InitDescriptor() {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFieldDescriptor_Type.tp_new = PyType_GenericNew;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (PyType_Ready(&CFieldDescriptor_Type) < 0)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CDescriptorPool_Type.tp_new = PyType_GenericNew;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (PyType_Ready(&CDescriptorPool_Type) < 0)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace python
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protobuf
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
338