| OLD | NEW |
| (Empty) |
| 1 // Protocol Buffers - Google's data interchange format | |
| 2 // Copyright 2008 Google Inc. All rights reserved. | |
| 3 // http://code.google.com/p/protobuf/ | |
| 4 // | |
| 5 // Redistribution and use in source and binary forms, with or without | |
| 6 // modification, are permitted provided that the following conditions are | |
| 7 // met: | |
| 8 // | |
| 9 // * Redistributions of source code must retain the above copyright | |
| 10 // notice, this list of conditions and the following disclaimer. | |
| 11 // * Redistributions in binary form must reproduce the above | |
| 12 // copyright notice, this list of conditions and the following disclaimer | |
| 13 // in the documentation and/or other materials provided with the | |
| 14 // distribution. | |
| 15 // * Neither the name of Google Inc. nor the names of its | |
| 16 // contributors may be used to endorse or promote products derived from | |
| 17 // this software without specific prior written permission. | |
| 18 // | |
| 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | |
| 31 // Author: petar@google.com (Petar Petrov) | |
| 32 | |
| 33 #include <Python.h> | |
| 34 #include <string> | |
| 35 | |
| 36 #include <google/protobuf/pyext/python_descriptor.h> | |
| 37 #include <google/protobuf/descriptor.pb.h> | |
| 38 | |
| 39 #define C(str) const_cast<char*>(str) | |
| 40 | |
| 41 namespace google { | |
| 42 namespace protobuf { | |
| 43 namespace python { | |
| 44 | |
| 45 | |
| 46 static void CFieldDescriptorDealloc(CFieldDescriptor* self); | |
| 47 | |
| 48 static google::protobuf::DescriptorPool* g_descriptor_pool = NULL; | |
| 49 | |
| 50 static PyObject* CFieldDescriptor_GetFullName( | |
| 51 CFieldDescriptor* self, void *closure) { | |
| 52 Py_XINCREF(self->full_name); | |
| 53 return self->full_name; | |
| 54 } | |
| 55 | |
| 56 static PyObject* CFieldDescriptor_GetName( | |
| 57 CFieldDescriptor *self, void *closure) { | |
| 58 Py_XINCREF(self->name); | |
| 59 return self->name; | |
| 60 } | |
| 61 | |
| 62 static PyObject* CFieldDescriptor_GetCppType( | |
| 63 CFieldDescriptor *self, void *closure) { | |
| 64 Py_XINCREF(self->cpp_type); | |
| 65 return self->cpp_type; | |
| 66 } | |
| 67 | |
| 68 static PyObject* CFieldDescriptor_GetLabel( | |
| 69 CFieldDescriptor *self, void *closure) { | |
| 70 Py_XINCREF(self->label); | |
| 71 return self->label; | |
| 72 } | |
| 73 | |
| 74 static PyObject* CFieldDescriptor_GetID( | |
| 75 CFieldDescriptor *self, void *closure) { | |
| 76 Py_XINCREF(self->id); | |
| 77 return self->id; | |
| 78 } | |
| 79 | |
| 80 | |
| 81 static PyGetSetDef CFieldDescriptorGetters[] = { | |
| 82 { C("full_name"), | |
| 83 (getter)CFieldDescriptor_GetFullName, NULL, "Full name", NULL}, | |
| 84 { C("name"), | |
| 85 (getter)CFieldDescriptor_GetName, NULL, "last name", NULL}, | |
| 86 { C("cpp_type"), | |
| 87 (getter)CFieldDescriptor_GetCppType, NULL, "C++ Type", NULL}, | |
| 88 { C("label"), | |
| 89 (getter)CFieldDescriptor_GetLabel, NULL, "Label", NULL}, | |
| 90 { C("id"), | |
| 91 (getter)CFieldDescriptor_GetID, NULL, "ID", NULL}, | |
| 92 {NULL} | |
| 93 }; | |
| 94 | |
| 95 PyTypeObject CFieldDescriptor_Type = { | |
| 96 PyObject_HEAD_INIT(&PyType_Type) | |
| 97 0, | |
| 98 C("google.protobuf.internal." | |
| 99 "_net_proto2___python." | |
| 100 "CFieldDescriptor"), // tp_name | |
| 101 sizeof(CFieldDescriptor), // tp_basicsize | |
| 102 0, // tp_itemsize | |
| 103 (destructor)CFieldDescriptorDealloc, // tp_dealloc | |
| 104 0, // tp_print | |
| 105 0, // tp_getattr | |
| 106 0, // tp_setattr | |
| 107 0, // tp_compare | |
| 108 0, // tp_repr | |
| 109 0, // tp_as_number | |
| 110 0, // tp_as_sequence | |
| 111 0, // tp_as_mapping | |
| 112 0, // tp_hash | |
| 113 0, // tp_call | |
| 114 0, // tp_str | |
| 115 0, // tp_getattro | |
| 116 0, // tp_setattro | |
| 117 0, // tp_as_buffer | |
| 118 Py_TPFLAGS_DEFAULT, // tp_flags | |
| 119 C("A Field Descriptor"), // tp_doc | |
| 120 0, // tp_traverse | |
| 121 0, // tp_clear | |
| 122 0, // tp_richcompare | |
| 123 0, // tp_weaklistoffset | |
| 124 0, // tp_iter | |
| 125 0, // tp_iternext | |
| 126 0, // tp_methods | |
| 127 0, // tp_members | |
| 128 CFieldDescriptorGetters, // tp_getset | |
| 129 0, // tp_base | |
| 130 0, // tp_dict | |
| 131 0, // tp_descr_get | |
| 132 0, // tp_descr_set | |
| 133 0, // tp_dictoffset | |
| 134 0, // tp_init | |
| 135 PyType_GenericAlloc, // tp_alloc | |
| 136 PyType_GenericNew, // tp_new | |
| 137 PyObject_Del, // tp_free | |
| 138 }; | |
| 139 | |
| 140 static void CFieldDescriptorDealloc(CFieldDescriptor* self) { | |
| 141 Py_DECREF(self->full_name); | |
| 142 Py_DECREF(self->name); | |
| 143 Py_DECREF(self->cpp_type); | |
| 144 Py_DECREF(self->label); | |
| 145 Py_DECREF(self->id); | |
| 146 self->ob_type->tp_free(reinterpret_cast<PyObject*>(self)); | |
| 147 } | |
| 148 | |
| 149 typedef struct { | |
| 150 PyObject_HEAD | |
| 151 | |
| 152 const google::protobuf::DescriptorPool* pool; | |
| 153 } CDescriptorPool; | |
| 154 | |
| 155 static void CDescriptorPoolDealloc(CDescriptorPool* self); | |
| 156 | |
| 157 static PyObject* CDescriptorPool_NewCDescriptor( | |
| 158 const google::protobuf::FieldDescriptor* field_descriptor) { | |
| 159 CFieldDescriptor* cfield_descriptor = PyObject_New( | |
| 160 CFieldDescriptor, &CFieldDescriptor_Type); | |
| 161 if (cfield_descriptor == NULL) { | |
| 162 return NULL; | |
| 163 } | |
| 164 cfield_descriptor->descriptor = field_descriptor; | |
| 165 | |
| 166 cfield_descriptor->full_name = PyString_FromString( | |
| 167 field_descriptor->full_name().c_str()); | |
| 168 cfield_descriptor->name = PyString_FromString( | |
| 169 field_descriptor->name().c_str()); | |
| 170 cfield_descriptor->cpp_type = PyLong_FromLong(field_descriptor->cpp_type()); | |
| 171 cfield_descriptor->label = PyLong_FromLong(field_descriptor->label()); | |
| 172 cfield_descriptor->id = PyLong_FromVoidPtr(cfield_descriptor); | |
| 173 return reinterpret_cast<PyObject*>(cfield_descriptor); | |
| 174 } | |
| 175 | |
| 176 static PyObject* CDescriptorPool_FindFieldByName( | |
| 177 CDescriptorPool* self, PyObject* arg) { | |
| 178 const char* full_field_name = PyString_AsString(arg); | |
| 179 if (full_field_name == NULL) { | |
| 180 return NULL; | |
| 181 } | |
| 182 | |
| 183 const google::protobuf::FieldDescriptor* field_descriptor = NULL; | |
| 184 | |
| 185 field_descriptor = self->pool->FindFieldByName(full_field_name); | |
| 186 | |
| 187 | |
| 188 if (field_descriptor == NULL) { | |
| 189 PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s", | |
| 190 full_field_name); | |
| 191 return NULL; | |
| 192 } | |
| 193 | |
| 194 return CDescriptorPool_NewCDescriptor(field_descriptor); | |
| 195 } | |
| 196 | |
| 197 static PyObject* CDescriptorPool_FindExtensionByName( | |
| 198 CDescriptorPool* self, PyObject* arg) { | |
| 199 const char* full_field_name = PyString_AsString(arg); | |
| 200 if (full_field_name == NULL) { | |
| 201 return NULL; | |
| 202 } | |
| 203 | |
| 204 const google::protobuf::FieldDescriptor* field_descriptor = | |
| 205 self->pool->FindExtensionByName(full_field_name); | |
| 206 if (field_descriptor == NULL) { | |
| 207 PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s", | |
| 208 full_field_name); | |
| 209 return NULL; | |
| 210 } | |
| 211 | |
| 212 return CDescriptorPool_NewCDescriptor(field_descriptor); | |
| 213 } | |
| 214 | |
| 215 static PyMethodDef CDescriptorPoolMethods[] = { | |
| 216 { C("FindFieldByName"), | |
| 217 (PyCFunction)CDescriptorPool_FindFieldByName, | |
| 218 METH_O, | |
| 219 C("Searches for a field descriptor by full name.") }, | |
| 220 { C("FindExtensionByName"), | |
| 221 (PyCFunction)CDescriptorPool_FindExtensionByName, | |
| 222 METH_O, | |
| 223 C("Searches for extension descriptor by full name.") }, | |
| 224 {NULL} | |
| 225 }; | |
| 226 | |
| 227 PyTypeObject CDescriptorPool_Type = { | |
| 228 PyObject_HEAD_INIT(&PyType_Type) | |
| 229 0, | |
| 230 C("google.protobuf.internal." | |
| 231 "_net_proto2___python." | |
| 232 "CFieldDescriptor"), // tp_name | |
| 233 sizeof(CDescriptorPool), // tp_basicsize | |
| 234 0, // tp_itemsize | |
| 235 (destructor)CDescriptorPoolDealloc, // tp_dealloc | |
| 236 0, // tp_print | |
| 237 0, // tp_getattr | |
| 238 0, // tp_setattr | |
| 239 0, // tp_compare | |
| 240 0, // tp_repr | |
| 241 0, // tp_as_number | |
| 242 0, // tp_as_sequence | |
| 243 0, // tp_as_mapping | |
| 244 0, // tp_hash | |
| 245 0, // tp_call | |
| 246 0, // tp_str | |
| 247 0, // tp_getattro | |
| 248 0, // tp_setattro | |
| 249 0, // tp_as_buffer | |
| 250 Py_TPFLAGS_DEFAULT, // tp_flags | |
| 251 C("A Descriptor Pool"), // tp_doc | |
| 252 0, // tp_traverse | |
| 253 0, // tp_clear | |
| 254 0, // tp_richcompare | |
| 255 0, // tp_weaklistoffset | |
| 256 0, // tp_iter | |
| 257 0, // tp_iternext | |
| 258 CDescriptorPoolMethods, // tp_methods | |
| 259 0, // tp_members | |
| 260 0, // tp_getset | |
| 261 0, // tp_base | |
| 262 0, // tp_dict | |
| 263 0, // tp_descr_get | |
| 264 0, // tp_descr_set | |
| 265 0, // tp_dictoffset | |
| 266 0, // tp_init | |
| 267 PyType_GenericAlloc, // tp_alloc | |
| 268 PyType_GenericNew, // tp_new | |
| 269 PyObject_Del, // tp_free | |
| 270 }; | |
| 271 | |
| 272 static void CDescriptorPoolDealloc(CDescriptorPool* self) { | |
| 273 self->ob_type->tp_free(reinterpret_cast<PyObject*>(self)); | |
| 274 } | |
| 275 | |
| 276 google::protobuf::DescriptorPool* GetDescriptorPool() { | |
| 277 if (g_descriptor_pool == NULL) { | |
| 278 g_descriptor_pool = new google::protobuf::DescriptorPool( | |
| 279 google::protobuf::DescriptorPool::generated_pool()); | |
| 280 } | |
| 281 return g_descriptor_pool; | |
| 282 } | |
| 283 | |
| 284 PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args) { | |
| 285 CDescriptorPool* cdescriptor_pool = PyObject_New( | |
| 286 CDescriptorPool, &CDescriptorPool_Type); | |
| 287 if (cdescriptor_pool == NULL) { | |
| 288 return NULL; | |
| 289 } | |
| 290 cdescriptor_pool->pool = GetDescriptorPool(); | |
| 291 return reinterpret_cast<PyObject*>(cdescriptor_pool); | |
| 292 } | |
| 293 | |
| 294 PyObject* Python_BuildFile(PyObject* ignored, PyObject* arg) { | |
| 295 char* message_type; | |
| 296 Py_ssize_t message_len; | |
| 297 | |
| 298 if (PyString_AsStringAndSize(arg, &message_type, &message_len) < 0) { | |
| 299 return NULL; | |
| 300 } | |
| 301 | |
| 302 google::protobuf::FileDescriptorProto file_proto; | |
| 303 if (!file_proto.ParseFromArray(message_type, message_len)) { | |
| 304 PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!"); | |
| 305 return NULL; | |
| 306 } | |
| 307 | |
| 308 if (google::protobuf::DescriptorPool::generated_pool()->FindFileByName( | |
| 309 file_proto.name()) != NULL) { | |
| 310 Py_RETURN_NONE; | |
| 311 } | |
| 312 | |
| 313 const google::protobuf::FileDescriptor* descriptor = GetDescriptorPool()->Buil
dFile( | |
| 314 file_proto); | |
| 315 if (descriptor == NULL) { | |
| 316 PyErr_SetString(PyExc_TypeError, | |
| 317 "Couldn't build proto file into descriptor pool!"); | |
| 318 return NULL; | |
| 319 } | |
| 320 | |
| 321 Py_RETURN_NONE; | |
| 322 } | |
| 323 | |
| 324 bool InitDescriptor() { | |
| 325 CFieldDescriptor_Type.tp_new = PyType_GenericNew; | |
| 326 if (PyType_Ready(&CFieldDescriptor_Type) < 0) | |
| 327 return false; | |
| 328 | |
| 329 CDescriptorPool_Type.tp_new = PyType_GenericNew; | |
| 330 if (PyType_Ready(&CDescriptorPool_Type) < 0) | |
| 331 return false; | |
| 332 return true; | |
| 333 } | |
| 334 | |
| 335 } // namespace python | |
| 336 } // namespace protobuf | |
| 337 } // namespace google | |
| OLD | NEW |