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@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 61namespace google { 62namespace protobuf { 63namespace 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. 71hash_map<const void*, PyObject*> interned_descriptors; 72 73PyObject* 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. 94bool _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. 138static 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. 159template<class DescriptorClass> 160const FileDescriptor* GetFileDescriptor(const DescriptorClass* descriptor) { 161 return descriptor->file(); 162} 163template<> 164const FileDescriptor* GetFileDescriptor(const FileDescriptor* descriptor) { 165 return descriptor; 166} 167template<> 168const FileDescriptor* GetFileDescriptor(const EnumValueDescriptor* descriptor) { 169 return descriptor->type()->file(); 170} 171template<> 172const 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. 183template<class DescriptorClass> 184static 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. 259template<class DescriptorProtoClass, class DescriptorClass> 260static 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. 279typedef 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. 292typedef 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 301namespace 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. 309template<class DescriptorClass> 310PyObject* 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 358static 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 365static PyGetSetDef Getters[] = { 366 {NULL} 367}; 368 369PyTypeObject 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 404const 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 412namespace message_descriptor { 413 414// Unchecked accessor to the C++ pointer. 415static const Descriptor* _GetDescriptor(PyBaseDescriptor* self) { 416 return reinterpret_cast<const Descriptor*>(self->descriptor); 417} 418 419static PyObject* GetName(PyBaseDescriptor* self, void *closure) { 420 return PyString_FromCppString(_GetDescriptor(self)->name()); 421} 422 423static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) { 424 return PyString_FromCppString(_GetDescriptor(self)->full_name()); 425} 426 427static PyObject* GetFile(PyBaseDescriptor *self, void *closure) { 428 return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file()); 429} 430 431static 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 444static PyObject* GetFieldsByName(PyBaseDescriptor* self, void *closure) { 445 return NewMessageFieldsByName(_GetDescriptor(self)); 446} 447 448static PyObject* GetFieldsByCamelcaseName(PyBaseDescriptor* self, 449 void *closure) { 450 return NewMessageFieldsByCamelcaseName(_GetDescriptor(self)); 451} 452 453static PyObject* GetFieldsByNumber(PyBaseDescriptor* self, void *closure) { 454 return NewMessageFieldsByNumber(_GetDescriptor(self)); 455} 456 457static PyObject* GetFieldsSeq(PyBaseDescriptor* self, void *closure) { 458 return NewMessageFieldsSeq(_GetDescriptor(self)); 459} 460 461static PyObject* GetNestedTypesByName(PyBaseDescriptor* self, void *closure) { 462 return NewMessageNestedTypesByName(_GetDescriptor(self)); 463} 464 465static PyObject* GetNestedTypesSeq(PyBaseDescriptor* self, void *closure) { 466 return NewMessageNestedTypesSeq(_GetDescriptor(self)); 467} 468 469static PyObject* GetExtensionsByName(PyBaseDescriptor* self, void *closure) { 470 return NewMessageExtensionsByName(_GetDescriptor(self)); 471} 472 473static PyObject* GetExtensions(PyBaseDescriptor* self, void *closure) { 474 return NewMessageExtensionsSeq(_GetDescriptor(self)); 475} 476 477static PyObject* GetEnumsSeq(PyBaseDescriptor* self, void *closure) { 478 return NewMessageEnumsSeq(_GetDescriptor(self)); 479} 480 481static PyObject* GetEnumTypesByName(PyBaseDescriptor* self, void *closure) { 482 return NewMessageEnumsByName(_GetDescriptor(self)); 483} 484 485static PyObject* GetEnumValuesByName(PyBaseDescriptor* self, void *closure) { 486 return NewMessageEnumValuesByName(_GetDescriptor(self)); 487} 488 489static PyObject* GetOneofsByName(PyBaseDescriptor* self, void *closure) { 490 return NewMessageOneofsByName(_GetDescriptor(self)); 491} 492 493static PyObject* GetOneofsSeq(PyBaseDescriptor* self, void *closure) { 494 return NewMessageOneofsSeq(_GetDescriptor(self)); 495} 496 497static 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 505static 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 519static 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 529static int SetContainingType(PyBaseDescriptor *self, PyObject *value, 530 void *closure) { 531 return CheckCalledFromGeneratedFile("containing_type"); 532} 533 534static 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} 542static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, 543 void *closure) { 544 return CheckCalledFromGeneratedFile("has_options"); 545} 546 547static PyObject* GetOptions(PyBaseDescriptor *self) { 548 return GetOrBuildOptions(_GetDescriptor(self)); 549} 550 551static int SetOptions(PyBaseDescriptor *self, PyObject *value, 552 void *closure) { 553 return CheckCalledFromGeneratedFile("_options"); 554} 555 556static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { 557 return CopyToPythonProto<DescriptorProto>(_GetDescriptor(self), target); 558} 559 560static 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 580static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) { 581 return PyString_InternFromString( 582 FileDescriptor::SyntaxName(_GetDescriptor(self)->file()->syntax())); 583} 584 585static 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 619static 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 628PyTypeObject 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 662PyObject* PyMessageDescriptor_FromDescriptor( 663 const Descriptor* message_descriptor) { 664 return descriptor::NewInternedDescriptor( 665 &PyMessageDescriptor_Type, message_descriptor, NULL); 666} 667 668const 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 677namespace field_descriptor { 678 679// Unchecked accessor to the C++ pointer. 680static const FieldDescriptor* _GetDescriptor( 681 PyBaseDescriptor *self) { 682 return reinterpret_cast<const FieldDescriptor*>(self->descriptor); 683} 684 685static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) { 686 return PyString_FromCppString(_GetDescriptor(self)->full_name()); 687} 688 689static PyObject* GetName(PyBaseDescriptor *self, void *closure) { 690 return PyString_FromCppString(_GetDescriptor(self)->name()); 691} 692 693static PyObject* GetCamelcaseName(PyBaseDescriptor* self, void *closure) { 694 return PyString_FromCppString(_GetDescriptor(self)->camelcase_name()); 695} 696 697static PyObject* GetType(PyBaseDescriptor *self, void *closure) { 698 return PyInt_FromLong(_GetDescriptor(self)->type()); 699} 700 701static PyObject* GetCppType(PyBaseDescriptor *self, void *closure) { 702 return PyInt_FromLong(_GetDescriptor(self)->cpp_type()); 703} 704 705static PyObject* GetLabel(PyBaseDescriptor *self, void *closure) { 706 return PyInt_FromLong(_GetDescriptor(self)->label()); 707} 708 709static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) { 710 return PyInt_FromLong(_GetDescriptor(self)->number()); 711} 712 713static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) { 714 return PyInt_FromLong(_GetDescriptor(self)->index()); 715} 716 717static PyObject* GetID(PyBaseDescriptor *self, void *closure) { 718 return PyLong_FromVoidPtr(self); 719} 720 721static PyObject* IsExtension(PyBaseDescriptor *self, void *closure) { 722 return PyBool_FromLong(_GetDescriptor(self)->is_extension()); 723} 724 725static PyObject* HasDefaultValue(PyBaseDescriptor *self, void *closure) { 726 return PyBool_FromLong(_GetDescriptor(self)->has_default_value()); 727} 728 729static 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 787static PyObject* GetCDescriptor(PyObject *self, void *closure) { 788 Py_INCREF(self); 789 return self; 790} 791 792static 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 801static int SetEnumType(PyBaseDescriptor *self, PyObject *value, void *closure) { 802 return CheckCalledFromGeneratedFile("enum_type"); 803} 804 805static 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 814static int SetMessageType(PyBaseDescriptor *self, PyObject *value, 815 void *closure) { 816 return CheckCalledFromGeneratedFile("message_type"); 817} 818 819static 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 829static int SetContainingType(PyBaseDescriptor *self, PyObject *value, 830 void *closure) { 831 return CheckCalledFromGeneratedFile("containing_type"); 832} 833 834static 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 844static 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 854static int SetContainingOneof(PyBaseDescriptor *self, PyObject *value, 855 void *closure) { 856 return CheckCalledFromGeneratedFile("containing_oneof"); 857} 858 859static 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} 867static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, 868 void *closure) { 869 return CheckCalledFromGeneratedFile("has_options"); 870} 871 872static PyObject* GetOptions(PyBaseDescriptor *self) { 873 return GetOrBuildOptions(_GetDescriptor(self)); 874} 875 876static int SetOptions(PyBaseDescriptor *self, PyObject *value, 877 void *closure) { 878 return CheckCalledFromGeneratedFile("_options"); 879} 880 881 882static 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 911static PyMethodDef Methods[] = { 912 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, 913 {NULL} 914}; 915 916} // namespace field_descriptor 917 918PyTypeObject 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 952PyObject* PyFieldDescriptor_FromDescriptor( 953 const FieldDescriptor* field_descriptor) { 954 return descriptor::NewInternedDescriptor( 955 &PyFieldDescriptor_Type, field_descriptor, NULL); 956} 957 958const 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 967namespace enum_descriptor { 968 969// Unchecked accessor to the C++ pointer. 970static const EnumDescriptor* _GetDescriptor( 971 PyBaseDescriptor *self) { 972 return reinterpret_cast<const EnumDescriptor*>(self->descriptor); 973} 974 975static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) { 976 return PyString_FromCppString(_GetDescriptor(self)->full_name()); 977} 978 979static PyObject* GetName(PyBaseDescriptor *self, void *closure) { 980 return PyString_FromCppString(_GetDescriptor(self)->name()); 981} 982 983static PyObject* GetFile(PyBaseDescriptor *self, void *closure) { 984 return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file()); 985} 986 987static PyObject* GetEnumvaluesByName(PyBaseDescriptor* self, void *closure) { 988 return NewEnumValuesByName(_GetDescriptor(self)); 989} 990 991static PyObject* GetEnumvaluesByNumber(PyBaseDescriptor* self, void *closure) { 992 return NewEnumValuesByNumber(_GetDescriptor(self)); 993} 994 995static PyObject* GetEnumvaluesSeq(PyBaseDescriptor* self, void *closure) { 996 return NewEnumValuesSeq(_GetDescriptor(self)); 997} 998 999static 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 1009static int SetContainingType(PyBaseDescriptor *self, PyObject *value, 1010 void *closure) { 1011 return CheckCalledFromGeneratedFile("containing_type"); 1012} 1013 1014 1015static 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} 1023static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, 1024 void *closure) { 1025 return CheckCalledFromGeneratedFile("has_options"); 1026} 1027 1028static PyObject* GetOptions(PyBaseDescriptor *self) { 1029 return GetOrBuildOptions(_GetDescriptor(self)); 1030} 1031 1032static int SetOptions(PyBaseDescriptor *self, PyObject *value, 1033 void *closure) { 1034 return CheckCalledFromGeneratedFile("_options"); 1035} 1036 1037static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { 1038 return CopyToPythonProto<EnumDescriptorProto>(_GetDescriptor(self), target); 1039} 1040 1041static PyMethodDef Methods[] = { 1042 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, 1043 { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, 1044 {NULL} 1045}; 1046 1047static 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 1066PyTypeObject 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 1100PyObject* PyEnumDescriptor_FromDescriptor( 1101 const EnumDescriptor* enum_descriptor) { 1102 return descriptor::NewInternedDescriptor( 1103 &PyEnumDescriptor_Type, enum_descriptor, NULL); 1104} 1105 1106const 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 1115namespace enumvalue_descriptor { 1116 1117// Unchecked accessor to the C++ pointer. 1118static const EnumValueDescriptor* _GetDescriptor( 1119 PyBaseDescriptor *self) { 1120 return reinterpret_cast<const EnumValueDescriptor*>(self->descriptor); 1121} 1122 1123static PyObject* GetName(PyBaseDescriptor *self, void *closure) { 1124 return PyString_FromCppString(_GetDescriptor(self)->name()); 1125} 1126 1127static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) { 1128 return PyInt_FromLong(_GetDescriptor(self)->number()); 1129} 1130 1131static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) { 1132 return PyInt_FromLong(_GetDescriptor(self)->index()); 1133} 1134 1135static PyObject* GetType(PyBaseDescriptor *self, void *closure) { 1136 return PyEnumDescriptor_FromDescriptor(_GetDescriptor(self)->type()); 1137} 1138 1139static 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} 1147static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, 1148 void *closure) { 1149 return CheckCalledFromGeneratedFile("has_options"); 1150} 1151 1152static PyObject* GetOptions(PyBaseDescriptor *self) { 1153 return GetOrBuildOptions(_GetDescriptor(self)); 1154} 1155 1156static int SetOptions(PyBaseDescriptor *self, PyObject *value, 1157 void *closure) { 1158 return CheckCalledFromGeneratedFile("_options"); 1159} 1160 1161 1162static 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 1173static PyMethodDef Methods[] = { 1174 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, 1175 {NULL} 1176}; 1177 1178} // namespace enumvalue_descriptor 1179 1180PyTypeObject 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 1214PyObject* PyEnumValueDescriptor_FromDescriptor( 1215 const EnumValueDescriptor* enumvalue_descriptor) { 1216 return descriptor::NewInternedDescriptor( 1217 &PyEnumValueDescriptor_Type, enumvalue_descriptor, NULL); 1218} 1219 1220namespace file_descriptor { 1221 1222// Unchecked accessor to the C++ pointer. 1223static const FileDescriptor* _GetDescriptor(PyFileDescriptor *self) { 1224 return reinterpret_cast<const FileDescriptor*>(self->base.descriptor); 1225} 1226 1227static void Dealloc(PyFileDescriptor* self) { 1228 Py_XDECREF(self->serialized_pb); 1229 descriptor::Dealloc(&self->base); 1230} 1231 1232static 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 1239static PyObject* GetName(PyFileDescriptor *self, void *closure) { 1240 return PyString_FromCppString(_GetDescriptor(self)->name()); 1241} 1242 1243static PyObject* GetPackage(PyFileDescriptor *self, void *closure) { 1244 return PyString_FromCppString(_GetDescriptor(self)->package()); 1245} 1246 1247static 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 1266static PyObject* GetMessageTypesByName(PyFileDescriptor* self, void *closure) { 1267 return NewFileMessageTypesByName(_GetDescriptor(self)); 1268} 1269 1270static PyObject* GetEnumTypesByName(PyFileDescriptor* self, void *closure) { 1271 return NewFileEnumTypesByName(_GetDescriptor(self)); 1272} 1273 1274static PyObject* GetExtensionsByName(PyFileDescriptor* self, void *closure) { 1275 return NewFileExtensionsByName(_GetDescriptor(self)); 1276} 1277 1278static PyObject* GetDependencies(PyFileDescriptor* self, void *closure) { 1279 return NewFileDependencies(_GetDescriptor(self)); 1280} 1281 1282static PyObject* GetPublicDependencies(PyFileDescriptor* self, void *closure) { 1283 return NewFilePublicDependencies(_GetDescriptor(self)); 1284} 1285 1286static 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} 1294static int SetHasOptions(PyFileDescriptor *self, PyObject *value, 1295 void *closure) { 1296 return CheckCalledFromGeneratedFile("has_options"); 1297} 1298 1299static PyObject* GetOptions(PyFileDescriptor *self) { 1300 return GetOrBuildOptions(_GetDescriptor(self)); 1301} 1302 1303static int SetOptions(PyFileDescriptor *self, PyObject *value, 1304 void *closure) { 1305 return CheckCalledFromGeneratedFile("_options"); 1306} 1307 1308static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) { 1309 return PyString_InternFromString( 1310 FileDescriptor::SyntaxName(_GetDescriptor(self)->syntax())); 1311} 1312 1313static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) { 1314 return CopyToPythonProto<FileDescriptorProto>(_GetDescriptor(self), target); 1315} 1316 1317static 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 1336static PyMethodDef Methods[] = { 1337 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, 1338 { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, 1339 {NULL} 1340}; 1341 1342} // namespace file_descriptor 1343 1344PyTypeObject 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 1386PyObject* PyFileDescriptor_FromDescriptor( 1387 const FileDescriptor* file_descriptor) { 1388 return PyFileDescriptor_FromDescriptorWithSerializedPb(file_descriptor, 1389 NULL); 1390} 1391 1392PyObject* 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 1412const 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 1421namespace oneof_descriptor { 1422 1423// Unchecked accessor to the C++ pointer. 1424static const OneofDescriptor* _GetDescriptor( 1425 PyBaseDescriptor *self) { 1426 return reinterpret_cast<const OneofDescriptor*>(self->descriptor); 1427} 1428 1429static PyObject* GetName(PyBaseDescriptor* self, void *closure) { 1430 return PyString_FromCppString(_GetDescriptor(self)->name()); 1431} 1432 1433static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) { 1434 return PyString_FromCppString(_GetDescriptor(self)->full_name()); 1435} 1436 1437static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) { 1438 return PyInt_FromLong(_GetDescriptor(self)->index()); 1439} 1440 1441static PyObject* GetFields(PyBaseDescriptor* self, void *closure) { 1442 return NewOneofFieldsSeq(_GetDescriptor(self)); 1443} 1444 1445static 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 1455static 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 1467PyTypeObject 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 1501PyObject* 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. 1508static 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 1524static 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 1533bool 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