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