1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 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 (at) google.com (Petar Petrov) 32 33 #include <Python.h> 34 #include <frameobject.h> 35 #include <string> 36 37 #include <google/protobuf/io/coded_stream.h> 38 #include <google/protobuf/descriptor.pb.h> 39 #include <google/protobuf/dynamic_message.h> 40 #include <google/protobuf/pyext/descriptor.h> 41 #include <google/protobuf/pyext/descriptor_containers.h> 42 #include <google/protobuf/pyext/descriptor_pool.h> 43 #include <google/protobuf/pyext/message.h> 44 #include <google/protobuf/pyext/scoped_pyobject_ptr.h> 45 46 #if PY_MAJOR_VERSION >= 3 47 #define PyString_FromStringAndSize PyUnicode_FromStringAndSize 48 #define PyString_Check PyUnicode_Check 49 #define PyString_InternFromString PyUnicode_InternFromString 50 #define PyInt_FromLong PyLong_FromLong 51 #define PyInt_FromSize_t PyLong_FromSize_t 52 #if PY_VERSION_HEX < 0x03030000 53 #error "Python 3.0 - 3.2 are not supported." 54 #endif 55 #define PyString_AsStringAndSize(ob, charpp, sizep) \ 56 (PyUnicode_Check(ob)? \ 57 ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \ 58 PyBytes_AsStringAndSize(ob, (charpp), (sizep))) 59 #endif 60 61 namespace google { 62 namespace protobuf { 63 namespace python { 64 65 // Store interned descriptors, so that the same C++ descriptor yields the same 66 // Python object. Objects are not immortal: this map does not own the 67 // references, and items are deleted when the last reference to the object is 68 // released. 69 // This is enough to support the "is" operator on live objects. 70 // All descriptors are stored here. 71 hash_map<const void*, PyObject*> interned_descriptors; 72 73 PyObject* PyString_FromCppString(const string& str) { 74 return PyString_FromStringAndSize(str.c_str(), str.size()); 75 } 76 77 // Check that the calling Python code is the global scope of a _pb2.py module. 78 // This function is used to support the current code generated by the proto 79 // compiler, which creates descriptors, then update some properties. 80 // For example: 81 // message_descriptor = Descriptor( 82 // name='Message', 83 // fields = [FieldDescriptor(name='field')] 84 // message_descriptor.fields[0].containing_type = message_descriptor 85 // 86 // This code is still executed, but the descriptors now have no other storage 87 // than the (const) C++ pointer, and are immutable. 88 // So we let this code pass, by simply ignoring the new value. 89 // 90 // From user code, descriptors still look immutable. 91 // 92 // TODO(amauryfa): Change the proto2 compiler to remove the assignments, and 93 // remove this hack. 94 bool _CalledFromGeneratedFile(int stacklevel) { 95 #ifndef PYPY_VERSION 96 // This check is not critical and is somewhat difficult to implement correctly 97 // in PyPy. 98 PyFrameObject* frame = PyEval_GetFrame(); 99 if (frame == NULL) { 100 return false; 101 } 102 while (stacklevel-- > 0) { 103 frame = frame->f_back; 104 if (frame == NULL) { 105 return false; 106 } 107 } 108 if (frame->f_globals != frame->f_locals) { 109 // Not at global module scope 110 return false; 111 } 112 113 if (frame->f_code->co_filename == NULL) { 114 return false; 115 } 116 char* filename; 117 Py_ssize_t filename_size; 118 if (PyString_AsStringAndSize(frame->f_code->co_filename, 119 &filename, &filename_size) < 0) { 120 // filename is not a string. 121 PyErr_Clear(); 122 return false; 123 } 124 if (filename_size < 7) { 125 // filename is too short. 126 return false; 127 } 128 if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) { 129 // Filename is not ending with _pb2. 130 return false; 131 } 132 #endif 133 return true; 134 } 135 136 // If the calling code is not a _pb2.py file, raise AttributeError. 137 // To be used in attribute setters. 138 static int CheckCalledFromGeneratedFile(const char* attr_name) { 139 if (_CalledFromGeneratedFile(0)) { 140 return 0; 141 } 142 PyErr_Format(PyExc_AttributeError, 143 "attribute is not writable: %s", attr_name); 144 return -1; 145 } 146 147 148 #ifndef PyVarObject_HEAD_INIT 149 #define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, 150 #endif 151 #ifndef Py_TYPE 152 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) 153 #endif 154 155 156 // Helper functions for descriptor objects. 157 158 // A set of templates to retrieve the C++ FileDescriptor of any descriptor. 159 template<class DescriptorClass> 160 const FileDescriptor* GetFileDescriptor(const DescriptorClass* descriptor) { 161 return descriptor->file(); 162 } 163 template<> 164 const FileDescriptor* GetFileDescriptor(const FileDescriptor* descriptor) { 165 return descriptor; 166 } 167 template<> 168 const FileDescriptor* GetFileDescriptor(const EnumValueDescriptor* descriptor) { 169 return descriptor->type()->file(); 170 } 171 template<> 172 const FileDescriptor* GetFileDescriptor(const OneofDescriptor* descriptor) { 173 return descriptor->containing_type()->file(); 174 } 175 176 // Converts options into a Python protobuf, and cache the result. 177 // 178 // This is a bit tricky because options can contain extension fields defined in 179 // the same proto file. In this case the options parsed from the serialized_pb 180 // have unkown fields, and we need to parse them again. 181 // 182 // Always returns a new reference. 183 template<class DescriptorClass> 184 static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { 185 // Options (and their extensions) are completely resolved in the proto file 186 // containing the descriptor. 187 PyDescriptorPool* pool = GetDescriptorPool_FromPool( 188 GetFileDescriptor(descriptor)->pool()); 189 190 hash_map<const void*, PyObject*>* descriptor_options = 191 pool->descriptor_options; 192 // First search in the cache. 193 if (descriptor_options->find(descriptor) != descriptor_options->end()) { 194 PyObject *value = (*descriptor_options)[descriptor]; 195 Py_INCREF(value); 196 return value; 197 } 198 199 // Build the Options object: get its Python class, and make a copy of the C++ 200 // read-only instance. 201 const Message& options(descriptor->options()); 202 const Descriptor *message_type = options.GetDescriptor(); 203 CMessageClass* message_class( 204 cdescriptor_pool::GetMessageClass(pool, message_type)); 205 if (message_class == NULL) { 206 // The Options message was not found in the current DescriptorPool. 207 // In this case, there cannot be extensions to these options, and we can 208 // try to use the basic pool instead. 209 PyErr_Clear(); 210 message_class = cdescriptor_pool::GetMessageClass( 211 GetDefaultDescriptorPool(), message_type); 212 } 213 if (message_class == NULL) { 214 PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s", 215 message_type->full_name().c_str()); 216 return NULL; 217 } 218 ScopedPyObjectPtr value( 219 PyEval_CallObject(message_class->AsPyObject(), NULL)); 220 if (value == NULL) { 221 return NULL; 222 } 223 if (!PyObject_TypeCheck(value.get(), &CMessage_Type)) { 224 PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s", 225 message_type->full_name().c_str(), 226 Py_TYPE(value.get())->tp_name); 227 return NULL; 228 } 229 CMessage* cmsg = reinterpret_cast<CMessage*>(value.get()); 230 231 const Reflection* reflection = options.GetReflection(); 232 const UnknownFieldSet& unknown_fields(reflection->GetUnknownFields(options)); 233 if (unknown_fields.empty()) { 234 cmsg->message->CopyFrom(options); 235 } else { 236 // Reparse options string! XXX call cmessage::MergeFromString 237 string serialized; 238 options.SerializeToString(&serialized); 239 io::CodedInputStream input( 240 reinterpret_cast<const uint8*>(serialized.c_str()), serialized.size()); 241 input.SetExtensionRegistry(pool->pool, pool->message_factory); 242 bool success = cmsg->message->MergePartialFromCodedStream(&input); 243 if (!success) { 244 PyErr_Format(PyExc_ValueError, "Error parsing Options message"); 245 return NULL; 246 } 247 } 248 249 // Cache the result. 250 Py_INCREF(value.get()); 251 (*pool->descriptor_options)[descriptor] = value.get(); 252 253 return value.release(); 254 } 255 256 // Copy the C++ descriptor to a Python message. 257 // The Python message is an instance of descriptor_pb2.DescriptorProto 258 // or similar. 259 template<class DescriptorProtoClass, class DescriptorClass> 260 static PyObject* CopyToPythonProto(const DescriptorClass *descriptor, 261 PyObject *target) { 262 const Descriptor* self_descriptor = 263 DescriptorProtoClass::default_instance().GetDescriptor(); 264 CMessage* message = reinterpret_cast<CMessage*>(target); 265 if (!PyObject_TypeCheck(target, &CMessage_Type) || 266 message->message->GetDescriptor() != self_descriptor) { 267 PyErr_Format(PyExc_TypeError, "Not a %s message", 268 self_descriptor->full_name().c_str()); 269 return NULL; 270 } 271 cmessage::AssureWritable(message); 272 DescriptorProtoClass* descriptor_message = 273 static_cast<DescriptorProtoClass*>(message->message); 274 descriptor->CopyTo(descriptor_message); 275 Py_RETURN_NONE; 276 } 277 278 // All Descriptors classes share the same memory layout. 279 typedef struct PyBaseDescriptor { 280 PyObject_HEAD 281 282 // Pointer to the C++ proto2 descriptor. 283 // Like all descriptors, it is owned by the global DescriptorPool. 284 const void* descriptor; 285 286 // Owned reference to the DescriptorPool, to ensure it is kept alive. 287 PyDescriptorPool* pool; 288 } PyBaseDescriptor; 289 290 291 // FileDescriptor structure "inherits" from the base descriptor. 292 typedef struct PyFileDescriptor { 293 PyBaseDescriptor base; 294 295 // The cached version of serialized pb. Either NULL, or a Bytes string. 296 // We own the reference. 297 PyObject *serialized_pb; 298 } PyFileDescriptor; 299 300 301 namespace descriptor { 302 303 // Creates or retrieve a Python descriptor of the specified type. 304 // Objects are interned: the same descriptor will return the same object if it 305 // was kept alive. 306 // 'was_created' is an optional pointer to a bool, and is set to true if a new 307 // object was allocated. 308 // Always return a new reference. 309 template<class DescriptorClass> 310 PyObject* NewInternedDescriptor(PyTypeObject* type, 311 const DescriptorClass* descriptor, 312 bool* was_created) { 313 if (was_created) { 314 *was_created = false; 315 } 316 if (descriptor == NULL) { 317 PyErr_BadInternalCall(); 318 return NULL; 319 } 320 321 // See if the object is in the map of interned descriptors 322 hash_map<const void*, PyObject*>::iterator it = 323 interned_descriptors.find(descriptor); 324 if (it != interned_descriptors.end()) { 325 GOOGLE_DCHECK(Py_TYPE(it->second) == type); 326 Py_INCREF(it->second); 327 return it->second; 328 } 329 // Create a new descriptor object 330 PyBaseDescriptor* py_descriptor = PyObject_New( 331 PyBaseDescriptor, type); 332 if (py_descriptor == NULL) { 333 return NULL; 334 } 335 py_descriptor->descriptor = descriptor; 336 337 // and cache it. 338 interned_descriptors.insert( 339 std::make_pair(descriptor, reinterpret_cast<PyObject*>(py_descriptor))); 340 341 // Ensures that the DescriptorPool stays alive. 342 PyDescriptorPool* pool = GetDescriptorPool_FromPool( 343 GetFileDescriptor(descriptor)->pool()); 344 if (pool == NULL) { 345 // Don't DECREF, the object is not fully initialized. 346 PyObject_Del(py_descriptor); 347 return NULL; 348 } 349 Py_INCREF(pool); 350 py_descriptor->pool = pool; 351 352 if (was_created) { 353 *was_created = true; 354 } 355 return reinterpret_cast<PyObject*>(py_descriptor); 356 } 357 358 static void Dealloc(PyBaseDescriptor* self) { 359 // Remove from interned dictionary 360 interned_descriptors.erase(self->descriptor); 361 Py_CLEAR(self->pool); 362 Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); 363 } 364 365 static PyGetSetDef Getters[] = { 366 {NULL} 367 }; 368 369 PyTypeObject PyBaseDescriptor_Type = { 370 PyVarObject_HEAD_INIT(&PyType_Type, 0) 371 FULL_MODULE_NAME ".DescriptorBase", // tp_name 372 sizeof(PyBaseDescriptor), // tp_basicsize 373 0, // tp_itemsize 374 (destructor)Dealloc, // tp_dealloc 375 0, // tp_print 376 0, // tp_getattr 377 0, // tp_setattr 378 0, // tp_compare 379 0, // tp_repr 380 0, // tp_as_number 381 0, // tp_as_sequence 382 0, // tp_as_mapping 383 0, // tp_hash 384 0, // tp_call 385 0, // tp_str 386 0, // tp_getattro 387 0, // tp_setattro 388 0, // tp_as_buffer 389 Py_TPFLAGS_DEFAULT, // tp_flags 390 "Descriptors base class", // tp_doc 391 0, // tp_traverse 392 0, // tp_clear 393 0, // tp_richcompare 394 0, // tp_weaklistoffset 395 0, // tp_iter 396 0, // tp_iternext 397 0, // tp_methods 398 0, // tp_members 399 Getters, // tp_getset 400 }; 401 402 } // namespace descriptor 403 404 const void* PyDescriptor_AsVoidPtr(PyObject* obj) { 405 if (!PyObject_TypeCheck(obj, &descriptor::PyBaseDescriptor_Type)) { 406 PyErr_SetString(PyExc_TypeError, "Not a BaseDescriptor"); 407 return NULL; 408 } 409 return reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor; 410 } 411 412 namespace message_descriptor { 413 414 // Unchecked accessor to the C++ pointer. 415 static const Descriptor* _GetDescriptor(PyBaseDescriptor* self) { 416 return reinterpret_cast<const Descriptor*>(self->descriptor); 417 } 418 419 static PyObject* GetName(PyBaseDescriptor* self, void *closure) { 420 return PyString_FromCppString(_GetDescriptor(self)->name()); 421 } 422 423 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) { 424 return PyString_FromCppString(_GetDescriptor(self)->full_name()); 425 } 426 427 static PyObject* GetFile(PyBaseDescriptor *self, void *closure) { 428 return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file()); 429 } 430 431 static PyObject* GetConcreteClass(PyBaseDescriptor* self, void *closure) { 432 // Retuns the canonical class for the given descriptor. 433 // This is the class that was registered with the primary descriptor pool 434 // which contains this descriptor. 435 // This might not be the one you expect! For example the returned object does 436 // not know about extensions defined in a custom pool. 437 CMessageClass* concrete_class(cdescriptor_pool::GetMessageClass( 438 GetDescriptorPool_FromPool(_GetDescriptor(self)->file()->pool()), 439 _GetDescriptor(self))); 440 Py_XINCREF(concrete_class); 441 return concrete_class->AsPyObject(); 442 } 443 444 static PyObject* GetFieldsByName(PyBaseDescriptor* self, void *closure) { 445 return NewMessageFieldsByName(_GetDescriptor(self)); 446 } 447 448 static PyObject* GetFieldsByCamelcaseName(PyBaseDescriptor* self, 449 void *closure) { 450 return NewMessageFieldsByCamelcaseName(_GetDescriptor(self)); 451 } 452 453 static PyObject* GetFieldsByNumber(PyBaseDescriptor* self, void *closure) { 454 return NewMessageFieldsByNumber(_GetDescriptor(self)); 455 } 456 457 static PyObject* GetFieldsSeq(PyBaseDescriptor* self, void *closure) { 458 return NewMessageFieldsSeq(_GetDescriptor(self)); 459 } 460 461 static PyObject* GetNestedTypesByName(PyBaseDescriptor* self, void *closure) { 462 return NewMessageNestedTypesByName(_GetDescriptor(self)); 463 } 464 465 static PyObject* GetNestedTypesSeq(PyBaseDescriptor* self, void *closure) { 466 return NewMessageNestedTypesSeq(_GetDescriptor(self)); 467 } 468 469 static PyObject* GetExtensionsByName(PyBaseDescriptor* self, void *closure) { 470 return NewMessageExtensionsByName(_GetDescriptor(self)); 471 } 472 473 static PyObject* GetExtensions(PyBaseDescriptor* self, void *closure) { 474 return NewMessageExtensionsSeq(_GetDescriptor(self)); 475 } 476 477 static PyObject* GetEnumsSeq(PyBaseDescriptor* self, void *closure) { 478 return NewMessageEnumsSeq(_GetDescriptor(self)); 479 } 480 481 static PyObject* GetEnumTypesByName(PyBaseDescriptor* self, void *closure) { 482 return NewMessageEnumsByName(_GetDescriptor(self)); 483 } 484 485 static PyObject* GetEnumValuesByName(PyBaseDescriptor* self, void *closure) { 486 return NewMessageEnumValuesByName(_GetDescriptor(self)); 487 } 488 489 static PyObject* GetOneofsByName(PyBaseDescriptor* self, void *closure) { 490 return NewMessageOneofsByName(_GetDescriptor(self)); 491 } 492 493 static PyObject* GetOneofsSeq(PyBaseDescriptor* self, void *closure) { 494 return NewMessageOneofsSeq(_GetDescriptor(self)); 495 } 496 497 static PyObject* IsExtendable(PyBaseDescriptor *self, void *closure) { 498 if (_GetDescriptor(self)->extension_range_count() > 0) { 499 Py_RETURN_TRUE; 500 } else { 501 Py_RETURN_FALSE; 502 } 503 } 504 505 static PyObject* GetExtensionRanges(PyBaseDescriptor *self, void *closure) { 506 const Descriptor* descriptor = _GetDescriptor(self); 507 PyObject* range_list = PyList_New(descriptor->extension_range_count()); 508 509 for (int i = 0; i < descriptor->extension_range_count(); i++) { 510 const Descriptor::ExtensionRange* range = descriptor->extension_range(i); 511 PyObject* start = PyInt_FromLong(range->start); 512 PyObject* end = PyInt_FromLong(range->end); 513 PyList_SetItem(range_list, i, PyTuple_Pack(2, start, end)); 514 } 515 516 return range_list; 517 } 518 519 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) { 520 const Descriptor* containing_type = 521 _GetDescriptor(self)->containing_type(); 522 if (containing_type) { 523 return PyMessageDescriptor_FromDescriptor(containing_type); 524 } else { 525 Py_RETURN_NONE; 526 } 527 } 528 529 static int SetContainingType(PyBaseDescriptor *self, PyObject *value, 530 void *closure) { 531 return CheckCalledFromGeneratedFile("containing_type"); 532 } 533 534 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) { 535 const MessageOptions& options(_GetDescriptor(self)->options()); 536 if (&options != &MessageOptions::default_instance()) { 537 Py_RETURN_TRUE; 538 } else { 539 Py_RETURN_FALSE; 540 } 541 } 542 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, 543 void *closure) { 544 return CheckCalledFromGeneratedFile("has_options"); 545 } 546 547 static PyObject* GetOptions(PyBaseDescriptor *self) { 548 return GetOrBuildOptions(_GetDescriptor(self)); 549 } 550 551 static int SetOptions(PyBaseDescriptor *self, PyObject *value, 552 void *closure) { 553 return CheckCalledFromGeneratedFile("_options"); 554 } 555 556 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { 557 return CopyToPythonProto<DescriptorProto>(_GetDescriptor(self), target); 558 } 559 560 static PyObject* EnumValueName(PyBaseDescriptor *self, PyObject *args) { 561 const char *enum_name; 562 int number; 563 if (!PyArg_ParseTuple(args, "si", &enum_name, &number)) 564 return NULL; 565 const EnumDescriptor *enum_type = 566 _GetDescriptor(self)->FindEnumTypeByName(enum_name); 567 if (enum_type == NULL) { 568 PyErr_SetString(PyExc_KeyError, enum_name); 569 return NULL; 570 } 571 const EnumValueDescriptor *enum_value = 572 enum_type->FindValueByNumber(number); 573 if (enum_value == NULL) { 574 PyErr_Format(PyExc_KeyError, "%d", number); 575 return NULL; 576 } 577 return PyString_FromCppString(enum_value->name()); 578 } 579 580 static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) { 581 return PyString_InternFromString( 582 FileDescriptor::SyntaxName(_GetDescriptor(self)->file()->syntax())); 583 } 584 585 static PyGetSetDef Getters[] = { 586 { "name", (getter)GetName, NULL, "Last name"}, 587 { "full_name", (getter)GetFullName, NULL, "Full name"}, 588 { "_concrete_class", (getter)GetConcreteClass, NULL, "concrete class"}, 589 { "file", (getter)GetFile, NULL, "File descriptor"}, 590 591 { "fields", (getter)GetFieldsSeq, NULL, "Fields sequence"}, 592 { "fields_by_name", (getter)GetFieldsByName, NULL, "Fields by name"}, 593 { "fields_by_camelcase_name", (getter)GetFieldsByCamelcaseName, NULL, 594 "Fields by camelCase name"}, 595 { "fields_by_number", (getter)GetFieldsByNumber, NULL, "Fields by number"}, 596 { "nested_types", (getter)GetNestedTypesSeq, NULL, "Nested types sequence"}, 597 { "nested_types_by_name", (getter)GetNestedTypesByName, NULL, 598 "Nested types by name"}, 599 { "extensions", (getter)GetExtensions, NULL, "Extensions Sequence"}, 600 { "extensions_by_name", (getter)GetExtensionsByName, NULL, 601 "Extensions by name"}, 602 { "extension_ranges", (getter)GetExtensionRanges, NULL, "Extension ranges"}, 603 { "enum_types", (getter)GetEnumsSeq, NULL, "Enum sequence"}, 604 { "enum_types_by_name", (getter)GetEnumTypesByName, NULL, 605 "Enum types by name"}, 606 { "enum_values_by_name", (getter)GetEnumValuesByName, NULL, 607 "Enum values by name"}, 608 { "oneofs_by_name", (getter)GetOneofsByName, NULL, "Oneofs by name"}, 609 { "oneofs", (getter)GetOneofsSeq, NULL, "Oneofs by name"}, 610 { "containing_type", (getter)GetContainingType, (setter)SetContainingType, 611 "Containing type"}, 612 { "is_extendable", (getter)IsExtendable, (setter)NULL}, 613 { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, 614 { "_options", (getter)NULL, (setter)SetOptions, "Options"}, 615 { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"}, 616 {NULL} 617 }; 618 619 static PyMethodDef Methods[] = { 620 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, 621 { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, 622 { "EnumValueName", (PyCFunction)EnumValueName, METH_VARARGS, }, 623 {NULL} 624 }; 625 626 } // namespace message_descriptor 627 628 PyTypeObject PyMessageDescriptor_Type = { 629 PyVarObject_HEAD_INIT(&PyType_Type, 0) 630 FULL_MODULE_NAME ".MessageDescriptor", // tp_name 631 sizeof(PyBaseDescriptor), // tp_basicsize 632 0, // tp_itemsize 633 0, // tp_dealloc 634 0, // tp_print 635 0, // tp_getattr 636 0, // tp_setattr 637 0, // tp_compare 638 0, // tp_repr 639 0, // tp_as_number 640 0, // tp_as_sequence 641 0, // tp_as_mapping 642 0, // tp_hash 643 0, // tp_call 644 0, // tp_str 645 0, // tp_getattro 646 0, // tp_setattro 647 0, // tp_as_buffer 648 Py_TPFLAGS_DEFAULT, // tp_flags 649 "A Message Descriptor", // tp_doc 650 0, // tp_traverse 651 0, // tp_clear 652 0, // tp_richcompare 653 0, // tp_weaklistoffset 654 0, // tp_iter 655 0, // tp_iternext 656 message_descriptor::Methods, // tp_methods 657 0, // tp_members 658 message_descriptor::Getters, // tp_getset 659 &descriptor::PyBaseDescriptor_Type, // tp_base 660 }; 661 662 PyObject* PyMessageDescriptor_FromDescriptor( 663 const Descriptor* message_descriptor) { 664 return descriptor::NewInternedDescriptor( 665 &PyMessageDescriptor_Type, message_descriptor, NULL); 666 } 667 668 const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj) { 669 if (!PyObject_TypeCheck(obj, &PyMessageDescriptor_Type)) { 670 PyErr_SetString(PyExc_TypeError, "Not a MessageDescriptor"); 671 return NULL; 672 } 673 return reinterpret_cast<const Descriptor*>( 674 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor); 675 } 676 677 namespace field_descriptor { 678 679 // Unchecked accessor to the C++ pointer. 680 static const FieldDescriptor* _GetDescriptor( 681 PyBaseDescriptor *self) { 682 return reinterpret_cast<const FieldDescriptor*>(self->descriptor); 683 } 684 685 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) { 686 return PyString_FromCppString(_GetDescriptor(self)->full_name()); 687 } 688 689 static PyObject* GetName(PyBaseDescriptor *self, void *closure) { 690 return PyString_FromCppString(_GetDescriptor(self)->name()); 691 } 692 693 static PyObject* GetCamelcaseName(PyBaseDescriptor* self, void *closure) { 694 return PyString_FromCppString(_GetDescriptor(self)->camelcase_name()); 695 } 696 697 static PyObject* GetType(PyBaseDescriptor *self, void *closure) { 698 return PyInt_FromLong(_GetDescriptor(self)->type()); 699 } 700 701 static PyObject* GetCppType(PyBaseDescriptor *self, void *closure) { 702 return PyInt_FromLong(_GetDescriptor(self)->cpp_type()); 703 } 704 705 static PyObject* GetLabel(PyBaseDescriptor *self, void *closure) { 706 return PyInt_FromLong(_GetDescriptor(self)->label()); 707 } 708 709 static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) { 710 return PyInt_FromLong(_GetDescriptor(self)->number()); 711 } 712 713 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) { 714 return PyInt_FromLong(_GetDescriptor(self)->index()); 715 } 716 717 static PyObject* GetID(PyBaseDescriptor *self, void *closure) { 718 return PyLong_FromVoidPtr(self); 719 } 720 721 static PyObject* IsExtension(PyBaseDescriptor *self, void *closure) { 722 return PyBool_FromLong(_GetDescriptor(self)->is_extension()); 723 } 724 725 static PyObject* HasDefaultValue(PyBaseDescriptor *self, void *closure) { 726 return PyBool_FromLong(_GetDescriptor(self)->has_default_value()); 727 } 728 729 static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) { 730 PyObject *result; 731 732 switch (_GetDescriptor(self)->cpp_type()) { 733 case FieldDescriptor::CPPTYPE_INT32: { 734 int32 value = _GetDescriptor(self)->default_value_int32(); 735 result = PyInt_FromLong(value); 736 break; 737 } 738 case FieldDescriptor::CPPTYPE_INT64: { 739 int64 value = _GetDescriptor(self)->default_value_int64(); 740 result = PyLong_FromLongLong(value); 741 break; 742 } 743 case FieldDescriptor::CPPTYPE_UINT32: { 744 uint32 value = _GetDescriptor(self)->default_value_uint32(); 745 result = PyInt_FromSize_t(value); 746 break; 747 } 748 case FieldDescriptor::CPPTYPE_UINT64: { 749 uint64 value = _GetDescriptor(self)->default_value_uint64(); 750 result = PyLong_FromUnsignedLongLong(value); 751 break; 752 } 753 case FieldDescriptor::CPPTYPE_FLOAT: { 754 float value = _GetDescriptor(self)->default_value_float(); 755 result = PyFloat_FromDouble(value); 756 break; 757 } 758 case FieldDescriptor::CPPTYPE_DOUBLE: { 759 double value = _GetDescriptor(self)->default_value_double(); 760 result = PyFloat_FromDouble(value); 761 break; 762 } 763 case FieldDescriptor::CPPTYPE_BOOL: { 764 bool value = _GetDescriptor(self)->default_value_bool(); 765 result = PyBool_FromLong(value); 766 break; 767 } 768 case FieldDescriptor::CPPTYPE_STRING: { 769 string value = _GetDescriptor(self)->default_value_string(); 770 result = ToStringObject(_GetDescriptor(self), value); 771 break; 772 } 773 case FieldDescriptor::CPPTYPE_ENUM: { 774 const EnumValueDescriptor* value = 775 _GetDescriptor(self)->default_value_enum(); 776 result = PyInt_FromLong(value->number()); 777 break; 778 } 779 default: 780 PyErr_Format(PyExc_NotImplementedError, "default value for %s", 781 _GetDescriptor(self)->full_name().c_str()); 782 return NULL; 783 } 784 return result; 785 } 786 787 static PyObject* GetCDescriptor(PyObject *self, void *closure) { 788 Py_INCREF(self); 789 return self; 790 } 791 792 static PyObject *GetEnumType(PyBaseDescriptor *self, void *closure) { 793 const EnumDescriptor* enum_type = _GetDescriptor(self)->enum_type(); 794 if (enum_type) { 795 return PyEnumDescriptor_FromDescriptor(enum_type); 796 } else { 797 Py_RETURN_NONE; 798 } 799 } 800 801 static int SetEnumType(PyBaseDescriptor *self, PyObject *value, void *closure) { 802 return CheckCalledFromGeneratedFile("enum_type"); 803 } 804 805 static PyObject *GetMessageType(PyBaseDescriptor *self, void *closure) { 806 const Descriptor* message_type = _GetDescriptor(self)->message_type(); 807 if (message_type) { 808 return PyMessageDescriptor_FromDescriptor(message_type); 809 } else { 810 Py_RETURN_NONE; 811 } 812 } 813 814 static int SetMessageType(PyBaseDescriptor *self, PyObject *value, 815 void *closure) { 816 return CheckCalledFromGeneratedFile("message_type"); 817 } 818 819 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) { 820 const Descriptor* containing_type = 821 _GetDescriptor(self)->containing_type(); 822 if (containing_type) { 823 return PyMessageDescriptor_FromDescriptor(containing_type); 824 } else { 825 Py_RETURN_NONE; 826 } 827 } 828 829 static int SetContainingType(PyBaseDescriptor *self, PyObject *value, 830 void *closure) { 831 return CheckCalledFromGeneratedFile("containing_type"); 832 } 833 834 static PyObject* GetExtensionScope(PyBaseDescriptor *self, void *closure) { 835 const Descriptor* extension_scope = 836 _GetDescriptor(self)->extension_scope(); 837 if (extension_scope) { 838 return PyMessageDescriptor_FromDescriptor(extension_scope); 839 } else { 840 Py_RETURN_NONE; 841 } 842 } 843 844 static PyObject* GetContainingOneof(PyBaseDescriptor *self, void *closure) { 845 const OneofDescriptor* containing_oneof = 846 _GetDescriptor(self)->containing_oneof(); 847 if (containing_oneof) { 848 return PyOneofDescriptor_FromDescriptor(containing_oneof); 849 } else { 850 Py_RETURN_NONE; 851 } 852 } 853 854 static int SetContainingOneof(PyBaseDescriptor *self, PyObject *value, 855 void *closure) { 856 return CheckCalledFromGeneratedFile("containing_oneof"); 857 } 858 859 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) { 860 const FieldOptions& options(_GetDescriptor(self)->options()); 861 if (&options != &FieldOptions::default_instance()) { 862 Py_RETURN_TRUE; 863 } else { 864 Py_RETURN_FALSE; 865 } 866 } 867 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, 868 void *closure) { 869 return CheckCalledFromGeneratedFile("has_options"); 870 } 871 872 static PyObject* GetOptions(PyBaseDescriptor *self) { 873 return GetOrBuildOptions(_GetDescriptor(self)); 874 } 875 876 static int SetOptions(PyBaseDescriptor *self, PyObject *value, 877 void *closure) { 878 return CheckCalledFromGeneratedFile("_options"); 879 } 880 881 882 static PyGetSetDef Getters[] = { 883 { "full_name", (getter)GetFullName, NULL, "Full name"}, 884 { "name", (getter)GetName, NULL, "Unqualified name"}, 885 { "camelcase_name", (getter)GetCamelcaseName, NULL, "Camelcase name"}, 886 { "type", (getter)GetType, NULL, "C++ Type"}, 887 { "cpp_type", (getter)GetCppType, NULL, "C++ Type"}, 888 { "label", (getter)GetLabel, NULL, "Label"}, 889 { "number", (getter)GetNumber, NULL, "Number"}, 890 { "index", (getter)GetIndex, NULL, "Index"}, 891 { "default_value", (getter)GetDefaultValue, NULL, "Default Value"}, 892 { "has_default_value", (getter)HasDefaultValue}, 893 { "is_extension", (getter)IsExtension, NULL, "ID"}, 894 { "id", (getter)GetID, NULL, "ID"}, 895 { "_cdescriptor", (getter)GetCDescriptor, NULL, "HAACK REMOVE ME"}, 896 897 { "message_type", (getter)GetMessageType, (setter)SetMessageType, 898 "Message type"}, 899 { "enum_type", (getter)GetEnumType, (setter)SetEnumType, "Enum type"}, 900 { "containing_type", (getter)GetContainingType, (setter)SetContainingType, 901 "Containing type"}, 902 { "extension_scope", (getter)GetExtensionScope, (setter)NULL, 903 "Extension scope"}, 904 { "containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof, 905 "Containing oneof"}, 906 { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, 907 { "_options", (getter)NULL, (setter)SetOptions, "Options"}, 908 {NULL} 909 }; 910 911 static PyMethodDef Methods[] = { 912 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, 913 {NULL} 914 }; 915 916 } // namespace field_descriptor 917 918 PyTypeObject PyFieldDescriptor_Type = { 919 PyVarObject_HEAD_INIT(&PyType_Type, 0) 920 FULL_MODULE_NAME ".FieldDescriptor", // tp_name 921 sizeof(PyBaseDescriptor), // tp_basicsize 922 0, // tp_itemsize 923 0, // tp_dealloc 924 0, // tp_print 925 0, // tp_getattr 926 0, // tp_setattr 927 0, // tp_compare 928 0, // tp_repr 929 0, // tp_as_number 930 0, // tp_as_sequence 931 0, // tp_as_mapping 932 0, // tp_hash 933 0, // tp_call 934 0, // tp_str 935 0, // tp_getattro 936 0, // tp_setattro 937 0, // tp_as_buffer 938 Py_TPFLAGS_DEFAULT, // tp_flags 939 "A Field Descriptor", // tp_doc 940 0, // tp_traverse 941 0, // tp_clear 942 0, // tp_richcompare 943 0, // tp_weaklistoffset 944 0, // tp_iter 945 0, // tp_iternext 946 field_descriptor::Methods, // tp_methods 947 0, // tp_members 948 field_descriptor::Getters, // tp_getset 949 &descriptor::PyBaseDescriptor_Type, // tp_base 950 }; 951 952 PyObject* PyFieldDescriptor_FromDescriptor( 953 const FieldDescriptor* field_descriptor) { 954 return descriptor::NewInternedDescriptor( 955 &PyFieldDescriptor_Type, field_descriptor, NULL); 956 } 957 958 const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj) { 959 if (!PyObject_TypeCheck(obj, &PyFieldDescriptor_Type)) { 960 PyErr_SetString(PyExc_TypeError, "Not a FieldDescriptor"); 961 return NULL; 962 } 963 return reinterpret_cast<const FieldDescriptor*>( 964 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor); 965 } 966 967 namespace enum_descriptor { 968 969 // Unchecked accessor to the C++ pointer. 970 static const EnumDescriptor* _GetDescriptor( 971 PyBaseDescriptor *self) { 972 return reinterpret_cast<const EnumDescriptor*>(self->descriptor); 973 } 974 975 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) { 976 return PyString_FromCppString(_GetDescriptor(self)->full_name()); 977 } 978 979 static PyObject* GetName(PyBaseDescriptor *self, void *closure) { 980 return PyString_FromCppString(_GetDescriptor(self)->name()); 981 } 982 983 static PyObject* GetFile(PyBaseDescriptor *self, void *closure) { 984 return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file()); 985 } 986 987 static PyObject* GetEnumvaluesByName(PyBaseDescriptor* self, void *closure) { 988 return NewEnumValuesByName(_GetDescriptor(self)); 989 } 990 991 static PyObject* GetEnumvaluesByNumber(PyBaseDescriptor* self, void *closure) { 992 return NewEnumValuesByNumber(_GetDescriptor(self)); 993 } 994 995 static PyObject* GetEnumvaluesSeq(PyBaseDescriptor* self, void *closure) { 996 return NewEnumValuesSeq(_GetDescriptor(self)); 997 } 998 999 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) { 1000 const Descriptor* containing_type = 1001 _GetDescriptor(self)->containing_type(); 1002 if (containing_type) { 1003 return PyMessageDescriptor_FromDescriptor(containing_type); 1004 } else { 1005 Py_RETURN_NONE; 1006 } 1007 } 1008 1009 static int SetContainingType(PyBaseDescriptor *self, PyObject *value, 1010 void *closure) { 1011 return CheckCalledFromGeneratedFile("containing_type"); 1012 } 1013 1014 1015 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) { 1016 const EnumOptions& options(_GetDescriptor(self)->options()); 1017 if (&options != &EnumOptions::default_instance()) { 1018 Py_RETURN_TRUE; 1019 } else { 1020 Py_RETURN_FALSE; 1021 } 1022 } 1023 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, 1024 void *closure) { 1025 return CheckCalledFromGeneratedFile("has_options"); 1026 } 1027 1028 static PyObject* GetOptions(PyBaseDescriptor *self) { 1029 return GetOrBuildOptions(_GetDescriptor(self)); 1030 } 1031 1032 static int SetOptions(PyBaseDescriptor *self, PyObject *value, 1033 void *closure) { 1034 return CheckCalledFromGeneratedFile("_options"); 1035 } 1036 1037 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { 1038 return CopyToPythonProto<EnumDescriptorProto>(_GetDescriptor(self), target); 1039 } 1040 1041 static PyMethodDef Methods[] = { 1042 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, 1043 { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, 1044 {NULL} 1045 }; 1046 1047 static PyGetSetDef Getters[] = { 1048 { "full_name", (getter)GetFullName, NULL, "Full name"}, 1049 { "name", (getter)GetName, NULL, "last name"}, 1050 { "file", (getter)GetFile, NULL, "File descriptor"}, 1051 { "values", (getter)GetEnumvaluesSeq, NULL, "values"}, 1052 { "values_by_name", (getter)GetEnumvaluesByName, NULL, 1053 "Enum values by name"}, 1054 { "values_by_number", (getter)GetEnumvaluesByNumber, NULL, 1055 "Enum values by number"}, 1056 1057 { "containing_type", (getter)GetContainingType, (setter)SetContainingType, 1058 "Containing type"}, 1059 { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, 1060 { "_options", (getter)NULL, (setter)SetOptions, "Options"}, 1061 {NULL} 1062 }; 1063 1064 } // namespace enum_descriptor 1065 1066 PyTypeObject PyEnumDescriptor_Type = { 1067 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1068 FULL_MODULE_NAME ".EnumDescriptor", // tp_name 1069 sizeof(PyBaseDescriptor), // tp_basicsize 1070 0, // tp_itemsize 1071 0, // tp_dealloc 1072 0, // tp_print 1073 0, // tp_getattr 1074 0, // tp_setattr 1075 0, // tp_compare 1076 0, // tp_repr 1077 0, // tp_as_number 1078 0, // tp_as_sequence 1079 0, // tp_as_mapping 1080 0, // tp_hash 1081 0, // tp_call 1082 0, // tp_str 1083 0, // tp_getattro 1084 0, // tp_setattro 1085 0, // tp_as_buffer 1086 Py_TPFLAGS_DEFAULT, // tp_flags 1087 "A Enum Descriptor", // tp_doc 1088 0, // tp_traverse 1089 0, // tp_clear 1090 0, // tp_richcompare 1091 0, // tp_weaklistoffset 1092 0, // tp_iter 1093 0, // tp_iternext 1094 enum_descriptor::Methods, // tp_getset 1095 0, // tp_members 1096 enum_descriptor::Getters, // tp_getset 1097 &descriptor::PyBaseDescriptor_Type, // tp_base 1098 }; 1099 1100 PyObject* PyEnumDescriptor_FromDescriptor( 1101 const EnumDescriptor* enum_descriptor) { 1102 return descriptor::NewInternedDescriptor( 1103 &PyEnumDescriptor_Type, enum_descriptor, NULL); 1104 } 1105 1106 const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj) { 1107 if (!PyObject_TypeCheck(obj, &PyEnumDescriptor_Type)) { 1108 PyErr_SetString(PyExc_TypeError, "Not an EnumDescriptor"); 1109 return NULL; 1110 } 1111 return reinterpret_cast<const EnumDescriptor*>( 1112 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor); 1113 } 1114 1115 namespace enumvalue_descriptor { 1116 1117 // Unchecked accessor to the C++ pointer. 1118 static const EnumValueDescriptor* _GetDescriptor( 1119 PyBaseDescriptor *self) { 1120 return reinterpret_cast<const EnumValueDescriptor*>(self->descriptor); 1121 } 1122 1123 static PyObject* GetName(PyBaseDescriptor *self, void *closure) { 1124 return PyString_FromCppString(_GetDescriptor(self)->name()); 1125 } 1126 1127 static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) { 1128 return PyInt_FromLong(_GetDescriptor(self)->number()); 1129 } 1130 1131 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) { 1132 return PyInt_FromLong(_GetDescriptor(self)->index()); 1133 } 1134 1135 static PyObject* GetType(PyBaseDescriptor *self, void *closure) { 1136 return PyEnumDescriptor_FromDescriptor(_GetDescriptor(self)->type()); 1137 } 1138 1139 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) { 1140 const EnumValueOptions& options(_GetDescriptor(self)->options()); 1141 if (&options != &EnumValueOptions::default_instance()) { 1142 Py_RETURN_TRUE; 1143 } else { 1144 Py_RETURN_FALSE; 1145 } 1146 } 1147 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, 1148 void *closure) { 1149 return CheckCalledFromGeneratedFile("has_options"); 1150 } 1151 1152 static PyObject* GetOptions(PyBaseDescriptor *self) { 1153 return GetOrBuildOptions(_GetDescriptor(self)); 1154 } 1155 1156 static int SetOptions(PyBaseDescriptor *self, PyObject *value, 1157 void *closure) { 1158 return CheckCalledFromGeneratedFile("_options"); 1159 } 1160 1161 1162 static PyGetSetDef Getters[] = { 1163 { "name", (getter)GetName, NULL, "name"}, 1164 { "number", (getter)GetNumber, NULL, "number"}, 1165 { "index", (getter)GetIndex, NULL, "index"}, 1166 { "type", (getter)GetType, NULL, "index"}, 1167 1168 { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, 1169 { "_options", (getter)NULL, (setter)SetOptions, "Options"}, 1170 {NULL} 1171 }; 1172 1173 static PyMethodDef Methods[] = { 1174 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, 1175 {NULL} 1176 }; 1177 1178 } // namespace enumvalue_descriptor 1179 1180 PyTypeObject PyEnumValueDescriptor_Type = { 1181 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1182 FULL_MODULE_NAME ".EnumValueDescriptor", // tp_name 1183 sizeof(PyBaseDescriptor), // tp_basicsize 1184 0, // tp_itemsize 1185 0, // tp_dealloc 1186 0, // tp_print 1187 0, // tp_getattr 1188 0, // tp_setattr 1189 0, // tp_compare 1190 0, // tp_repr 1191 0, // tp_as_number 1192 0, // tp_as_sequence 1193 0, // tp_as_mapping 1194 0, // tp_hash 1195 0, // tp_call 1196 0, // tp_str 1197 0, // tp_getattro 1198 0, // tp_setattro 1199 0, // tp_as_buffer 1200 Py_TPFLAGS_DEFAULT, // tp_flags 1201 "A EnumValue Descriptor", // tp_doc 1202 0, // tp_traverse 1203 0, // tp_clear 1204 0, // tp_richcompare 1205 0, // tp_weaklistoffset 1206 0, // tp_iter 1207 0, // tp_iternext 1208 enumvalue_descriptor::Methods, // tp_methods 1209 0, // tp_members 1210 enumvalue_descriptor::Getters, // tp_getset 1211 &descriptor::PyBaseDescriptor_Type, // tp_base 1212 }; 1213 1214 PyObject* PyEnumValueDescriptor_FromDescriptor( 1215 const EnumValueDescriptor* enumvalue_descriptor) { 1216 return descriptor::NewInternedDescriptor( 1217 &PyEnumValueDescriptor_Type, enumvalue_descriptor, NULL); 1218 } 1219 1220 namespace file_descriptor { 1221 1222 // Unchecked accessor to the C++ pointer. 1223 static const FileDescriptor* _GetDescriptor(PyFileDescriptor *self) { 1224 return reinterpret_cast<const FileDescriptor*>(self->base.descriptor); 1225 } 1226 1227 static void Dealloc(PyFileDescriptor* self) { 1228 Py_XDECREF(self->serialized_pb); 1229 descriptor::Dealloc(&self->base); 1230 } 1231 1232 static PyObject* GetPool(PyFileDescriptor *self, void *closure) { 1233 PyObject* pool = reinterpret_cast<PyObject*>( 1234 GetDescriptorPool_FromPool(_GetDescriptor(self)->pool())); 1235 Py_XINCREF(pool); 1236 return pool; 1237 } 1238 1239 static PyObject* GetName(PyFileDescriptor *self, void *closure) { 1240 return PyString_FromCppString(_GetDescriptor(self)->name()); 1241 } 1242 1243 static PyObject* GetPackage(PyFileDescriptor *self, void *closure) { 1244 return PyString_FromCppString(_GetDescriptor(self)->package()); 1245 } 1246 1247 static PyObject* GetSerializedPb(PyFileDescriptor *self, void *closure) { 1248 PyObject *serialized_pb = self->serialized_pb; 1249 if (serialized_pb != NULL) { 1250 Py_INCREF(serialized_pb); 1251 return serialized_pb; 1252 } 1253 FileDescriptorProto file_proto; 1254 _GetDescriptor(self)->CopyTo(&file_proto); 1255 string contents; 1256 file_proto.SerializePartialToString(&contents); 1257 self->serialized_pb = PyBytes_FromStringAndSize( 1258 contents.c_str(), contents.size()); 1259 if (self->serialized_pb == NULL) { 1260 return NULL; 1261 } 1262 Py_INCREF(self->serialized_pb); 1263 return self->serialized_pb; 1264 } 1265 1266 static PyObject* GetMessageTypesByName(PyFileDescriptor* self, void *closure) { 1267 return NewFileMessageTypesByName(_GetDescriptor(self)); 1268 } 1269 1270 static PyObject* GetEnumTypesByName(PyFileDescriptor* self, void *closure) { 1271 return NewFileEnumTypesByName(_GetDescriptor(self)); 1272 } 1273 1274 static PyObject* GetExtensionsByName(PyFileDescriptor* self, void *closure) { 1275 return NewFileExtensionsByName(_GetDescriptor(self)); 1276 } 1277 1278 static PyObject* GetDependencies(PyFileDescriptor* self, void *closure) { 1279 return NewFileDependencies(_GetDescriptor(self)); 1280 } 1281 1282 static PyObject* GetPublicDependencies(PyFileDescriptor* self, void *closure) { 1283 return NewFilePublicDependencies(_GetDescriptor(self)); 1284 } 1285 1286 static PyObject* GetHasOptions(PyFileDescriptor *self, void *closure) { 1287 const FileOptions& options(_GetDescriptor(self)->options()); 1288 if (&options != &FileOptions::default_instance()) { 1289 Py_RETURN_TRUE; 1290 } else { 1291 Py_RETURN_FALSE; 1292 } 1293 } 1294 static int SetHasOptions(PyFileDescriptor *self, PyObject *value, 1295 void *closure) { 1296 return CheckCalledFromGeneratedFile("has_options"); 1297 } 1298 1299 static PyObject* GetOptions(PyFileDescriptor *self) { 1300 return GetOrBuildOptions(_GetDescriptor(self)); 1301 } 1302 1303 static int SetOptions(PyFileDescriptor *self, PyObject *value, 1304 void *closure) { 1305 return CheckCalledFromGeneratedFile("_options"); 1306 } 1307 1308 static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) { 1309 return PyString_InternFromString( 1310 FileDescriptor::SyntaxName(_GetDescriptor(self)->syntax())); 1311 } 1312 1313 static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) { 1314 return CopyToPythonProto<FileDescriptorProto>(_GetDescriptor(self), target); 1315 } 1316 1317 static PyGetSetDef Getters[] = { 1318 { "pool", (getter)GetPool, NULL, "pool"}, 1319 { "name", (getter)GetName, NULL, "name"}, 1320 { "package", (getter)GetPackage, NULL, "package"}, 1321 { "serialized_pb", (getter)GetSerializedPb}, 1322 { "message_types_by_name", (getter)GetMessageTypesByName, NULL, 1323 "Messages by name"}, 1324 { "enum_types_by_name", (getter)GetEnumTypesByName, NULL, "Enums by name"}, 1325 { "extensions_by_name", (getter)GetExtensionsByName, NULL, 1326 "Extensions by name"}, 1327 { "dependencies", (getter)GetDependencies, NULL, "Dependencies"}, 1328 { "public_dependencies", (getter)GetPublicDependencies, NULL, "Dependencies"}, 1329 1330 { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, 1331 { "_options", (getter)NULL, (setter)SetOptions, "Options"}, 1332 { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"}, 1333 {NULL} 1334 }; 1335 1336 static PyMethodDef Methods[] = { 1337 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, 1338 { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, 1339 {NULL} 1340 }; 1341 1342 } // namespace file_descriptor 1343 1344 PyTypeObject PyFileDescriptor_Type = { 1345 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1346 FULL_MODULE_NAME ".FileDescriptor", // tp_name 1347 sizeof(PyFileDescriptor), // tp_basicsize 1348 0, // tp_itemsize 1349 (destructor)file_descriptor::Dealloc, // tp_dealloc 1350 0, // tp_print 1351 0, // tp_getattr 1352 0, // tp_setattr 1353 0, // tp_compare 1354 0, // tp_repr 1355 0, // tp_as_number 1356 0, // tp_as_sequence 1357 0, // tp_as_mapping 1358 0, // tp_hash 1359 0, // tp_call 1360 0, // tp_str 1361 0, // tp_getattro 1362 0, // tp_setattro 1363 0, // tp_as_buffer 1364 Py_TPFLAGS_DEFAULT, // tp_flags 1365 "A File Descriptor", // tp_doc 1366 0, // tp_traverse 1367 0, // tp_clear 1368 0, // tp_richcompare 1369 0, // tp_weaklistoffset 1370 0, // tp_iter 1371 0, // tp_iternext 1372 file_descriptor::Methods, // tp_methods 1373 0, // tp_members 1374 file_descriptor::Getters, // tp_getset 1375 &descriptor::PyBaseDescriptor_Type, // tp_base 1376 0, // tp_dict 1377 0, // tp_descr_get 1378 0, // tp_descr_set 1379 0, // tp_dictoffset 1380 0, // tp_init 1381 0, // tp_alloc 1382 0, // tp_new 1383 PyObject_Del, // tp_free 1384 }; 1385 1386 PyObject* PyFileDescriptor_FromDescriptor( 1387 const FileDescriptor* file_descriptor) { 1388 return PyFileDescriptor_FromDescriptorWithSerializedPb(file_descriptor, 1389 NULL); 1390 } 1391 1392 PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb( 1393 const FileDescriptor* file_descriptor, PyObject *serialized_pb) { 1394 bool was_created; 1395 PyObject* py_descriptor = descriptor::NewInternedDescriptor( 1396 &PyFileDescriptor_Type, file_descriptor, &was_created); 1397 if (py_descriptor == NULL) { 1398 return NULL; 1399 } 1400 if (was_created) { 1401 PyFileDescriptor* cfile_descriptor = 1402 reinterpret_cast<PyFileDescriptor*>(py_descriptor); 1403 Py_XINCREF(serialized_pb); 1404 cfile_descriptor->serialized_pb = serialized_pb; 1405 } 1406 // TODO(amauryfa): In the case of a cached object, check that serialized_pb 1407 // is the same as before. 1408 1409 return py_descriptor; 1410 } 1411 1412 const FileDescriptor* PyFileDescriptor_AsDescriptor(PyObject* obj) { 1413 if (!PyObject_TypeCheck(obj, &PyFileDescriptor_Type)) { 1414 PyErr_SetString(PyExc_TypeError, "Not a FileDescriptor"); 1415 return NULL; 1416 } 1417 return reinterpret_cast<const FileDescriptor*>( 1418 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor); 1419 } 1420 1421 namespace oneof_descriptor { 1422 1423 // Unchecked accessor to the C++ pointer. 1424 static const OneofDescriptor* _GetDescriptor( 1425 PyBaseDescriptor *self) { 1426 return reinterpret_cast<const OneofDescriptor*>(self->descriptor); 1427 } 1428 1429 static PyObject* GetName(PyBaseDescriptor* self, void *closure) { 1430 return PyString_FromCppString(_GetDescriptor(self)->name()); 1431 } 1432 1433 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) { 1434 return PyString_FromCppString(_GetDescriptor(self)->full_name()); 1435 } 1436 1437 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) { 1438 return PyInt_FromLong(_GetDescriptor(self)->index()); 1439 } 1440 1441 static PyObject* GetFields(PyBaseDescriptor* self, void *closure) { 1442 return NewOneofFieldsSeq(_GetDescriptor(self)); 1443 } 1444 1445 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) { 1446 const Descriptor* containing_type = 1447 _GetDescriptor(self)->containing_type(); 1448 if (containing_type) { 1449 return PyMessageDescriptor_FromDescriptor(containing_type); 1450 } else { 1451 Py_RETURN_NONE; 1452 } 1453 } 1454 1455 static PyGetSetDef Getters[] = { 1456 { "name", (getter)GetName, NULL, "Name"}, 1457 { "full_name", (getter)GetFullName, NULL, "Full name"}, 1458 { "index", (getter)GetIndex, NULL, "Index"}, 1459 1460 { "containing_type", (getter)GetContainingType, NULL, "Containing type"}, 1461 { "fields", (getter)GetFields, NULL, "Fields"}, 1462 {NULL} 1463 }; 1464 1465 } // namespace oneof_descriptor 1466 1467 PyTypeObject PyOneofDescriptor_Type = { 1468 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1469 FULL_MODULE_NAME ".OneofDescriptor", // tp_name 1470 sizeof(PyBaseDescriptor), // tp_basicsize 1471 0, // tp_itemsize 1472 0, // tp_dealloc 1473 0, // tp_print 1474 0, // tp_getattr 1475 0, // tp_setattr 1476 0, // tp_compare 1477 0, // tp_repr 1478 0, // tp_as_number 1479 0, // tp_as_sequence 1480 0, // tp_as_mapping 1481 0, // tp_hash 1482 0, // tp_call 1483 0, // tp_str 1484 0, // tp_getattro 1485 0, // tp_setattro 1486 0, // tp_as_buffer 1487 Py_TPFLAGS_DEFAULT, // tp_flags 1488 "A Oneof Descriptor", // tp_doc 1489 0, // tp_traverse 1490 0, // tp_clear 1491 0, // tp_richcompare 1492 0, // tp_weaklistoffset 1493 0, // tp_iter 1494 0, // tp_iternext 1495 0, // tp_methods 1496 0, // tp_members 1497 oneof_descriptor::Getters, // tp_getset 1498 &descriptor::PyBaseDescriptor_Type, // tp_base 1499 }; 1500 1501 PyObject* PyOneofDescriptor_FromDescriptor( 1502 const OneofDescriptor* oneof_descriptor) { 1503 return descriptor::NewInternedDescriptor( 1504 &PyOneofDescriptor_Type, oneof_descriptor, NULL); 1505 } 1506 1507 // Add a enum values to a type dictionary. 1508 static bool AddEnumValues(PyTypeObject *type, 1509 const EnumDescriptor* enum_descriptor) { 1510 for (int i = 0; i < enum_descriptor->value_count(); ++i) { 1511 const EnumValueDescriptor* value = enum_descriptor->value(i); 1512 ScopedPyObjectPtr obj(PyInt_FromLong(value->number())); 1513 if (obj == NULL) { 1514 return false; 1515 } 1516 if (PyDict_SetItemString(type->tp_dict, value->name().c_str(), obj.get()) < 1517 0) { 1518 return false; 1519 } 1520 } 1521 return true; 1522 } 1523 1524 static bool AddIntConstant(PyTypeObject *type, const char* name, int value) { 1525 ScopedPyObjectPtr obj(PyInt_FromLong(value)); 1526 if (PyDict_SetItemString(type->tp_dict, name, obj.get()) < 0) { 1527 return false; 1528 } 1529 return true; 1530 } 1531 1532 1533 bool InitDescriptor() { 1534 if (PyType_Ready(&PyMessageDescriptor_Type) < 0) 1535 return false; 1536 1537 if (PyType_Ready(&PyFieldDescriptor_Type) < 0) 1538 return false; 1539 1540 if (!AddEnumValues(&PyFieldDescriptor_Type, 1541 FieldDescriptorProto::Label_descriptor())) { 1542 return false; 1543 } 1544 if (!AddEnumValues(&PyFieldDescriptor_Type, 1545 FieldDescriptorProto::Type_descriptor())) { 1546 return false; 1547 } 1548 #define ADD_FIELDDESC_CONSTANT(NAME) AddIntConstant( \ 1549 &PyFieldDescriptor_Type, #NAME, FieldDescriptor::NAME) 1550 if (!ADD_FIELDDESC_CONSTANT(CPPTYPE_INT32) || 1551 !ADD_FIELDDESC_CONSTANT(CPPTYPE_INT64) || 1552 !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT32) || 1553 !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT64) || 1554 !ADD_FIELDDESC_CONSTANT(CPPTYPE_DOUBLE) || 1555 !ADD_FIELDDESC_CONSTANT(CPPTYPE_FLOAT) || 1556 !ADD_FIELDDESC_CONSTANT(CPPTYPE_BOOL) || 1557 !ADD_FIELDDESC_CONSTANT(CPPTYPE_ENUM) || 1558 !ADD_FIELDDESC_CONSTANT(CPPTYPE_STRING) || 1559 !ADD_FIELDDESC_CONSTANT(CPPTYPE_MESSAGE)) { 1560 return false; 1561 } 1562 #undef ADD_FIELDDESC_CONSTANT 1563 1564 if (PyType_Ready(&PyEnumDescriptor_Type) < 0) 1565 return false; 1566 1567 if (PyType_Ready(&PyEnumValueDescriptor_Type) < 0) 1568 return false; 1569 1570 if (PyType_Ready(&PyFileDescriptor_Type) < 0) 1571 return false; 1572 1573 if (PyType_Ready(&PyOneofDescriptor_Type) < 0) 1574 return false; 1575 1576 if (!InitDescriptorMappingTypes()) 1577 return false; 1578 1579 return true; 1580 } 1581 1582 } // namespace python 1583 } // namespace protobuf 1584 } // namespace google 1585