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: anuraag@google.com (Anuraag Agrawal) 32// Author: tibell@google.com (Johan Tibell) 33 34#include <google/protobuf/pyext/message.h> 35 36#include <memory> 37#ifndef _SHARED_PTR_H 38#include <google/protobuf/stubs/shared_ptr.h> 39#endif 40#include <string> 41#include <vector> 42 43#ifndef PyVarObject_HEAD_INIT 44#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, 45#endif 46#ifndef Py_TYPE 47#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) 48#endif 49#include <google/protobuf/descriptor.pb.h> 50#include <google/protobuf/stubs/common.h> 51#include <google/protobuf/io/coded_stream.h> 52#include <google/protobuf/descriptor.h> 53#include <google/protobuf/dynamic_message.h> 54#include <google/protobuf/message.h> 55#include <google/protobuf/text_format.h> 56#include <google/protobuf/pyext/descriptor.h> 57#include <google/protobuf/pyext/extension_dict.h> 58#include <google/protobuf/pyext/repeated_composite_container.h> 59#include <google/protobuf/pyext/repeated_scalar_container.h> 60#include <google/protobuf/pyext/scoped_pyobject_ptr.h> 61 62#if PY_MAJOR_VERSION >= 3 63 #define PyInt_Check PyLong_Check 64 #define PyInt_AsLong PyLong_AsLong 65 #define PyInt_FromLong PyLong_FromLong 66 #define PyInt_FromSize_t PyLong_FromSize_t 67 #define PyString_Check PyUnicode_Check 68 #define PyString_FromString PyUnicode_FromString 69 #define PyString_FromStringAndSize PyUnicode_FromStringAndSize 70 #if PY_VERSION_HEX < 0x03030000 71 #error "Python 3.0 - 3.2 are not supported." 72 #else 73 #define PyString_AsString(ob) \ 74 (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AS_STRING(ob)) 75 #endif 76#endif 77 78namespace google { 79namespace protobuf { 80namespace python { 81 82// Forward declarations 83namespace cmessage { 84static PyObject* GetDescriptor(CMessage* self, PyObject* name); 85static string GetMessageName(CMessage* self); 86int InternalReleaseFieldByDescriptor( 87 const google::protobuf::FieldDescriptor* field_descriptor, 88 PyObject* composite_field, 89 google::protobuf::Message* parent_message); 90} // namespace cmessage 91 92// --------------------------------------------------------------------- 93// Visiting the composite children of a CMessage 94 95struct ChildVisitor { 96 // Returns 0 on success, -1 on failure. 97 int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) { 98 return 0; 99 } 100 101 // Returns 0 on success, -1 on failure. 102 int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) { 103 return 0; 104 } 105 106 // Returns 0 on success, -1 on failure. 107 int VisitCMessage(CMessage* cmessage, 108 const google::protobuf::FieldDescriptor* field_descriptor) { 109 return 0; 110 } 111}; 112 113// Apply a function to a composite field. Does nothing if child is of 114// non-composite type. 115template<class Visitor> 116static int VisitCompositeField(const FieldDescriptor* descriptor, 117 PyObject* child, 118 Visitor visitor) { 119 if (descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) { 120 if (descriptor->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) { 121 RepeatedCompositeContainer* container = 122 reinterpret_cast<RepeatedCompositeContainer*>(child); 123 if (visitor.VisitRepeatedCompositeContainer(container) == -1) 124 return -1; 125 } else { 126 RepeatedScalarContainer* container = 127 reinterpret_cast<RepeatedScalarContainer*>(child); 128 if (visitor.VisitRepeatedScalarContainer(container) == -1) 129 return -1; 130 } 131 } else if (descriptor->cpp_type() == 132 google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) { 133 CMessage* cmsg = reinterpret_cast<CMessage*>(child); 134 if (visitor.VisitCMessage(cmsg, descriptor) == -1) 135 return -1; 136 } 137 // The ExtensionDict might contain non-composite fields, which we 138 // skip here. 139 return 0; 140} 141 142// Visit each composite field and extension field of this CMessage. 143// Returns -1 on error and 0 on success. 144template<class Visitor> 145int ForEachCompositeField(CMessage* self, Visitor visitor) { 146 Py_ssize_t pos = 0; 147 PyObject* key; 148 PyObject* field; 149 150 // Visit normal fields. 151 while (PyDict_Next(self->composite_fields, &pos, &key, &field)) { 152 PyObject* cdescriptor = cmessage::GetDescriptor(self, key); 153 if (cdescriptor != NULL) { 154 const google::protobuf::FieldDescriptor* descriptor = 155 reinterpret_cast<CFieldDescriptor*>(cdescriptor)->descriptor; 156 if (VisitCompositeField(descriptor, field, visitor) == -1) 157 return -1; 158 } 159 } 160 161 // Visit extension fields. 162 if (self->extensions != NULL) { 163 while (PyDict_Next(self->extensions->values, &pos, &key, &field)) { 164 CFieldDescriptor* cdescriptor = 165 extension_dict::InternalGetCDescriptorFromExtension(key); 166 if (cdescriptor == NULL) 167 return -1; 168 if (VisitCompositeField(cdescriptor->descriptor, field, visitor) == -1) 169 return -1; 170 } 171 } 172 173 return 0; 174} 175 176// --------------------------------------------------------------------- 177 178// Constants used for integer type range checking. 179PyObject* kPythonZero; 180PyObject* kint32min_py; 181PyObject* kint32max_py; 182PyObject* kuint32max_py; 183PyObject* kint64min_py; 184PyObject* kint64max_py; 185PyObject* kuint64max_py; 186 187PyObject* EnumTypeWrapper_class; 188PyObject* EncodeError_class; 189PyObject* DecodeError_class; 190PyObject* PickleError_class; 191 192// Constant PyString values used for GetAttr/GetItem. 193static PyObject* kDESCRIPTOR; 194static PyObject* k__descriptors; 195static PyObject* kfull_name; 196static PyObject* kname; 197static PyObject* kmessage_type; 198static PyObject* kis_extendable; 199static PyObject* kextensions_by_name; 200static PyObject* k_extensions_by_name; 201static PyObject* k_extensions_by_number; 202static PyObject* k_concrete_class; 203static PyObject* kfields_by_name; 204 205static CDescriptorPool* descriptor_pool; 206 207/* Is 64bit */ 208void FormatTypeError(PyObject* arg, char* expected_types) { 209 PyObject* repr = PyObject_Repr(arg); 210 if (repr) { 211 PyErr_Format(PyExc_TypeError, 212 "%.100s has type %.100s, but expected one of: %s", 213 PyString_AsString(repr), 214 Py_TYPE(arg)->tp_name, 215 expected_types); 216 Py_DECREF(repr); 217 } 218} 219 220template<class T> 221bool CheckAndGetInteger( 222 PyObject* arg, T* value, PyObject* min, PyObject* max) { 223 bool is_long = PyLong_Check(arg); 224#if PY_MAJOR_VERSION < 3 225 if (!PyInt_Check(arg) && !is_long) { 226 FormatTypeError(arg, "int, long"); 227 return false; 228 } 229 if (PyObject_Compare(min, arg) > 0 || PyObject_Compare(max, arg) < 0) { 230#else 231 if (!is_long) { 232 FormatTypeError(arg, "int"); 233 return false; 234 } 235 if (PyObject_RichCompareBool(min, arg, Py_LE) != 1 || 236 PyObject_RichCompareBool(max, arg, Py_GE) != 1) { 237#endif 238 PyObject *s = PyObject_Str(arg); 239 if (s) { 240 PyErr_Format(PyExc_ValueError, 241 "Value out of range: %s", 242 PyString_AsString(s)); 243 Py_DECREF(s); 244 } 245 return false; 246 } 247#if PY_MAJOR_VERSION < 3 248 if (!is_long) { 249 *value = static_cast<T>(PyInt_AsLong(arg)); 250 } else // NOLINT 251#endif 252 { 253 if (min == kPythonZero) { 254 *value = static_cast<T>(PyLong_AsUnsignedLongLong(arg)); 255 } else { 256 *value = static_cast<T>(PyLong_AsLongLong(arg)); 257 } 258 } 259 return true; 260} 261 262// These are referenced by repeated_scalar_container, and must 263// be explicitly instantiated. 264template bool CheckAndGetInteger<int32>( 265 PyObject*, int32*, PyObject*, PyObject*); 266template bool CheckAndGetInteger<int64>( 267 PyObject*, int64*, PyObject*, PyObject*); 268template bool CheckAndGetInteger<uint32>( 269 PyObject*, uint32*, PyObject*, PyObject*); 270template bool CheckAndGetInteger<uint64>( 271 PyObject*, uint64*, PyObject*, PyObject*); 272 273bool CheckAndGetDouble(PyObject* arg, double* value) { 274 if (!PyInt_Check(arg) && !PyLong_Check(arg) && 275 !PyFloat_Check(arg)) { 276 FormatTypeError(arg, "int, long, float"); 277 return false; 278 } 279 *value = PyFloat_AsDouble(arg); 280 return true; 281} 282 283bool CheckAndGetFloat(PyObject* arg, float* value) { 284 double double_value; 285 if (!CheckAndGetDouble(arg, &double_value)) { 286 return false; 287 } 288 *value = static_cast<float>(double_value); 289 return true; 290} 291 292bool CheckAndGetBool(PyObject* arg, bool* value) { 293 if (!PyInt_Check(arg) && !PyBool_Check(arg) && !PyLong_Check(arg)) { 294 FormatTypeError(arg, "int, long, bool"); 295 return false; 296 } 297 *value = static_cast<bool>(PyInt_AsLong(arg)); 298 return true; 299} 300 301bool CheckAndSetString( 302 PyObject* arg, google::protobuf::Message* message, 303 const google::protobuf::FieldDescriptor* descriptor, 304 const google::protobuf::Reflection* reflection, 305 bool append, 306 int index) { 307 GOOGLE_DCHECK(descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING || 308 descriptor->type() == google::protobuf::FieldDescriptor::TYPE_BYTES); 309 if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) { 310 if (!PyBytes_Check(arg) && !PyUnicode_Check(arg)) { 311 FormatTypeError(arg, "bytes, unicode"); 312 return false; 313 } 314 315 if (PyBytes_Check(arg)) { 316 PyObject* unicode = PyUnicode_FromEncodedObject(arg, "ascii", NULL); 317 if (unicode == NULL) { 318 PyObject* repr = PyObject_Repr(arg); 319 PyErr_Format(PyExc_ValueError, 320 "%s has type str, but isn't in 7-bit ASCII " 321 "encoding. Non-ASCII strings must be converted to " 322 "unicode objects before being added.", 323 PyString_AsString(repr)); 324 Py_DECREF(repr); 325 return false; 326 } else { 327 Py_DECREF(unicode); 328 } 329 } 330 } else if (!PyBytes_Check(arg)) { 331 FormatTypeError(arg, "bytes"); 332 return false; 333 } 334 335 PyObject* encoded_string = NULL; 336 if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) { 337 if (PyBytes_Check(arg)) { 338#if PY_MAJOR_VERSION < 3 339 encoded_string = PyString_AsEncodedObject(arg, "utf-8", NULL); 340#else 341 encoded_string = arg; // Already encoded. 342 Py_INCREF(encoded_string); 343#endif 344 } else { 345 encoded_string = PyUnicode_AsEncodedObject(arg, "utf-8", NULL); 346 } 347 } else { 348 // In this case field type is "bytes". 349 encoded_string = arg; 350 Py_INCREF(encoded_string); 351 } 352 353 if (encoded_string == NULL) { 354 return false; 355 } 356 357 char* value; 358 Py_ssize_t value_len; 359 if (PyBytes_AsStringAndSize(encoded_string, &value, &value_len) < 0) { 360 Py_DECREF(encoded_string); 361 return false; 362 } 363 364 string value_string(value, value_len); 365 if (append) { 366 reflection->AddString(message, descriptor, value_string); 367 } else if (index < 0) { 368 reflection->SetString(message, descriptor, value_string); 369 } else { 370 reflection->SetRepeatedString(message, descriptor, index, value_string); 371 } 372 Py_DECREF(encoded_string); 373 return true; 374} 375 376PyObject* ToStringObject( 377 const google::protobuf::FieldDescriptor* descriptor, string value) { 378 if (descriptor->type() != google::protobuf::FieldDescriptor::TYPE_STRING) { 379 return PyBytes_FromStringAndSize(value.c_str(), value.length()); 380 } 381 382 PyObject* result = PyUnicode_DecodeUTF8(value.c_str(), value.length(), NULL); 383 // If the string can't be decoded in UTF-8, just return a string object that 384 // contains the raw bytes. This can't happen if the value was assigned using 385 // the members of the Python message object, but can happen if the values were 386 // parsed from the wire (binary). 387 if (result == NULL) { 388 PyErr_Clear(); 389 result = PyBytes_FromStringAndSize(value.c_str(), value.length()); 390 } 391 return result; 392} 393 394google::protobuf::DynamicMessageFactory* global_message_factory; 395 396namespace cmessage { 397 398static int MaybeReleaseOverlappingOneofField( 399 CMessage* cmessage, 400 const google::protobuf::FieldDescriptor* field) { 401#ifdef GOOGLE_PROTOBUF_HAS_ONEOF 402 google::protobuf::Message* message = cmessage->message; 403 const google::protobuf::Reflection* reflection = message->GetReflection(); 404 if (!field->containing_oneof() || 405 !reflection->HasOneof(*message, field->containing_oneof()) || 406 reflection->HasField(*message, field)) { 407 // No other field in this oneof, no need to release. 408 return 0; 409 } 410 411 const OneofDescriptor* oneof = field->containing_oneof(); 412 const FieldDescriptor* existing_field = 413 reflection->GetOneofFieldDescriptor(*message, oneof); 414 if (existing_field->cpp_type() != google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) { 415 // Non-message fields don't need to be released. 416 return 0; 417 } 418 const char* field_name = existing_field->name().c_str(); 419 PyObject* child_message = PyDict_GetItemString( 420 cmessage->composite_fields, field_name); 421 if (child_message == NULL) { 422 // No python reference to this field so no need to release. 423 return 0; 424 } 425 426 if (InternalReleaseFieldByDescriptor( 427 existing_field, child_message, message) < 0) { 428 return -1; 429 } 430 return PyDict_DelItemString(cmessage->composite_fields, field_name); 431#else 432 return 0; 433#endif 434} 435 436// --------------------------------------------------------------------- 437// Making a message writable 438 439static google::protobuf::Message* GetMutableMessage( 440 CMessage* parent, 441 const google::protobuf::FieldDescriptor* parent_field) { 442 google::protobuf::Message* parent_message = parent->message; 443 const google::protobuf::Reflection* reflection = parent_message->GetReflection(); 444 if (MaybeReleaseOverlappingOneofField(parent, parent_field) < 0) { 445 return NULL; 446 } 447 return reflection->MutableMessage( 448 parent_message, parent_field, global_message_factory); 449} 450 451struct FixupMessageReference : public ChildVisitor { 452 // message must outlive this object. 453 explicit FixupMessageReference(google::protobuf::Message* message) : 454 message_(message) {} 455 456 int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) { 457 container->message = message_; 458 return 0; 459 } 460 461 int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) { 462 container->message = message_; 463 return 0; 464 } 465 466 private: 467 google::protobuf::Message* message_; 468}; 469 470int AssureWritable(CMessage* self) { 471 if (self == NULL || !self->read_only) { 472 return 0; 473 } 474 475 if (self->parent == NULL) { 476 // If parent is NULL but we are trying to modify a read-only message, this 477 // is a reference to a constant default instance that needs to be replaced 478 // with a mutable top-level message. 479 const Message* prototype = global_message_factory->GetPrototype( 480 self->message->GetDescriptor()); 481 self->message = prototype->New(); 482 self->owner.reset(self->message); 483 } else { 484 // Otherwise, we need a mutable child message. 485 if (AssureWritable(self->parent) == -1) 486 return -1; 487 488 // Make self->message writable. 489 google::protobuf::Message* parent_message = self->parent->message; 490 google::protobuf::Message* mutable_message = GetMutableMessage( 491 self->parent, 492 self->parent_field->descriptor); 493 if (mutable_message == NULL) { 494 return -1; 495 } 496 self->message = mutable_message; 497 } 498 self->read_only = false; 499 500 // When a CMessage is made writable its Message pointer is updated 501 // to point to a new mutable Message. When that happens we need to 502 // update any references to the old, read-only CMessage. There are 503 // three places such references occur: RepeatedScalarContainer, 504 // RepeatedCompositeContainer, and ExtensionDict. 505 if (self->extensions != NULL) 506 self->extensions->message = self->message; 507 if (ForEachCompositeField(self, FixupMessageReference(self->message)) == -1) 508 return -1; 509 510 return 0; 511} 512 513// --- Globals: 514 515static PyObject* GetDescriptor(CMessage* self, PyObject* name) { 516 PyObject* descriptors = 517 PyDict_GetItem(Py_TYPE(self)->tp_dict, k__descriptors); 518 if (descriptors == NULL) { 519 PyErr_SetString(PyExc_TypeError, "No __descriptors"); 520 return NULL; 521 } 522 523 return PyDict_GetItem(descriptors, name); 524} 525 526static const google::protobuf::Message* CreateMessage(const char* message_type) { 527 string message_name(message_type); 528 const google::protobuf::Descriptor* descriptor = 529 GetDescriptorPool()->FindMessageTypeByName(message_name); 530 if (descriptor == NULL) { 531 PyErr_SetString(PyExc_TypeError, message_type); 532 return NULL; 533 } 534 return global_message_factory->GetPrototype(descriptor); 535} 536 537// If cmessage_list is not NULL, this function releases values into the 538// container CMessages instead of just removing. Repeated composite container 539// needs to do this to make sure CMessages stay alive if they're still 540// referenced after deletion. Repeated scalar container doesn't need to worry. 541int InternalDeleteRepeatedField( 542 google::protobuf::Message* message, 543 const google::protobuf::FieldDescriptor* field_descriptor, 544 PyObject* slice, 545 PyObject* cmessage_list) { 546 Py_ssize_t length, from, to, step, slice_length; 547 const google::protobuf::Reflection* reflection = message->GetReflection(); 548 int min, max; 549 length = reflection->FieldSize(*message, field_descriptor); 550 551 if (PyInt_Check(slice) || PyLong_Check(slice)) { 552 from = to = PyLong_AsLong(slice); 553 if (from < 0) { 554 from = to = length + from; 555 } 556 step = 1; 557 min = max = from; 558 559 // Range check. 560 if (from < 0 || from >= length) { 561 PyErr_Format(PyExc_IndexError, "list assignment index out of range"); 562 return -1; 563 } 564 } else if (PySlice_Check(slice)) { 565 from = to = step = slice_length = 0; 566 PySlice_GetIndicesEx( 567#if PY_MAJOR_VERSION < 3 568 reinterpret_cast<PySliceObject*>(slice), 569#else 570 slice, 571#endif 572 length, &from, &to, &step, &slice_length); 573 if (from < to) { 574 min = from; 575 max = to - 1; 576 } else { 577 min = to + 1; 578 max = from; 579 } 580 } else { 581 PyErr_SetString(PyExc_TypeError, "list indices must be integers"); 582 return -1; 583 } 584 585 Py_ssize_t i = from; 586 std::vector<bool> to_delete(length, false); 587 while (i >= min && i <= max) { 588 to_delete[i] = true; 589 i += step; 590 } 591 592 to = 0; 593 for (i = 0; i < length; ++i) { 594 if (!to_delete[i]) { 595 if (i != to) { 596 reflection->SwapElements(message, field_descriptor, i, to); 597 if (cmessage_list != NULL) { 598 // If a list of cmessages is passed in (i.e. from a repeated 599 // composite container), swap those as well to correspond to the 600 // swaps in the underlying message so they're in the right order 601 // when we start releasing. 602 PyObject* tmp = PyList_GET_ITEM(cmessage_list, i); 603 PyList_SET_ITEM(cmessage_list, i, 604 PyList_GET_ITEM(cmessage_list, to)); 605 PyList_SET_ITEM(cmessage_list, to, tmp); 606 } 607 } 608 ++to; 609 } 610 } 611 612 while (i > to) { 613 if (cmessage_list == NULL) { 614 reflection->RemoveLast(message, field_descriptor); 615 } else { 616 CMessage* last_cmessage = reinterpret_cast<CMessage*>( 617 PyList_GET_ITEM(cmessage_list, PyList_GET_SIZE(cmessage_list) - 1)); 618 repeated_composite_container::ReleaseLastTo( 619 field_descriptor, message, last_cmessage); 620 if (PySequence_DelItem(cmessage_list, -1) < 0) { 621 return -1; 622 } 623 } 624 --i; 625 } 626 627 return 0; 628} 629 630int InitAttributes(CMessage* self, PyObject* arg, PyObject* kwargs) { 631 ScopedPyObjectPtr descriptor; 632 if (arg == NULL) { 633 descriptor.reset( 634 PyObject_GetAttr(reinterpret_cast<PyObject*>(self), kDESCRIPTOR)); 635 if (descriptor == NULL) { 636 return NULL; 637 } 638 } else { 639 descriptor.reset(arg); 640 descriptor.inc(); 641 } 642 ScopedPyObjectPtr is_extendable(PyObject_GetAttr(descriptor, kis_extendable)); 643 if (is_extendable == NULL) { 644 return NULL; 645 } 646 int retcode = PyObject_IsTrue(is_extendable); 647 if (retcode == -1) { 648 return NULL; 649 } 650 if (retcode) { 651 PyObject* py_extension_dict = PyObject_CallObject( 652 reinterpret_cast<PyObject*>(&ExtensionDict_Type), NULL); 653 if (py_extension_dict == NULL) { 654 return NULL; 655 } 656 ExtensionDict* extension_dict = reinterpret_cast<ExtensionDict*>( 657 py_extension_dict); 658 extension_dict->parent = self; 659 extension_dict->message = self->message; 660 self->extensions = extension_dict; 661 } 662 663 if (kwargs == NULL) { 664 return 0; 665 } 666 667 Py_ssize_t pos = 0; 668 PyObject* name; 669 PyObject* value; 670 while (PyDict_Next(kwargs, &pos, &name, &value)) { 671 if (!PyString_Check(name)) { 672 PyErr_SetString(PyExc_ValueError, "Field name must be a string"); 673 return -1; 674 } 675 PyObject* py_cdescriptor = GetDescriptor(self, name); 676 if (py_cdescriptor == NULL) { 677 PyErr_Format(PyExc_ValueError, "Protocol message has no \"%s\" field.", 678 PyString_AsString(name)); 679 return -1; 680 } 681 const google::protobuf::FieldDescriptor* descriptor = 682 reinterpret_cast<CFieldDescriptor*>(py_cdescriptor)->descriptor; 683 if (descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) { 684 ScopedPyObjectPtr container(GetAttr(self, name)); 685 if (container == NULL) { 686 return -1; 687 } 688 if (descriptor->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) { 689 if (repeated_composite_container::Extend( 690 reinterpret_cast<RepeatedCompositeContainer*>(container.get()), 691 value) 692 == NULL) { 693 return -1; 694 } 695 } else { 696 if (repeated_scalar_container::Extend( 697 reinterpret_cast<RepeatedScalarContainer*>(container.get()), 698 value) == 699 NULL) { 700 return -1; 701 } 702 } 703 } else if (descriptor->cpp_type() == 704 google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) { 705 ScopedPyObjectPtr message(GetAttr(self, name)); 706 if (message == NULL) { 707 return -1; 708 } 709 if (MergeFrom(reinterpret_cast<CMessage*>(message.get()), 710 value) == NULL) { 711 return -1; 712 } 713 } else { 714 if (SetAttr(self, name, value) < 0) { 715 return -1; 716 } 717 } 718 } 719 return 0; 720} 721 722static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { 723 CMessage* self = reinterpret_cast<CMessage*>(type->tp_alloc(type, 0)); 724 if (self == NULL) { 725 return NULL; 726 } 727 728 self->message = NULL; 729 self->parent = NULL; 730 self->parent_field = NULL; 731 self->read_only = false; 732 self->extensions = NULL; 733 734 self->composite_fields = PyDict_New(); 735 if (self->composite_fields == NULL) { 736 return NULL; 737 } 738 return reinterpret_cast<PyObject*>(self); 739} 740 741PyObject* NewEmpty(PyObject* type) { 742 return New(reinterpret_cast<PyTypeObject*>(type), NULL, NULL); 743} 744 745static int Init(CMessage* self, PyObject* args, PyObject* kwargs) { 746 if (kwargs == NULL) { 747 // TODO(anuraag): Set error 748 return -1; 749 } 750 751 PyObject* descriptor = PyTuple_GetItem(args, 0); 752 if (descriptor == NULL || PyTuple_Size(args) != 1) { 753 PyErr_SetString(PyExc_ValueError, "args must contain one arg: descriptor"); 754 return -1; 755 } 756 757 ScopedPyObjectPtr py_message_type(PyObject_GetAttr(descriptor, kfull_name)); 758 if (py_message_type == NULL) { 759 return -1; 760 } 761 762 const char* message_type = PyString_AsString(py_message_type.get()); 763 const google::protobuf::Message* message = CreateMessage(message_type); 764 if (message == NULL) { 765 return -1; 766 } 767 768 self->message = message->New(); 769 self->owner.reset(self->message); 770 771 if (InitAttributes(self, descriptor, kwargs) < 0) { 772 return -1; 773 } 774 return 0; 775} 776 777// --------------------------------------------------------------------- 778// Deallocating a CMessage 779// 780// Deallocating a CMessage requires that we clear any weak references 781// from children to the message being deallocated. 782 783// Clear the weak reference from the child to the parent. 784struct ClearWeakReferences : public ChildVisitor { 785 int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) { 786 container->parent = NULL; 787 // The elements in the container have the same parent as the 788 // container itself, so NULL out that pointer as well. 789 const Py_ssize_t n = PyList_GET_SIZE(container->child_messages); 790 for (Py_ssize_t i = 0; i < n; ++i) { 791 CMessage* child_cmessage = reinterpret_cast<CMessage*>( 792 PyList_GET_ITEM(container->child_messages, i)); 793 child_cmessage->parent = NULL; 794 } 795 return 0; 796 } 797 798 int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) { 799 container->parent = NULL; 800 return 0; 801 } 802 803 int VisitCMessage(CMessage* cmessage, 804 const google::protobuf::FieldDescriptor* field_descriptor) { 805 cmessage->parent = NULL; 806 return 0; 807 } 808}; 809 810static void Dealloc(CMessage* self) { 811 // Null out all weak references from children to this message. 812 GOOGLE_CHECK_EQ(0, ForEachCompositeField(self, ClearWeakReferences())); 813 814 Py_CLEAR(self->extensions); 815 Py_CLEAR(self->composite_fields); 816 self->owner.reset(); 817 Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); 818} 819 820// --------------------------------------------------------------------- 821 822 823PyObject* IsInitialized(CMessage* self, PyObject* args) { 824 PyObject* errors = NULL; 825 if (PyArg_ParseTuple(args, "|O", &errors) < 0) { 826 return NULL; 827 } 828 if (self->message->IsInitialized()) { 829 Py_RETURN_TRUE; 830 } 831 if (errors != NULL) { 832 ScopedPyObjectPtr initialization_errors( 833 FindInitializationErrors(self)); 834 if (initialization_errors == NULL) { 835 return NULL; 836 } 837 ScopedPyObjectPtr extend_name(PyString_FromString("extend")); 838 if (extend_name == NULL) { 839 return NULL; 840 } 841 ScopedPyObjectPtr result(PyObject_CallMethodObjArgs( 842 errors, 843 extend_name.get(), 844 initialization_errors.get(), 845 NULL)); 846 if (result == NULL) { 847 return NULL; 848 } 849 } 850 Py_RETURN_FALSE; 851} 852 853PyObject* HasFieldByDescriptor( 854 CMessage* self, const google::protobuf::FieldDescriptor* field_descriptor) { 855 google::protobuf::Message* message = self->message; 856 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { 857 PyErr_SetString(PyExc_KeyError, 858 "Field does not belong to message!"); 859 return NULL; 860 } 861 if (field_descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) { 862 PyErr_SetString(PyExc_KeyError, 863 "Field is repeated. A singular method is required."); 864 return NULL; 865 } 866 bool has_field = 867 message->GetReflection()->HasField(*message, field_descriptor); 868 return PyBool_FromLong(has_field ? 1 : 0); 869} 870 871const google::protobuf::FieldDescriptor* FindFieldWithOneofs( 872 const google::protobuf::Message* message, const char* field_name, bool* in_oneof) { 873 const google::protobuf::Descriptor* descriptor = message->GetDescriptor(); 874 const google::protobuf::FieldDescriptor* field_descriptor = 875 descriptor->FindFieldByName(field_name); 876 if (field_descriptor == NULL) { 877 const google::protobuf::OneofDescriptor* oneof_desc = 878 message->GetDescriptor()->FindOneofByName(field_name); 879 if (oneof_desc == NULL) { 880 *in_oneof = false; 881 return NULL; 882 } else { 883 *in_oneof = true; 884 return message->GetReflection()->GetOneofFieldDescriptor( 885 *message, oneof_desc); 886 } 887 } 888 return field_descriptor; 889} 890 891PyObject* HasField(CMessage* self, PyObject* arg) { 892#if PY_MAJOR_VERSION < 3 893 char* field_name; 894 if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) { 895#else 896 char* field_name = PyUnicode_AsUTF8(arg); 897 if (!field_name) { 898#endif 899 return NULL; 900 } 901 902 google::protobuf::Message* message = self->message; 903 const google::protobuf::Descriptor* descriptor = message->GetDescriptor(); 904 bool is_in_oneof; 905 const google::protobuf::FieldDescriptor* field_descriptor = 906 FindFieldWithOneofs(message, field_name, &is_in_oneof); 907 if (field_descriptor == NULL) { 908 if (!is_in_oneof) { 909 PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name); 910 return NULL; 911 } else { 912 Py_RETURN_FALSE; 913 } 914 } 915 916 if (field_descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) { 917 PyErr_Format(PyExc_ValueError, 918 "Protocol message has no singular \"%s\" field.", field_name); 919 return NULL; 920 } 921 922 bool has_field = 923 message->GetReflection()->HasField(*message, field_descriptor); 924 if (!has_field && field_descriptor->cpp_type() == 925 google::protobuf::FieldDescriptor::CPPTYPE_ENUM) { 926 // We may have an invalid enum value stored in the UnknownFieldSet and need 927 // to check presence in there as well. 928 const google::protobuf::UnknownFieldSet& unknown_field_set = 929 message->GetReflection()->GetUnknownFields(*message); 930 for (int i = 0; i < unknown_field_set.field_count(); ++i) { 931 if (unknown_field_set.field(i).number() == field_descriptor->number()) { 932 Py_RETURN_TRUE; 933 } 934 } 935 Py_RETURN_FALSE; 936 } 937 return PyBool_FromLong(has_field ? 1 : 0); 938} 939 940PyObject* ClearExtension(CMessage* self, PyObject* arg) { 941 if (self->extensions != NULL) { 942 return extension_dict::ClearExtension(self->extensions, arg); 943 } 944 PyErr_SetString(PyExc_TypeError, "Message is not extendable"); 945 return NULL; 946} 947 948PyObject* HasExtension(CMessage* self, PyObject* arg) { 949 if (self->extensions != NULL) { 950 return extension_dict::HasExtension(self->extensions, arg); 951 } 952 PyErr_SetString(PyExc_TypeError, "Message is not extendable"); 953 return NULL; 954} 955 956// --------------------------------------------------------------------- 957// Releasing messages 958// 959// The Python API's ClearField() and Clear() methods behave 960// differently than their C++ counterparts. While the C++ versions 961// clears the children the Python versions detaches the children, 962// without touching their content. This impedance mismatch causes 963// some complexity in the implementation, which is captured in this 964// section. 965// 966// When a CMessage field is cleared we need to: 967// 968// * Release the Message used as the backing store for the CMessage 969// from its parent. 970// 971// * Change the owner field of the released CMessage and all of its 972// children to point to the newly released Message. 973// 974// * Clear the weak references from the released CMessage to the 975// parent. 976// 977// When a RepeatedCompositeContainer field is cleared we need to: 978// 979// * Release all the Message used as the backing store for the 980// CMessages stored in the container. 981// 982// * Change the owner field of all the released CMessage and all of 983// their children to point to the newly released Messages. 984// 985// * Clear the weak references from the released container to the 986// parent. 987 988struct SetOwnerVisitor : public ChildVisitor { 989 // new_owner must outlive this object. 990 explicit SetOwnerVisitor(const shared_ptr<Message>& new_owner) 991 : new_owner_(new_owner) {} 992 993 int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) { 994 repeated_composite_container::SetOwner(container, new_owner_); 995 return 0; 996 } 997 998 int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) { 999 repeated_scalar_container::SetOwner(container, new_owner_); 1000 return 0; 1001 } 1002 1003 int VisitCMessage(CMessage* cmessage, 1004 const google::protobuf::FieldDescriptor* field_descriptor) { 1005 return SetOwner(cmessage, new_owner_); 1006 } 1007 1008 private: 1009 const shared_ptr<Message>& new_owner_; 1010}; 1011 1012// Change the owner of this CMessage and all its children, recursively. 1013int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner) { 1014 self->owner = new_owner; 1015 if (ForEachCompositeField(self, SetOwnerVisitor(new_owner)) == -1) 1016 return -1; 1017 return 0; 1018} 1019 1020// Releases the message specified by 'field' and returns the 1021// pointer. If the field does not exist a new message is created using 1022// 'descriptor'. The caller takes ownership of the returned pointer. 1023Message* ReleaseMessage(google::protobuf::Message* message, 1024 const google::protobuf::Descriptor* descriptor, 1025 const google::protobuf::FieldDescriptor* field_descriptor) { 1026 Message* released_message = message->GetReflection()->ReleaseMessage( 1027 message, field_descriptor, global_message_factory); 1028 // ReleaseMessage will return NULL which differs from 1029 // child_cmessage->message, if the field does not exist. In this case, 1030 // the latter points to the default instance via a const_cast<>, so we 1031 // have to reset it to a new mutable object since we are taking ownership. 1032 if (released_message == NULL) { 1033 const Message* prototype = global_message_factory->GetPrototype( 1034 descriptor); 1035 GOOGLE_DCHECK(prototype != NULL); 1036 released_message = prototype->New(); 1037 } 1038 1039 return released_message; 1040} 1041 1042int ReleaseSubMessage(google::protobuf::Message* message, 1043 const google::protobuf::FieldDescriptor* field_descriptor, 1044 CMessage* child_cmessage) { 1045 // Release the Message 1046 shared_ptr<Message> released_message(ReleaseMessage( 1047 message, child_cmessage->message->GetDescriptor(), field_descriptor)); 1048 child_cmessage->message = released_message.get(); 1049 child_cmessage->owner.swap(released_message); 1050 child_cmessage->parent = NULL; 1051 child_cmessage->parent_field = NULL; 1052 child_cmessage->read_only = false; 1053 return ForEachCompositeField(child_cmessage, 1054 SetOwnerVisitor(child_cmessage->owner)); 1055} 1056 1057struct ReleaseChild : public ChildVisitor { 1058 // message must outlive this object. 1059 explicit ReleaseChild(google::protobuf::Message* parent_message) : 1060 parent_message_(parent_message) {} 1061 1062 int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) { 1063 return repeated_composite_container::Release( 1064 reinterpret_cast<RepeatedCompositeContainer*>(container)); 1065 } 1066 1067 int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) { 1068 return repeated_scalar_container::Release( 1069 reinterpret_cast<RepeatedScalarContainer*>(container)); 1070 } 1071 1072 int VisitCMessage(CMessage* cmessage, 1073 const google::protobuf::FieldDescriptor* field_descriptor) { 1074 return ReleaseSubMessage(parent_message_, field_descriptor, 1075 reinterpret_cast<CMessage*>(cmessage)); 1076 } 1077 1078 google::protobuf::Message* parent_message_; 1079}; 1080 1081int InternalReleaseFieldByDescriptor( 1082 const google::protobuf::FieldDescriptor* field_descriptor, 1083 PyObject* composite_field, 1084 google::protobuf::Message* parent_message) { 1085 return VisitCompositeField( 1086 field_descriptor, 1087 composite_field, 1088 ReleaseChild(parent_message)); 1089} 1090 1091int InternalReleaseField(CMessage* self, PyObject* composite_field, 1092 PyObject* name) { 1093 PyObject* cdescriptor = GetDescriptor(self, name); 1094 if (cdescriptor != NULL) { 1095 const google::protobuf::FieldDescriptor* descriptor = 1096 reinterpret_cast<CFieldDescriptor*>(cdescriptor)->descriptor; 1097 return InternalReleaseFieldByDescriptor( 1098 descriptor, composite_field, self->message); 1099 } 1100 1101 return 0; 1102} 1103 1104PyObject* ClearFieldByDescriptor( 1105 CMessage* self, 1106 const google::protobuf::FieldDescriptor* descriptor) { 1107 if (!FIELD_BELONGS_TO_MESSAGE(descriptor, self->message)) { 1108 PyErr_SetString(PyExc_KeyError, 1109 "Field does not belong to message!"); 1110 return NULL; 1111 } 1112 AssureWritable(self); 1113 self->message->GetReflection()->ClearField(self->message, descriptor); 1114 Py_RETURN_NONE; 1115} 1116 1117PyObject* ClearField(CMessage* self, PyObject* arg) { 1118 char* field_name; 1119 if (!PyString_Check(arg)) { 1120 PyErr_SetString(PyExc_TypeError, "field name must be a string"); 1121 return NULL; 1122 } 1123#if PY_MAJOR_VERSION < 3 1124 if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) { 1125 return NULL; 1126 } 1127#else 1128 field_name = PyUnicode_AsUTF8(arg); 1129#endif 1130 AssureWritable(self); 1131 google::protobuf::Message* message = self->message; 1132 const google::protobuf::Descriptor* descriptor = message->GetDescriptor(); 1133 ScopedPyObjectPtr arg_in_oneof; 1134 bool is_in_oneof; 1135 const google::protobuf::FieldDescriptor* field_descriptor = 1136 FindFieldWithOneofs(message, field_name, &is_in_oneof); 1137 if (field_descriptor == NULL) { 1138 if (!is_in_oneof) { 1139 PyErr_Format(PyExc_ValueError, 1140 "Protocol message has no \"%s\" field.", field_name); 1141 return NULL; 1142 } else { 1143 Py_RETURN_NONE; 1144 } 1145 } else if (is_in_oneof) { 1146 arg_in_oneof.reset(PyString_FromString(field_descriptor->name().c_str())); 1147 arg = arg_in_oneof.get(); 1148 } 1149 1150 PyObject* composite_field = PyDict_GetItem(self->composite_fields, 1151 arg); 1152 1153 // Only release the field if there's a possibility that there are 1154 // references to it. 1155 if (composite_field != NULL) { 1156 if (InternalReleaseField(self, composite_field, arg) < 0) { 1157 return NULL; 1158 } 1159 PyDict_DelItem(self->composite_fields, arg); 1160 } 1161 message->GetReflection()->ClearField(message, field_descriptor); 1162 if (field_descriptor->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_ENUM) { 1163 google::protobuf::UnknownFieldSet* unknown_field_set = 1164 message->GetReflection()->MutableUnknownFields(message); 1165 unknown_field_set->DeleteByNumber(field_descriptor->number()); 1166 } 1167 1168 Py_RETURN_NONE; 1169} 1170 1171PyObject* Clear(CMessage* self) { 1172 AssureWritable(self); 1173 if (ForEachCompositeField(self, ReleaseChild(self->message)) == -1) 1174 return NULL; 1175 1176 // The old ExtensionDict still aliases this CMessage, but all its 1177 // fields have been released. 1178 if (self->extensions != NULL) { 1179 Py_CLEAR(self->extensions); 1180 PyObject* py_extension_dict = PyObject_CallObject( 1181 reinterpret_cast<PyObject*>(&ExtensionDict_Type), NULL); 1182 if (py_extension_dict == NULL) { 1183 return NULL; 1184 } 1185 ExtensionDict* extension_dict = reinterpret_cast<ExtensionDict*>( 1186 py_extension_dict); 1187 extension_dict->parent = self; 1188 extension_dict->message = self->message; 1189 self->extensions = extension_dict; 1190 } 1191 PyDict_Clear(self->composite_fields); 1192 self->message->Clear(); 1193 Py_RETURN_NONE; 1194} 1195 1196// --------------------------------------------------------------------- 1197 1198static string GetMessageName(CMessage* self) { 1199 if (self->parent_field != NULL) { 1200 return self->parent_field->descriptor->full_name(); 1201 } else { 1202 return self->message->GetDescriptor()->full_name(); 1203 } 1204} 1205 1206static PyObject* SerializeToString(CMessage* self, PyObject* args) { 1207 if (!self->message->IsInitialized()) { 1208 ScopedPyObjectPtr errors(FindInitializationErrors(self)); 1209 if (errors == NULL) { 1210 return NULL; 1211 } 1212 ScopedPyObjectPtr comma(PyString_FromString(",")); 1213 if (comma == NULL) { 1214 return NULL; 1215 } 1216 ScopedPyObjectPtr joined( 1217 PyObject_CallMethod(comma.get(), "join", "O", errors.get())); 1218 if (joined == NULL) { 1219 return NULL; 1220 } 1221 PyErr_Format(EncodeError_class, "Message %s is missing required fields: %s", 1222 GetMessageName(self).c_str(), PyString_AsString(joined.get())); 1223 return NULL; 1224 } 1225 int size = self->message->ByteSize(); 1226 if (size <= 0) { 1227 return PyBytes_FromString(""); 1228 } 1229 PyObject* result = PyBytes_FromStringAndSize(NULL, size); 1230 if (result == NULL) { 1231 return NULL; 1232 } 1233 char* buffer = PyBytes_AS_STRING(result); 1234 self->message->SerializeWithCachedSizesToArray( 1235 reinterpret_cast<uint8*>(buffer)); 1236 return result; 1237} 1238 1239static PyObject* SerializePartialToString(CMessage* self) { 1240 string contents; 1241 self->message->SerializePartialToString(&contents); 1242 return PyBytes_FromStringAndSize(contents.c_str(), contents.size()); 1243} 1244 1245// Formats proto fields for ascii dumps using python formatting functions where 1246// appropriate. 1247class PythonFieldValuePrinter : public google::protobuf::TextFormat::FieldValuePrinter { 1248 public: 1249 PythonFieldValuePrinter() : float_holder_(PyFloat_FromDouble(0)) {} 1250 1251 // Python has some differences from C++ when printing floating point numbers. 1252 // 1253 // 1) Trailing .0 is always printed. 1254 // 2) Outputted is rounded to 12 digits. 1255 // 1256 // We override floating point printing with the C-API function for printing 1257 // Python floats to ensure consistency. 1258 string PrintFloat(float value) const { return PrintDouble(value); } 1259 string PrintDouble(double value) const { 1260 reinterpret_cast<PyFloatObject*>(float_holder_.get())->ob_fval = value; 1261 ScopedPyObjectPtr s(PyObject_Str(float_holder_.get())); 1262 if (s == NULL) return string(); 1263#if PY_MAJOR_VERSION < 3 1264 char *cstr = PyBytes_AS_STRING(static_cast<PyObject*>(s)); 1265#else 1266 char *cstr = PyUnicode_AsUTF8(s); 1267#endif 1268 return string(cstr); 1269 } 1270 1271 private: 1272 // Holder for a python float object which we use to allow us to use 1273 // the Python API for printing doubles. We initialize once and then 1274 // directly modify it for every float printed to save on allocations 1275 // and refcounting. 1276 ScopedPyObjectPtr float_holder_; 1277}; 1278 1279static PyObject* ToStr(CMessage* self) { 1280 google::protobuf::TextFormat::Printer printer; 1281 // Passes ownership 1282 printer.SetDefaultFieldValuePrinter(new PythonFieldValuePrinter()); 1283 printer.SetHideUnknownFields(true); 1284 string output; 1285 if (!printer.PrintToString(*self->message, &output)) { 1286 PyErr_SetString(PyExc_ValueError, "Unable to convert message to str"); 1287 return NULL; 1288 } 1289 return PyString_FromString(output.c_str()); 1290} 1291 1292PyObject* MergeFrom(CMessage* self, PyObject* arg) { 1293 CMessage* other_message; 1294 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) { 1295 PyErr_SetString(PyExc_TypeError, "Must be a message"); 1296 return NULL; 1297 } 1298 1299 other_message = reinterpret_cast<CMessage*>(arg); 1300 if (other_message->message->GetDescriptor() != 1301 self->message->GetDescriptor()) { 1302 PyErr_Format(PyExc_TypeError, 1303 "Tried to merge from a message with a different type. " 1304 "to: %s, from: %s", 1305 self->message->GetDescriptor()->full_name().c_str(), 1306 other_message->message->GetDescriptor()->full_name().c_str()); 1307 return NULL; 1308 } 1309 AssureWritable(self); 1310 1311 // TODO(tibell): Message::MergeFrom might turn some child Messages 1312 // into mutable messages, invalidating the message field in the 1313 // corresponding CMessages. We should run a FixupMessageReferences 1314 // pass here. 1315 1316 self->message->MergeFrom(*other_message->message); 1317 Py_RETURN_NONE; 1318} 1319 1320static PyObject* CopyFrom(CMessage* self, PyObject* arg) { 1321 CMessage* other_message; 1322 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) { 1323 PyErr_SetString(PyExc_TypeError, "Must be a message"); 1324 return NULL; 1325 } 1326 1327 other_message = reinterpret_cast<CMessage*>(arg); 1328 1329 if (self == other_message) { 1330 Py_RETURN_NONE; 1331 } 1332 1333 if (other_message->message->GetDescriptor() != 1334 self->message->GetDescriptor()) { 1335 PyErr_Format(PyExc_TypeError, 1336 "Tried to copy from a message with a different type. " 1337 "to: %s, from: %s", 1338 self->message->GetDescriptor()->full_name().c_str(), 1339 other_message->message->GetDescriptor()->full_name().c_str()); 1340 return NULL; 1341 } 1342 1343 AssureWritable(self); 1344 1345 // CopyFrom on the message will not clean up self->composite_fields, 1346 // which can leave us in an inconsistent state, so clear it out here. 1347 Clear(self); 1348 1349 self->message->CopyFrom(*other_message->message); 1350 1351 Py_RETURN_NONE; 1352} 1353 1354static PyObject* MergeFromString(CMessage* self, PyObject* arg) { 1355 const void* data; 1356 Py_ssize_t data_length; 1357 if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) { 1358 return NULL; 1359 } 1360 1361 AssureWritable(self); 1362 google::protobuf::io::CodedInputStream input( 1363 reinterpret_cast<const uint8*>(data), data_length); 1364 input.SetExtensionRegistry(GetDescriptorPool(), global_message_factory); 1365 bool success = self->message->MergePartialFromCodedStream(&input); 1366 if (success) { 1367 return PyInt_FromLong(input.CurrentPosition()); 1368 } else { 1369 PyErr_Format(DecodeError_class, "Error parsing message"); 1370 return NULL; 1371 } 1372} 1373 1374static PyObject* ParseFromString(CMessage* self, PyObject* arg) { 1375 if (Clear(self) == NULL) { 1376 return NULL; 1377 } 1378 return MergeFromString(self, arg); 1379} 1380 1381static PyObject* ByteSize(CMessage* self, PyObject* args) { 1382 return PyLong_FromLong(self->message->ByteSize()); 1383} 1384 1385static PyObject* RegisterExtension(PyObject* cls, 1386 PyObject* extension_handle) { 1387 ScopedPyObjectPtr message_descriptor(PyObject_GetAttr(cls, kDESCRIPTOR)); 1388 if (message_descriptor == NULL) { 1389 return NULL; 1390 } 1391 if (PyObject_SetAttrString(extension_handle, "containing_type", 1392 message_descriptor) < 0) { 1393 return NULL; 1394 } 1395 ScopedPyObjectPtr extensions_by_name( 1396 PyObject_GetAttr(cls, k_extensions_by_name)); 1397 if (extensions_by_name == NULL) { 1398 PyErr_SetString(PyExc_TypeError, "no extensions_by_name on class"); 1399 return NULL; 1400 } 1401 ScopedPyObjectPtr full_name(PyObject_GetAttr(extension_handle, kfull_name)); 1402 if (full_name == NULL) { 1403 return NULL; 1404 } 1405 if (PyDict_SetItem(extensions_by_name, full_name, extension_handle) < 0) { 1406 return NULL; 1407 } 1408 1409 // Also store a mapping from extension number to implementing class. 1410 ScopedPyObjectPtr extensions_by_number( 1411 PyObject_GetAttr(cls, k_extensions_by_number)); 1412 if (extensions_by_number == NULL) { 1413 PyErr_SetString(PyExc_TypeError, "no extensions_by_number on class"); 1414 return NULL; 1415 } 1416 ScopedPyObjectPtr number(PyObject_GetAttrString(extension_handle, "number")); 1417 if (number == NULL) { 1418 return NULL; 1419 } 1420 if (PyDict_SetItem(extensions_by_number, number, extension_handle) < 0) { 1421 return NULL; 1422 } 1423 1424 CFieldDescriptor* cdescriptor = 1425 extension_dict::InternalGetCDescriptorFromExtension(extension_handle); 1426 ScopedPyObjectPtr py_cdescriptor(reinterpret_cast<PyObject*>(cdescriptor)); 1427 if (cdescriptor == NULL) { 1428 return NULL; 1429 } 1430 Py_INCREF(extension_handle); 1431 cdescriptor->descriptor_field = extension_handle; 1432 const google::protobuf::FieldDescriptor* descriptor = cdescriptor->descriptor; 1433 // Check if it's a message set 1434 if (descriptor->is_extension() && 1435 descriptor->containing_type()->options().message_set_wire_format() && 1436 descriptor->type() == google::protobuf::FieldDescriptor::TYPE_MESSAGE && 1437 descriptor->message_type() == descriptor->extension_scope() && 1438 descriptor->label() == google::protobuf::FieldDescriptor::LABEL_OPTIONAL) { 1439 ScopedPyObjectPtr message_name(PyString_FromStringAndSize( 1440 descriptor->message_type()->full_name().c_str(), 1441 descriptor->message_type()->full_name().size())); 1442 if (message_name == NULL) { 1443 return NULL; 1444 } 1445 PyDict_SetItem(extensions_by_name, message_name, extension_handle); 1446 } 1447 1448 Py_RETURN_NONE; 1449} 1450 1451static PyObject* SetInParent(CMessage* self, PyObject* args) { 1452 AssureWritable(self); 1453 Py_RETURN_NONE; 1454} 1455 1456static PyObject* WhichOneof(CMessage* self, PyObject* arg) { 1457 char* oneof_name; 1458 if (!PyString_Check(arg)) { 1459 PyErr_SetString(PyExc_TypeError, "field name must be a string"); 1460 return NULL; 1461 } 1462 oneof_name = PyString_AsString(arg); 1463 if (oneof_name == NULL) { 1464 return NULL; 1465 } 1466 const google::protobuf::OneofDescriptor* oneof_desc = 1467 self->message->GetDescriptor()->FindOneofByName(oneof_name); 1468 if (oneof_desc == NULL) { 1469 PyErr_Format(PyExc_ValueError, 1470 "Protocol message has no oneof \"%s\" field.", oneof_name); 1471 return NULL; 1472 } 1473 const google::protobuf::FieldDescriptor* field_in_oneof = 1474 self->message->GetReflection()->GetOneofFieldDescriptor( 1475 *self->message, oneof_desc); 1476 if (field_in_oneof == NULL) { 1477 Py_RETURN_NONE; 1478 } else { 1479 return PyString_FromString(field_in_oneof->name().c_str()); 1480 } 1481} 1482 1483static PyObject* ListFields(CMessage* self) { 1484 vector<const google::protobuf::FieldDescriptor*> fields; 1485 self->message->GetReflection()->ListFields(*self->message, &fields); 1486 1487 PyObject* descriptor = PyDict_GetItem(Py_TYPE(self)->tp_dict, kDESCRIPTOR); 1488 if (descriptor == NULL) { 1489 return NULL; 1490 } 1491 ScopedPyObjectPtr fields_by_name( 1492 PyObject_GetAttr(descriptor, kfields_by_name)); 1493 if (fields_by_name == NULL) { 1494 return NULL; 1495 } 1496 ScopedPyObjectPtr extensions_by_name(PyObject_GetAttr( 1497 reinterpret_cast<PyObject*>(Py_TYPE(self)), k_extensions_by_name)); 1498 if (extensions_by_name == NULL) { 1499 PyErr_SetString(PyExc_ValueError, "no extensionsbyname"); 1500 return NULL; 1501 } 1502 // Normally, the list will be exactly the size of the fields. 1503 PyObject* all_fields = PyList_New(fields.size()); 1504 if (all_fields == NULL) { 1505 return NULL; 1506 } 1507 1508 // When there are unknown extensions, the py list will *not* contain 1509 // the field information. Thus the actual size of the py list will be 1510 // smaller than the size of fields. Set the actual size at the end. 1511 Py_ssize_t actual_size = 0; 1512 for (Py_ssize_t i = 0; i < fields.size(); ++i) { 1513 ScopedPyObjectPtr t(PyTuple_New(2)); 1514 if (t == NULL) { 1515 Py_DECREF(all_fields); 1516 return NULL; 1517 } 1518 1519 if (fields[i]->is_extension()) { 1520 const string& field_name = fields[i]->full_name(); 1521 PyObject* extension_field = PyDict_GetItemString(extensions_by_name, 1522 field_name.c_str()); 1523 if (extension_field == NULL) { 1524 // If we couldn't fetch extension_field, it means the module that 1525 // defines this extension has not been explicitly imported in Python 1526 // code, and the extension hasn't been registered. There's nothing much 1527 // we can do about this, so just skip it in the output to match the 1528 // behavior of the python implementation. 1529 continue; 1530 } 1531 PyObject* extensions = reinterpret_cast<PyObject*>(self->extensions); 1532 if (extensions == NULL) { 1533 Py_DECREF(all_fields); 1534 return NULL; 1535 } 1536 // 'extension' reference later stolen by PyTuple_SET_ITEM. 1537 PyObject* extension = PyObject_GetItem(extensions, extension_field); 1538 if (extension == NULL) { 1539 Py_DECREF(all_fields); 1540 return NULL; 1541 } 1542 Py_INCREF(extension_field); 1543 PyTuple_SET_ITEM(t.get(), 0, extension_field); 1544 // Steals reference to 'extension' 1545 PyTuple_SET_ITEM(t.get(), 1, extension); 1546 } else { 1547 const string& field_name = fields[i]->name(); 1548 ScopedPyObjectPtr py_field_name(PyString_FromStringAndSize( 1549 field_name.c_str(), field_name.length())); 1550 if (py_field_name == NULL) { 1551 PyErr_SetString(PyExc_ValueError, "bad string"); 1552 Py_DECREF(all_fields); 1553 return NULL; 1554 } 1555 PyObject* field_descriptor = 1556 PyDict_GetItem(fields_by_name, py_field_name); 1557 if (field_descriptor == NULL) { 1558 Py_DECREF(all_fields); 1559 return NULL; 1560 } 1561 1562 PyObject* field_value = GetAttr(self, py_field_name); 1563 if (field_value == NULL) { 1564 PyErr_SetObject(PyExc_ValueError, py_field_name); 1565 Py_DECREF(all_fields); 1566 return NULL; 1567 } 1568 Py_INCREF(field_descriptor); 1569 PyTuple_SET_ITEM(t.get(), 0, field_descriptor); 1570 PyTuple_SET_ITEM(t.get(), 1, field_value); 1571 } 1572 PyList_SET_ITEM(all_fields, actual_size, t.release()); 1573 ++actual_size; 1574 } 1575 Py_SIZE(all_fields) = actual_size; 1576 return all_fields; 1577} 1578 1579PyObject* FindInitializationErrors(CMessage* self) { 1580 google::protobuf::Message* message = self->message; 1581 vector<string> errors; 1582 message->FindInitializationErrors(&errors); 1583 1584 PyObject* error_list = PyList_New(errors.size()); 1585 if (error_list == NULL) { 1586 return NULL; 1587 } 1588 for (Py_ssize_t i = 0; i < errors.size(); ++i) { 1589 const string& error = errors[i]; 1590 PyObject* error_string = PyString_FromStringAndSize( 1591 error.c_str(), error.length()); 1592 if (error_string == NULL) { 1593 Py_DECREF(error_list); 1594 return NULL; 1595 } 1596 PyList_SET_ITEM(error_list, i, error_string); 1597 } 1598 return error_list; 1599} 1600 1601static PyObject* RichCompare(CMessage* self, PyObject* other, int opid) { 1602 if (!PyObject_TypeCheck(other, &CMessage_Type)) { 1603 if (opid == Py_EQ) { 1604 Py_RETURN_FALSE; 1605 } else if (opid == Py_NE) { 1606 Py_RETURN_TRUE; 1607 } 1608 } 1609 if (opid == Py_EQ || opid == Py_NE) { 1610 ScopedPyObjectPtr self_fields(ListFields(self)); 1611 ScopedPyObjectPtr other_fields(ListFields( 1612 reinterpret_cast<CMessage*>(other))); 1613 return PyObject_RichCompare(self_fields, other_fields, opid); 1614 } else { 1615 Py_INCREF(Py_NotImplemented); 1616 return Py_NotImplemented; 1617 } 1618} 1619 1620PyObject* InternalGetScalar( 1621 CMessage* self, 1622 const google::protobuf::FieldDescriptor* field_descriptor) { 1623 google::protobuf::Message* message = self->message; 1624 const google::protobuf::Reflection* reflection = message->GetReflection(); 1625 1626 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { 1627 PyErr_SetString( 1628 PyExc_KeyError, "Field does not belong to message!"); 1629 return NULL; 1630 } 1631 1632 PyObject* result = NULL; 1633 switch (field_descriptor->cpp_type()) { 1634 case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { 1635 int32 value = reflection->GetInt32(*message, field_descriptor); 1636 result = PyInt_FromLong(value); 1637 break; 1638 } 1639 case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { 1640 int64 value = reflection->GetInt64(*message, field_descriptor); 1641 result = PyLong_FromLongLong(value); 1642 break; 1643 } 1644 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { 1645 uint32 value = reflection->GetUInt32(*message, field_descriptor); 1646 result = PyInt_FromSize_t(value); 1647 break; 1648 } 1649 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { 1650 uint64 value = reflection->GetUInt64(*message, field_descriptor); 1651 result = PyLong_FromUnsignedLongLong(value); 1652 break; 1653 } 1654 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { 1655 float value = reflection->GetFloat(*message, field_descriptor); 1656 result = PyFloat_FromDouble(value); 1657 break; 1658 } 1659 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { 1660 double value = reflection->GetDouble(*message, field_descriptor); 1661 result = PyFloat_FromDouble(value); 1662 break; 1663 } 1664 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { 1665 bool value = reflection->GetBool(*message, field_descriptor); 1666 result = PyBool_FromLong(value); 1667 break; 1668 } 1669 case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { 1670 string value = reflection->GetString(*message, field_descriptor); 1671 result = ToStringObject(field_descriptor, value); 1672 break; 1673 } 1674 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { 1675 if (!message->GetReflection()->HasField(*message, field_descriptor)) { 1676 // Look for the value in the unknown fields. 1677 google::protobuf::UnknownFieldSet* unknown_field_set = 1678 message->GetReflection()->MutableUnknownFields(message); 1679 for (int i = 0; i < unknown_field_set->field_count(); ++i) { 1680 if (unknown_field_set->field(i).number() == 1681 field_descriptor->number()) { 1682 result = PyInt_FromLong(unknown_field_set->field(i).varint()); 1683 break; 1684 } 1685 } 1686 } 1687 1688 if (result == NULL) { 1689 const google::protobuf::EnumValueDescriptor* enum_value = 1690 message->GetReflection()->GetEnum(*message, field_descriptor); 1691 result = PyInt_FromLong(enum_value->number()); 1692 } 1693 break; 1694 } 1695 default: 1696 PyErr_Format( 1697 PyExc_SystemError, "Getting a value from a field of unknown type %d", 1698 field_descriptor->cpp_type()); 1699 } 1700 1701 return result; 1702} 1703 1704PyObject* InternalGetSubMessage(CMessage* self, 1705 CFieldDescriptor* cfield_descriptor) { 1706 PyObject* field = cfield_descriptor->descriptor_field; 1707 ScopedPyObjectPtr message_type(PyObject_GetAttr(field, kmessage_type)); 1708 if (message_type == NULL) { 1709 return NULL; 1710 } 1711 ScopedPyObjectPtr concrete_class( 1712 PyObject_GetAttr(message_type, k_concrete_class)); 1713 if (concrete_class == NULL) { 1714 return NULL; 1715 } 1716 PyObject* py_cmsg = cmessage::NewEmpty(concrete_class); 1717 if (py_cmsg == NULL) { 1718 return NULL; 1719 } 1720 if (!PyObject_TypeCheck(py_cmsg, &CMessage_Type)) { 1721 PyErr_SetString(PyExc_TypeError, "Not a CMessage!"); 1722 } 1723 CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg); 1724 1725 const google::protobuf::FieldDescriptor* field_descriptor = 1726 cfield_descriptor->descriptor; 1727 const google::protobuf::Reflection* reflection = self->message->GetReflection(); 1728 const google::protobuf::Message& sub_message = reflection->GetMessage( 1729 *self->message, field_descriptor, global_message_factory); 1730 cmsg->owner = self->owner; 1731 cmsg->parent = self; 1732 cmsg->parent_field = cfield_descriptor; 1733 cmsg->read_only = !reflection->HasField(*self->message, field_descriptor); 1734 cmsg->message = const_cast<google::protobuf::Message*>(&sub_message); 1735 1736 if (InitAttributes(cmsg, NULL, NULL) < 0) { 1737 Py_DECREF(py_cmsg); 1738 return NULL; 1739 } 1740 return py_cmsg; 1741} 1742 1743int InternalSetScalar( 1744 CMessage* self, 1745 const google::protobuf::FieldDescriptor* field_descriptor, 1746 PyObject* arg) { 1747 google::protobuf::Message* message = self->message; 1748 const google::protobuf::Reflection* reflection = message->GetReflection(); 1749 1750 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { 1751 PyErr_SetString( 1752 PyExc_KeyError, "Field does not belong to message!"); 1753 return -1; 1754 } 1755 1756 if (MaybeReleaseOverlappingOneofField(self, field_descriptor) < 0) { 1757 return -1; 1758 } 1759 1760 switch (field_descriptor->cpp_type()) { 1761 case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { 1762 GOOGLE_CHECK_GET_INT32(arg, value, -1); 1763 reflection->SetInt32(message, field_descriptor, value); 1764 break; 1765 } 1766 case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { 1767 GOOGLE_CHECK_GET_INT64(arg, value, -1); 1768 reflection->SetInt64(message, field_descriptor, value); 1769 break; 1770 } 1771 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { 1772 GOOGLE_CHECK_GET_UINT32(arg, value, -1); 1773 reflection->SetUInt32(message, field_descriptor, value); 1774 break; 1775 } 1776 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { 1777 GOOGLE_CHECK_GET_UINT64(arg, value, -1); 1778 reflection->SetUInt64(message, field_descriptor, value); 1779 break; 1780 } 1781 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { 1782 GOOGLE_CHECK_GET_FLOAT(arg, value, -1); 1783 reflection->SetFloat(message, field_descriptor, value); 1784 break; 1785 } 1786 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { 1787 GOOGLE_CHECK_GET_DOUBLE(arg, value, -1); 1788 reflection->SetDouble(message, field_descriptor, value); 1789 break; 1790 } 1791 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { 1792 GOOGLE_CHECK_GET_BOOL(arg, value, -1); 1793 reflection->SetBool(message, field_descriptor, value); 1794 break; 1795 } 1796 case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { 1797 if (!CheckAndSetString( 1798 arg, message, field_descriptor, reflection, false, -1)) { 1799 return -1; 1800 } 1801 break; 1802 } 1803 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { 1804 GOOGLE_CHECK_GET_INT32(arg, value, -1); 1805 const google::protobuf::EnumDescriptor* enum_descriptor = 1806 field_descriptor->enum_type(); 1807 const google::protobuf::EnumValueDescriptor* enum_value = 1808 enum_descriptor->FindValueByNumber(value); 1809 if (enum_value != NULL) { 1810 reflection->SetEnum(message, field_descriptor, enum_value); 1811 } else { 1812 PyErr_Format(PyExc_ValueError, "Unknown enum value: %d", value); 1813 return -1; 1814 } 1815 break; 1816 } 1817 default: 1818 PyErr_Format( 1819 PyExc_SystemError, "Setting value to a field of unknown type %d", 1820 field_descriptor->cpp_type()); 1821 return -1; 1822 } 1823 1824 return 0; 1825} 1826 1827PyObject* FromString(PyTypeObject* cls, PyObject* serialized) { 1828 PyObject* py_cmsg = PyObject_CallObject( 1829 reinterpret_cast<PyObject*>(cls), NULL); 1830 if (py_cmsg == NULL) { 1831 return NULL; 1832 } 1833 CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg); 1834 1835 ScopedPyObjectPtr py_length(MergeFromString(cmsg, serialized)); 1836 if (py_length == NULL) { 1837 Py_DECREF(py_cmsg); 1838 return NULL; 1839 } 1840 1841 if (InitAttributes(cmsg, NULL, NULL) < 0) { 1842 Py_DECREF(py_cmsg); 1843 return NULL; 1844 } 1845 return py_cmsg; 1846} 1847 1848static PyObject* AddDescriptors(PyTypeObject* cls, 1849 PyObject* descriptor) { 1850 if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls), 1851 k_extensions_by_name, PyDict_New()) < 0) { 1852 return NULL; 1853 } 1854 if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls), 1855 k_extensions_by_number, PyDict_New()) < 0) { 1856 return NULL; 1857 } 1858 1859 ScopedPyObjectPtr field_descriptors(PyDict_New()); 1860 1861 ScopedPyObjectPtr fields(PyObject_GetAttrString(descriptor, "fields")); 1862 if (fields == NULL) { 1863 return NULL; 1864 } 1865 1866 ScopedPyObjectPtr _NUMBER_string(PyString_FromString("_FIELD_NUMBER")); 1867 if (_NUMBER_string == NULL) { 1868 return NULL; 1869 } 1870 1871 const Py_ssize_t fields_size = PyList_GET_SIZE(fields.get()); 1872 for (int i = 0; i < fields_size; ++i) { 1873 PyObject* field = PyList_GET_ITEM(fields.get(), i); 1874 ScopedPyObjectPtr field_name(PyObject_GetAttr(field, kname)); 1875 ScopedPyObjectPtr full_field_name(PyObject_GetAttr(field, kfull_name)); 1876 if (field_name == NULL || full_field_name == NULL) { 1877 PyErr_SetString(PyExc_TypeError, "Name is null"); 1878 return NULL; 1879 } 1880 1881 PyObject* field_descriptor = 1882 cdescriptor_pool::FindFieldByName(descriptor_pool, full_field_name); 1883 if (field_descriptor == NULL) { 1884 PyErr_SetString(PyExc_TypeError, "Couldn't find field"); 1885 return NULL; 1886 } 1887 Py_INCREF(field); 1888 CFieldDescriptor* cfield_descriptor = reinterpret_cast<CFieldDescriptor*>( 1889 field_descriptor); 1890 cfield_descriptor->descriptor_field = field; 1891 if (PyDict_SetItem(field_descriptors, field_name, field_descriptor) < 0) { 1892 return NULL; 1893 } 1894 1895 // The FieldDescriptor's name field might either be of type bytes or 1896 // of type unicode, depending on whether the FieldDescriptor was 1897 // parsed from a serialized message or read from the 1898 // <message>_pb2.py module. 1899 ScopedPyObjectPtr field_name_upcased( 1900 PyObject_CallMethod(field_name, "upper", NULL)); 1901 if (field_name_upcased == NULL) { 1902 return NULL; 1903 } 1904 1905 ScopedPyObjectPtr field_number_name(PyObject_CallMethod( 1906 field_name_upcased, "__add__", "(O)", _NUMBER_string.get())); 1907 if (field_number_name == NULL) { 1908 return NULL; 1909 } 1910 1911 ScopedPyObjectPtr number(PyInt_FromLong( 1912 cfield_descriptor->descriptor->number())); 1913 if (number == NULL) { 1914 return NULL; 1915 } 1916 if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls), 1917 field_number_name, number) == -1) { 1918 return NULL; 1919 } 1920 } 1921 1922 PyDict_SetItem(cls->tp_dict, k__descriptors, field_descriptors); 1923 1924 // Enum Values 1925 ScopedPyObjectPtr enum_types(PyObject_GetAttrString(descriptor, 1926 "enum_types")); 1927 if (enum_types == NULL) { 1928 return NULL; 1929 } 1930 ScopedPyObjectPtr type_iter(PyObject_GetIter(enum_types)); 1931 if (type_iter == NULL) { 1932 return NULL; 1933 } 1934 ScopedPyObjectPtr enum_type; 1935 while ((enum_type.reset(PyIter_Next(type_iter))) != NULL) { 1936 ScopedPyObjectPtr wrapped(PyObject_CallFunctionObjArgs( 1937 EnumTypeWrapper_class, enum_type.get(), NULL)); 1938 if (wrapped == NULL) { 1939 return NULL; 1940 } 1941 ScopedPyObjectPtr enum_name(PyObject_GetAttr(enum_type, kname)); 1942 if (enum_name == NULL) { 1943 return NULL; 1944 } 1945 if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls), 1946 enum_name, wrapped) == -1) { 1947 return NULL; 1948 } 1949 1950 ScopedPyObjectPtr enum_values(PyObject_GetAttrString(enum_type, "values")); 1951 if (enum_values == NULL) { 1952 return NULL; 1953 } 1954 ScopedPyObjectPtr values_iter(PyObject_GetIter(enum_values)); 1955 if (values_iter == NULL) { 1956 return NULL; 1957 } 1958 ScopedPyObjectPtr enum_value; 1959 while ((enum_value.reset(PyIter_Next(values_iter))) != NULL) { 1960 ScopedPyObjectPtr value_name(PyObject_GetAttr(enum_value, kname)); 1961 if (value_name == NULL) { 1962 return NULL; 1963 } 1964 ScopedPyObjectPtr value_number(PyObject_GetAttrString(enum_value, 1965 "number")); 1966 if (value_number == NULL) { 1967 return NULL; 1968 } 1969 if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls), 1970 value_name, value_number) == -1) { 1971 return NULL; 1972 } 1973 } 1974 if (PyErr_Occurred()) { // If PyIter_Next failed 1975 return NULL; 1976 } 1977 } 1978 if (PyErr_Occurred()) { // If PyIter_Next failed 1979 return NULL; 1980 } 1981 1982 ScopedPyObjectPtr extension_dict( 1983 PyObject_GetAttr(descriptor, kextensions_by_name)); 1984 if (extension_dict == NULL || !PyDict_Check(extension_dict)) { 1985 PyErr_SetString(PyExc_TypeError, "extensions_by_name not a dict"); 1986 return NULL; 1987 } 1988 Py_ssize_t pos = 0; 1989 PyObject* extension_name; 1990 PyObject* extension_field; 1991 1992 while (PyDict_Next(extension_dict, &pos, &extension_name, &extension_field)) { 1993 if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls), 1994 extension_name, extension_field) == -1) { 1995 return NULL; 1996 } 1997 ScopedPyObjectPtr py_cfield_descriptor( 1998 PyObject_GetAttrString(extension_field, "_cdescriptor")); 1999 if (py_cfield_descriptor == NULL) { 2000 return NULL; 2001 } 2002 CFieldDescriptor* cfield_descriptor = 2003 reinterpret_cast<CFieldDescriptor*>(py_cfield_descriptor.get()); 2004 Py_INCREF(extension_field); 2005 cfield_descriptor->descriptor_field = extension_field; 2006 2007 ScopedPyObjectPtr field_name_upcased( 2008 PyObject_CallMethod(extension_name, "upper", NULL)); 2009 if (field_name_upcased == NULL) { 2010 return NULL; 2011 } 2012 ScopedPyObjectPtr field_number_name(PyObject_CallMethod( 2013 field_name_upcased, "__add__", "(O)", _NUMBER_string.get())); 2014 if (field_number_name == NULL) { 2015 return NULL; 2016 } 2017 ScopedPyObjectPtr number(PyInt_FromLong( 2018 cfield_descriptor->descriptor->number())); 2019 if (number == NULL) { 2020 return NULL; 2021 } 2022 if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls), 2023 field_number_name, PyInt_FromLong( 2024 cfield_descriptor->descriptor->number())) == -1) { 2025 return NULL; 2026 } 2027 } 2028 2029 Py_RETURN_NONE; 2030} 2031 2032PyObject* DeepCopy(CMessage* self, PyObject* arg) { 2033 PyObject* clone = PyObject_CallObject( 2034 reinterpret_cast<PyObject*>(Py_TYPE(self)), NULL); 2035 if (clone == NULL) { 2036 return NULL; 2037 } 2038 if (!PyObject_TypeCheck(clone, &CMessage_Type)) { 2039 Py_DECREF(clone); 2040 return NULL; 2041 } 2042 if (InitAttributes(reinterpret_cast<CMessage*>(clone), NULL, NULL) < 0) { 2043 Py_DECREF(clone); 2044 return NULL; 2045 } 2046 if (MergeFrom(reinterpret_cast<CMessage*>(clone), 2047 reinterpret_cast<PyObject*>(self)) == NULL) { 2048 Py_DECREF(clone); 2049 return NULL; 2050 } 2051 return clone; 2052} 2053 2054PyObject* ToUnicode(CMessage* self) { 2055 // Lazy import to prevent circular dependencies 2056 ScopedPyObjectPtr text_format( 2057 PyImport_ImportModule("google.protobuf.text_format")); 2058 if (text_format == NULL) { 2059 return NULL; 2060 } 2061 ScopedPyObjectPtr method_name(PyString_FromString("MessageToString")); 2062 if (method_name == NULL) { 2063 return NULL; 2064 } 2065 Py_INCREF(Py_True); 2066 ScopedPyObjectPtr encoded(PyObject_CallMethodObjArgs(text_format, method_name, 2067 self, Py_True, NULL)); 2068 Py_DECREF(Py_True); 2069 if (encoded == NULL) { 2070 return NULL; 2071 } 2072#if PY_MAJOR_VERSION < 3 2073 PyObject* decoded = PyString_AsDecodedObject(encoded, "utf-8", NULL); 2074#else 2075 PyObject* decoded = PyUnicode_FromEncodedObject(encoded, "utf-8", NULL); 2076#endif 2077 if (decoded == NULL) { 2078 return NULL; 2079 } 2080 return decoded; 2081} 2082 2083PyObject* Reduce(CMessage* self) { 2084 ScopedPyObjectPtr constructor(reinterpret_cast<PyObject*>(Py_TYPE(self))); 2085 constructor.inc(); 2086 ScopedPyObjectPtr args(PyTuple_New(0)); 2087 if (args == NULL) { 2088 return NULL; 2089 } 2090 ScopedPyObjectPtr state(PyDict_New()); 2091 if (state == NULL) { 2092 return NULL; 2093 } 2094 ScopedPyObjectPtr serialized(SerializePartialToString(self)); 2095 if (serialized == NULL) { 2096 return NULL; 2097 } 2098 if (PyDict_SetItemString(state, "serialized", serialized) < 0) { 2099 return NULL; 2100 } 2101 return Py_BuildValue("OOO", constructor.get(), args.get(), state.get()); 2102} 2103 2104PyObject* SetState(CMessage* self, PyObject* state) { 2105 if (!PyDict_Check(state)) { 2106 PyErr_SetString(PyExc_TypeError, "state not a dict"); 2107 return NULL; 2108 } 2109 PyObject* serialized = PyDict_GetItemString(state, "serialized"); 2110 if (serialized == NULL) { 2111 return NULL; 2112 } 2113 if (ParseFromString(self, serialized) == NULL) { 2114 return NULL; 2115 } 2116 Py_RETURN_NONE; 2117} 2118 2119// CMessage static methods: 2120PyObject* _GetFieldDescriptor(PyObject* unused, PyObject* arg) { 2121 return cdescriptor_pool::FindFieldByName(descriptor_pool, arg); 2122} 2123 2124PyObject* _GetExtensionDescriptor(PyObject* unused, PyObject* arg) { 2125 return cdescriptor_pool::FindExtensionByName(descriptor_pool, arg); 2126} 2127 2128static PyMemberDef Members[] = { 2129 {"Extensions", T_OBJECT_EX, offsetof(CMessage, extensions), 0, 2130 "Extension dict"}, 2131 {NULL} 2132}; 2133 2134static PyMethodDef Methods[] = { 2135 { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, 2136 "Makes a deep copy of the class." }, 2137 { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, 2138 "Outputs picklable representation of the message." }, 2139 { "__setstate__", (PyCFunction)SetState, METH_O, 2140 "Inputs picklable representation of the message." }, 2141 { "__unicode__", (PyCFunction)ToUnicode, METH_NOARGS, 2142 "Outputs a unicode representation of the message." }, 2143 { "AddDescriptors", (PyCFunction)AddDescriptors, METH_O | METH_CLASS, 2144 "Adds field descriptors to the class" }, 2145 { "ByteSize", (PyCFunction)ByteSize, METH_NOARGS, 2146 "Returns the size of the message in bytes." }, 2147 { "Clear", (PyCFunction)Clear, METH_NOARGS, 2148 "Clears the message." }, 2149 { "ClearExtension", (PyCFunction)ClearExtension, METH_O, 2150 "Clears a message field." }, 2151 { "ClearField", (PyCFunction)ClearField, METH_O, 2152 "Clears a message field." }, 2153 { "CopyFrom", (PyCFunction)CopyFrom, METH_O, 2154 "Copies a protocol message into the current message." }, 2155 { "FindInitializationErrors", (PyCFunction)FindInitializationErrors, 2156 METH_NOARGS, 2157 "Finds unset required fields." }, 2158 { "FromString", (PyCFunction)FromString, METH_O | METH_CLASS, 2159 "Creates new method instance from given serialized data." }, 2160 { "HasExtension", (PyCFunction)HasExtension, METH_O, 2161 "Checks if a message field is set." }, 2162 { "HasField", (PyCFunction)HasField, METH_O, 2163 "Checks if a message field is set." }, 2164 { "IsInitialized", (PyCFunction)IsInitialized, METH_VARARGS, 2165 "Checks if all required fields of a protocol message are set." }, 2166 { "ListFields", (PyCFunction)ListFields, METH_NOARGS, 2167 "Lists all set fields of a message." }, 2168 { "MergeFrom", (PyCFunction)MergeFrom, METH_O, 2169 "Merges a protocol message into the current message." }, 2170 { "MergeFromString", (PyCFunction)MergeFromString, METH_O, 2171 "Merges a serialized message into the current message." }, 2172 { "ParseFromString", (PyCFunction)ParseFromString, METH_O, 2173 "Parses a serialized message into the current message." }, 2174 { "RegisterExtension", (PyCFunction)RegisterExtension, METH_O | METH_CLASS, 2175 "Registers an extension with the current message." }, 2176 { "SerializePartialToString", (PyCFunction)SerializePartialToString, 2177 METH_NOARGS, 2178 "Serializes the message to a string, even if it isn't initialized." }, 2179 { "SerializeToString", (PyCFunction)SerializeToString, METH_NOARGS, 2180 "Serializes the message to a string, only for initialized messages." }, 2181 { "SetInParent", (PyCFunction)SetInParent, METH_NOARGS, 2182 "Sets the has bit of the given field in its parent message." }, 2183 { "WhichOneof", (PyCFunction)WhichOneof, METH_O, 2184 "Returns the name of the field set inside a oneof, " 2185 "or None if no field is set." }, 2186 2187 // Static Methods. 2188 { "_BuildFile", (PyCFunction)Python_BuildFile, METH_O | METH_STATIC, 2189 "Registers a new protocol buffer file in the global C++ descriptor pool." }, 2190 { "_GetFieldDescriptor", (PyCFunction)_GetFieldDescriptor, 2191 METH_O | METH_STATIC, "Finds a field descriptor in the message pool." }, 2192 { "_GetExtensionDescriptor", (PyCFunction)_GetExtensionDescriptor, 2193 METH_O | METH_STATIC, 2194 "Finds a extension descriptor in the message pool." }, 2195 { NULL, NULL} 2196}; 2197 2198PyObject* GetAttr(CMessage* self, PyObject* name) { 2199 PyObject* value = PyDict_GetItem(self->composite_fields, name); 2200 if (value != NULL) { 2201 Py_INCREF(value); 2202 return value; 2203 } 2204 2205 PyObject* descriptor = GetDescriptor(self, name); 2206 if (descriptor != NULL) { 2207 CFieldDescriptor* cdescriptor = 2208 reinterpret_cast<CFieldDescriptor*>(descriptor); 2209 const google::protobuf::FieldDescriptor* field_descriptor = cdescriptor->descriptor; 2210 if (field_descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) { 2211 if (field_descriptor->cpp_type() == 2212 google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) { 2213 PyObject* py_container = PyObject_CallObject( 2214 reinterpret_cast<PyObject*>(&RepeatedCompositeContainer_Type), 2215 NULL); 2216 if (py_container == NULL) { 2217 return NULL; 2218 } 2219 RepeatedCompositeContainer* container = 2220 reinterpret_cast<RepeatedCompositeContainer*>(py_container); 2221 PyObject* field = cdescriptor->descriptor_field; 2222 PyObject* message_type = PyObject_GetAttr(field, kmessage_type); 2223 if (message_type == NULL) { 2224 return NULL; 2225 } 2226 PyObject* concrete_class = 2227 PyObject_GetAttr(message_type, k_concrete_class); 2228 if (concrete_class == NULL) { 2229 return NULL; 2230 } 2231 container->parent = self; 2232 container->parent_field = cdescriptor; 2233 container->message = self->message; 2234 container->owner = self->owner; 2235 container->subclass_init = concrete_class; 2236 Py_DECREF(message_type); 2237 if (PyDict_SetItem(self->composite_fields, name, py_container) < 0) { 2238 Py_DECREF(py_container); 2239 return NULL; 2240 } 2241 return py_container; 2242 } else { 2243 ScopedPyObjectPtr init_args(PyTuple_Pack(2, self, cdescriptor)); 2244 PyObject* py_container = PyObject_CallObject( 2245 reinterpret_cast<PyObject*>(&RepeatedScalarContainer_Type), 2246 init_args); 2247 if (py_container == NULL) { 2248 return NULL; 2249 } 2250 if (PyDict_SetItem(self->composite_fields, name, py_container) < 0) { 2251 Py_DECREF(py_container); 2252 return NULL; 2253 } 2254 return py_container; 2255 } 2256 } else { 2257 if (field_descriptor->cpp_type() == 2258 google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) { 2259 PyObject* sub_message = InternalGetSubMessage(self, cdescriptor); 2260 if (PyDict_SetItem(self->composite_fields, name, sub_message) < 0) { 2261 Py_DECREF(sub_message); 2262 return NULL; 2263 } 2264 return sub_message; 2265 } else { 2266 return InternalGetScalar(self, field_descriptor); 2267 } 2268 } 2269 } 2270 2271 return CMessage_Type.tp_base->tp_getattro(reinterpret_cast<PyObject*>(self), 2272 name); 2273} 2274 2275int SetAttr(CMessage* self, PyObject* name, PyObject* value) { 2276 if (PyDict_Contains(self->composite_fields, name)) { 2277 PyErr_SetString(PyExc_TypeError, "Can't set composite field"); 2278 return -1; 2279 } 2280 2281 PyObject* descriptor = GetDescriptor(self, name); 2282 if (descriptor != NULL) { 2283 AssureWritable(self); 2284 CFieldDescriptor* cdescriptor = 2285 reinterpret_cast<CFieldDescriptor*>(descriptor); 2286 const google::protobuf::FieldDescriptor* field_descriptor = cdescriptor->descriptor; 2287 if (field_descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) { 2288 PyErr_Format(PyExc_AttributeError, "Assignment not allowed to repeated " 2289 "field \"%s\" in protocol message object.", 2290 field_descriptor->name().c_str()); 2291 return -1; 2292 } else { 2293 if (field_descriptor->cpp_type() == 2294 google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) { 2295 PyErr_Format(PyExc_AttributeError, "Assignment not allowed to " 2296 "field \"%s\" in protocol message object.", 2297 field_descriptor->name().c_str()); 2298 return -1; 2299 } else { 2300 return InternalSetScalar(self, field_descriptor, value); 2301 } 2302 } 2303 } 2304 2305 PyErr_Format(PyExc_AttributeError, "Assignment not allowed"); 2306 return -1; 2307} 2308 2309} // namespace cmessage 2310 2311PyTypeObject CMessage_Type = { 2312 PyVarObject_HEAD_INIT(&PyType_Type, 0) 2313 "google.protobuf.internal." 2314 "cpp._message.CMessage", // tp_name 2315 sizeof(CMessage), // tp_basicsize 2316 0, // tp_itemsize 2317 (destructor)cmessage::Dealloc, // tp_dealloc 2318 0, // tp_print 2319 0, // tp_getattr 2320 0, // tp_setattr 2321 0, // tp_compare 2322 0, // tp_repr 2323 0, // tp_as_number 2324 0, // tp_as_sequence 2325 0, // tp_as_mapping 2326 0, // tp_hash 2327 0, // tp_call 2328 (reprfunc)cmessage::ToStr, // tp_str 2329 (getattrofunc)cmessage::GetAttr, // tp_getattro 2330 (setattrofunc)cmessage::SetAttr, // tp_setattro 2331 0, // tp_as_buffer 2332 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags 2333 "A ProtocolMessage", // tp_doc 2334 0, // tp_traverse 2335 0, // tp_clear 2336 (richcmpfunc)cmessage::RichCompare, // tp_richcompare 2337 0, // tp_weaklistoffset 2338 0, // tp_iter 2339 0, // tp_iternext 2340 cmessage::Methods, // tp_methods 2341 cmessage::Members, // tp_members 2342 0, // tp_getset 2343 0, // tp_base 2344 0, // tp_dict 2345 0, // tp_descr_get 2346 0, // tp_descr_set 2347 0, // tp_dictoffset 2348 (initproc)cmessage::Init, // tp_init 2349 0, // tp_alloc 2350 cmessage::New, // tp_new 2351}; 2352 2353// --- Exposing the C proto living inside Python proto to C code: 2354 2355const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg); 2356Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg); 2357 2358static const google::protobuf::Message* GetCProtoInsidePyProtoImpl(PyObject* msg) { 2359 if (!PyObject_TypeCheck(msg, &CMessage_Type)) { 2360 return NULL; 2361 } 2362 CMessage* cmsg = reinterpret_cast<CMessage*>(msg); 2363 return cmsg->message; 2364} 2365 2366static google::protobuf::Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) { 2367 if (!PyObject_TypeCheck(msg, &CMessage_Type)) { 2368 return NULL; 2369 } 2370 CMessage* cmsg = reinterpret_cast<CMessage*>(msg); 2371 if (PyDict_Size(cmsg->composite_fields) != 0 || 2372 (cmsg->extensions != NULL && 2373 PyDict_Size(cmsg->extensions->values) != 0)) { 2374 // There is currently no way of accurately syncing arbitrary changes to 2375 // the underlying C++ message back to the CMessage (e.g. removed repeated 2376 // composite containers). We only allow direct mutation of the underlying 2377 // C++ message if there is no child data in the CMessage. 2378 return NULL; 2379 } 2380 cmessage::AssureWritable(cmsg); 2381 return cmsg->message; 2382} 2383 2384static const char module_docstring[] = 2385"python-proto2 is a module that can be used to enhance proto2 Python API\n" 2386"performance.\n" 2387"\n" 2388"It provides access to the protocol buffers C++ reflection API that\n" 2389"implements the basic protocol buffer functions."; 2390 2391void InitGlobals() { 2392 // TODO(gps): Check all return values in this function for NULL and propagate 2393 // the error (MemoryError) on up to result in an import failure. These should 2394 // also be freed and reset to NULL during finalization. 2395 kPythonZero = PyInt_FromLong(0); 2396 kint32min_py = PyInt_FromLong(kint32min); 2397 kint32max_py = PyInt_FromLong(kint32max); 2398 kuint32max_py = PyLong_FromLongLong(kuint32max); 2399 kint64min_py = PyLong_FromLongLong(kint64min); 2400 kint64max_py = PyLong_FromLongLong(kint64max); 2401 kuint64max_py = PyLong_FromUnsignedLongLong(kuint64max); 2402 2403 kDESCRIPTOR = PyString_FromString("DESCRIPTOR"); 2404 k__descriptors = PyString_FromString("__descriptors"); 2405 kfull_name = PyString_FromString("full_name"); 2406 kis_extendable = PyString_FromString("is_extendable"); 2407 kextensions_by_name = PyString_FromString("extensions_by_name"); 2408 k_extensions_by_name = PyString_FromString("_extensions_by_name"); 2409 k_extensions_by_number = PyString_FromString("_extensions_by_number"); 2410 k_concrete_class = PyString_FromString("_concrete_class"); 2411 kmessage_type = PyString_FromString("message_type"); 2412 kname = PyString_FromString("name"); 2413 kfields_by_name = PyString_FromString("fields_by_name"); 2414 2415 global_message_factory = new DynamicMessageFactory(GetDescriptorPool()); 2416 global_message_factory->SetDelegateToGeneratedFactory(true); 2417 2418 descriptor_pool = reinterpret_cast<google::protobuf::python::CDescriptorPool*>( 2419 Python_NewCDescriptorPool(NULL, NULL)); 2420} 2421 2422bool InitProto2MessageModule(PyObject *m) { 2423 InitGlobals(); 2424 2425 google::protobuf::python::CMessage_Type.tp_hash = PyObject_HashNotImplemented; 2426 if (PyType_Ready(&google::protobuf::python::CMessage_Type) < 0) { 2427 return false; 2428 } 2429 2430 // All three of these are actually set elsewhere, directly onto the child 2431 // protocol buffer message class, but set them here as well to document that 2432 // subclasses need to set these. 2433 PyDict_SetItem(google::protobuf::python::CMessage_Type.tp_dict, kDESCRIPTOR, Py_None); 2434 PyDict_SetItem(google::protobuf::python::CMessage_Type.tp_dict, 2435 k_extensions_by_name, Py_None); 2436 PyDict_SetItem(google::protobuf::python::CMessage_Type.tp_dict, 2437 k_extensions_by_number, Py_None); 2438 2439 PyModule_AddObject(m, "Message", reinterpret_cast<PyObject*>( 2440 &google::protobuf::python::CMessage_Type)); 2441 2442 google::protobuf::python::RepeatedScalarContainer_Type.tp_new = PyType_GenericNew; 2443 google::protobuf::python::RepeatedScalarContainer_Type.tp_hash = 2444 PyObject_HashNotImplemented; 2445 if (PyType_Ready(&google::protobuf::python::RepeatedScalarContainer_Type) < 0) { 2446 return false; 2447 } 2448 2449 PyModule_AddObject(m, "RepeatedScalarContainer", 2450 reinterpret_cast<PyObject*>( 2451 &google::protobuf::python::RepeatedScalarContainer_Type)); 2452 2453 google::protobuf::python::RepeatedCompositeContainer_Type.tp_new = PyType_GenericNew; 2454 google::protobuf::python::RepeatedCompositeContainer_Type.tp_hash = 2455 PyObject_HashNotImplemented; 2456 if (PyType_Ready(&google::protobuf::python::RepeatedCompositeContainer_Type) < 0) { 2457 return false; 2458 } 2459 2460 PyModule_AddObject( 2461 m, "RepeatedCompositeContainer", 2462 reinterpret_cast<PyObject*>( 2463 &google::protobuf::python::RepeatedCompositeContainer_Type)); 2464 2465 google::protobuf::python::ExtensionDict_Type.tp_new = PyType_GenericNew; 2466 google::protobuf::python::ExtensionDict_Type.tp_hash = PyObject_HashNotImplemented; 2467 if (PyType_Ready(&google::protobuf::python::ExtensionDict_Type) < 0) { 2468 return false; 2469 } 2470 2471 PyModule_AddObject( 2472 m, "ExtensionDict", 2473 reinterpret_cast<PyObject*>(&google::protobuf::python::ExtensionDict_Type)); 2474 2475 if (!google::protobuf::python::InitDescriptor()) { 2476 return false; 2477 } 2478 2479 PyObject* enum_type_wrapper = PyImport_ImportModule( 2480 "google.protobuf.internal.enum_type_wrapper"); 2481 if (enum_type_wrapper == NULL) { 2482 return false; 2483 } 2484 google::protobuf::python::EnumTypeWrapper_class = 2485 PyObject_GetAttrString(enum_type_wrapper, "EnumTypeWrapper"); 2486 Py_DECREF(enum_type_wrapper); 2487 2488 PyObject* message_module = PyImport_ImportModule( 2489 "google.protobuf.message"); 2490 if (message_module == NULL) { 2491 return false; 2492 } 2493 google::protobuf::python::EncodeError_class = PyObject_GetAttrString(message_module, 2494 "EncodeError"); 2495 google::protobuf::python::DecodeError_class = PyObject_GetAttrString(message_module, 2496 "DecodeError"); 2497 Py_DECREF(message_module); 2498 2499 PyObject* pickle_module = PyImport_ImportModule("pickle"); 2500 if (pickle_module == NULL) { 2501 return false; 2502 } 2503 google::protobuf::python::PickleError_class = PyObject_GetAttrString(pickle_module, 2504 "PickleError"); 2505 Py_DECREF(pickle_module); 2506 2507 // Override {Get,Mutable}CProtoInsidePyProto. 2508 google::protobuf::python::GetCProtoInsidePyProtoPtr = 2509 google::protobuf::python::GetCProtoInsidePyProtoImpl; 2510 google::protobuf::python::MutableCProtoInsidePyProtoPtr = 2511 google::protobuf::python::MutableCProtoInsidePyProtoImpl; 2512 2513 return true; 2514} 2515 2516} // namespace python 2517} // namespace protobuf 2518 2519 2520#if PY_MAJOR_VERSION >= 3 2521static struct PyModuleDef _module = { 2522 PyModuleDef_HEAD_INIT, 2523 "_message", 2524 google::protobuf::python::module_docstring, 2525 -1, 2526 NULL, 2527 NULL, 2528 NULL, 2529 NULL, 2530 NULL 2531}; 2532#define INITFUNC PyInit__message 2533#define INITFUNC_ERRORVAL NULL 2534#else // Python 2 2535#define INITFUNC init_message 2536#define INITFUNC_ERRORVAL 2537#endif 2538 2539extern "C" { 2540 PyMODINIT_FUNC INITFUNC(void) { 2541 PyObject* m; 2542#if PY_MAJOR_VERSION >= 3 2543 m = PyModule_Create(&_module); 2544#else 2545 m = Py_InitModule3("_message", NULL, google::protobuf::python::module_docstring); 2546#endif 2547 if (m == NULL) { 2548 return INITFUNC_ERRORVAL; 2549 } 2550 2551 if (!google::protobuf::python::InitProto2MessageModule(m)) { 2552 Py_DECREF(m); 2553 return INITFUNC_ERRORVAL; 2554 } 2555 2556#if PY_MAJOR_VERSION >= 3 2557 return m; 2558#endif 2559 } 2560} 2561} // namespace google 2562