1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 // Author: anuraag@google.com (Anuraag Agrawal) 32 // Author: tibell@google.com (Johan Tibell) 33 34 #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__ 35 #define GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__ 36 37 #include <Python.h> 38 39 #include <memory> 40 #ifndef _SHARED_PTR_H 41 #include <google/protobuf/stubs/shared_ptr.h> 42 #endif 43 #include <string> 44 45 namespace google { 46 namespace protobuf { 47 48 class Message; 49 class Reflection; 50 class FieldDescriptor; 51 class Descriptor; 52 class DescriptorPool; 53 class MessageFactory; 54 55 #ifdef _SHARED_PTR_H 56 using std::shared_ptr; 57 using ::std::string; 58 #else 59 using internal::shared_ptr; 60 #endif 61 62 namespace python { 63 64 struct ExtensionDict; 65 struct PyDescriptorPool; 66 67 typedef struct CMessage { 68 PyObject_HEAD; 69 70 // This is the top-level C++ Message object that owns the whole 71 // proto tree. Every Python CMessage holds a reference to it in 72 // order to keep it alive as long as there's a Python object that 73 // references any part of the tree. 74 shared_ptr<Message> owner; 75 76 // Weak reference to a parent CMessage object. This is NULL for any top-level 77 // message and is set for any child message (i.e. a child submessage or a 78 // part of a repeated composite field). 79 // 80 // Used to make sure all ancestors are also mutable when first modifying 81 // a child submessage (in other words, turning a default message instance 82 // into a mutable one). 83 // 84 // If a submessage is released (becomes a new top-level message), this field 85 // MUST be set to NULL. The parent may get deallocated and further attempts 86 // to use this pointer will result in a crash. 87 struct CMessage* parent; 88 89 // Pointer to the parent's descriptor that describes this submessage. 90 // Used together with the parent's message when making a default message 91 // instance mutable. 92 // The pointer is owned by the global DescriptorPool. 93 const FieldDescriptor* parent_field_descriptor; 94 95 // Pointer to the C++ Message object for this CMessage. The 96 // CMessage does not own this pointer. 97 Message* message; 98 99 // Indicates this submessage is pointing to a default instance of a message. 100 // Submessages are always first created as read only messages and are then 101 // made writable, at which point this field is set to false. 102 bool read_only; 103 104 // A reference to a Python dictionary containing CMessage, 105 // RepeatedCompositeContainer, and RepeatedScalarContainer 106 // objects. Used as a cache to make sure we don't have to make a 107 // Python wrapper for the C++ Message objects on every access, or 108 // deal with the synchronization nightmare that could create. 109 PyObject* composite_fields; 110 111 // A reference to the dictionary containing the message's extensions. 112 // Similar to composite_fields, acting as a cache, but also contains the 113 // required extension dict logic. 114 ExtensionDict* extensions; 115 } CMessage; 116 117 extern PyTypeObject CMessage_Type; 118 119 120 // The (meta) type of all Messages classes. 121 // It allows us to cache some C++ pointers in the class object itself, they are 122 // faster to extract than from the type's dictionary. 123 124 struct CMessageClass { 125 // This is how CPython subclasses C structures: the base structure must be 126 // the first member of the object. 127 PyHeapTypeObject super; 128 129 // C++ descriptor of this message. 130 const Descriptor* message_descriptor; 131 132 // Owned reference, used to keep the pointer above alive. 133 PyObject* py_message_descriptor; 134 135 // The Python DescriptorPool used to create the class. It is needed to resolve 136 // fields descriptors, including extensions fields; its C++ MessageFactory is 137 // used to instantiate submessages. 138 // This can be different from DESCRIPTOR.file.pool, in the case of a custom 139 // DescriptorPool which defines new extensions. 140 // We own the reference, because it's important to keep the descriptors and 141 // factory alive. 142 PyDescriptorPool* py_descriptor_pool; 143 AsPyObjectCMessageClass144 PyObject* AsPyObject() { 145 return reinterpret_cast<PyObject*>(this); 146 } 147 }; 148 149 150 namespace cmessage { 151 152 // Internal function to create a new empty Message Python object, but with empty 153 // pointers to the C++ objects. 154 // The caller must fill self->message, self->owner and eventually self->parent. 155 CMessage* NewEmptyMessage(CMessageClass* type); 156 157 // Release a submessage from its proto tree, making it a new top-level messgae. 158 // A new message will be created if this is a read-only default instance. 159 // 160 // Corresponds to reflection api method ReleaseMessage. 161 int ReleaseSubMessage(CMessage* self, 162 const FieldDescriptor* field_descriptor, 163 CMessage* child_cmessage); 164 165 // Retrieves the C++ descriptor of a Python Extension descriptor. 166 // On error, return NULL with an exception set. 167 const FieldDescriptor* GetExtensionDescriptor(PyObject* extension); 168 169 // Initializes a new CMessage instance for a submessage. Only called once per 170 // submessage as the result is cached in composite_fields. 171 // 172 // Corresponds to reflection api method GetMessage. 173 PyObject* InternalGetSubMessage( 174 CMessage* self, const FieldDescriptor* field_descriptor); 175 176 // Deletes a range of C++ submessages in a repeated field (following a 177 // removal in a RepeatedCompositeContainer). 178 // 179 // Releases messages to the provided cmessage_list if it is not NULL rather 180 // than just removing them from the underlying proto. This cmessage_list must 181 // have a CMessage for each underlying submessage. The CMessages referred to 182 // by slice will be removed from cmessage_list by this function. 183 // 184 // Corresponds to reflection api method RemoveLast. 185 int InternalDeleteRepeatedField(CMessage* self, 186 const FieldDescriptor* field_descriptor, 187 PyObject* slice, PyObject* cmessage_list); 188 189 // Sets the specified scalar value to the message. 190 int InternalSetScalar(CMessage* self, 191 const FieldDescriptor* field_descriptor, 192 PyObject* value); 193 194 // Sets the specified scalar value to the message. Requires it is not a Oneof. 195 int InternalSetNonOneofScalar(Message* message, 196 const FieldDescriptor* field_descriptor, 197 PyObject* arg); 198 199 // Retrieves the specified scalar value from the message. 200 // 201 // Returns a new python reference. 202 PyObject* InternalGetScalar(const Message* message, 203 const FieldDescriptor* field_descriptor); 204 205 // Clears the message, removing all contained data. Extension dictionary and 206 // submessages are released first if there are remaining external references. 207 // 208 // Corresponds to message api method Clear. 209 PyObject* Clear(CMessage* self); 210 211 // Clears the data described by the given descriptor. Used to clear extensions 212 // (which don't have names). Extension release is handled by ExtensionDict 213 // class, not this function. 214 // TODO(anuraag): Try to make this discrepancy in release semantics with 215 // ClearField less confusing. 216 // 217 // Corresponds to reflection api method ClearField. 218 PyObject* ClearFieldByDescriptor( 219 CMessage* self, const FieldDescriptor* descriptor); 220 221 // Clears the data for the given field name. The message is released if there 222 // are any external references. 223 // 224 // Corresponds to reflection api method ClearField. 225 PyObject* ClearField(CMessage* self, PyObject* arg); 226 227 // Checks if the message has the field described by the descriptor. Used for 228 // extensions (which have no name). 229 // 230 // Corresponds to reflection api method HasField 231 PyObject* HasFieldByDescriptor( 232 CMessage* self, const FieldDescriptor* field_descriptor); 233 234 // Checks if the message has the named field. 235 // 236 // Corresponds to reflection api method HasField. 237 PyObject* HasField(CMessage* self, PyObject* arg); 238 239 // Initializes values of fields on a newly constructed message. 240 int InitAttributes(CMessage* self, PyObject* kwargs); 241 242 PyObject* MergeFrom(CMessage* self, PyObject* arg); 243 244 // Retrieves an attribute named 'name' from CMessage 'self'. Returns 245 // the attribute value on success, or NULL on failure. 246 // 247 // Returns a new reference. 248 PyObject* GetAttr(CMessage* self, PyObject* name); 249 250 // Set the value of the attribute named 'name', for CMessage 'self', 251 // to the value 'value'. Returns -1 on failure. 252 int SetAttr(CMessage* self, PyObject* name, PyObject* value); 253 254 PyObject* FindInitializationErrors(CMessage* self); 255 256 // Set the owner field of self and any children of self, recursively. 257 // Used when self is being released and thus has a new owner (the 258 // released Message.) 259 int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner); 260 261 int AssureWritable(CMessage* self); 262 263 // Returns the "best" DescriptorPool for the given message. 264 // This is often equivalent to message.DESCRIPTOR.pool, but not always, when 265 // the message class was created from a MessageFactory using a custom pool which 266 // uses the generated pool as an underlay. 267 // 268 // The returned pool is suitable for finding fields and building submessages, 269 // even in the case of extensions. 270 PyDescriptorPool* GetDescriptorPoolForMessage(CMessage* message); 271 272 } // namespace cmessage 273 274 275 /* Is 64bit */ 276 #define IS_64BIT (SIZEOF_LONG == 8) 277 278 #define FIELD_IS_REPEATED(field_descriptor) \ 279 ((field_descriptor)->label() == FieldDescriptor::LABEL_REPEATED) 280 281 #define GOOGLE_CHECK_GET_INT32(arg, value, err) \ 282 int32 value; \ 283 if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \ 284 return err; \ 285 } 286 287 #define GOOGLE_CHECK_GET_INT64(arg, value, err) \ 288 int64 value; \ 289 if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \ 290 return err; \ 291 } 292 293 #define GOOGLE_CHECK_GET_UINT32(arg, value, err) \ 294 uint32 value; \ 295 if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \ 296 return err; \ 297 } 298 299 #define GOOGLE_CHECK_GET_UINT64(arg, value, err) \ 300 uint64 value; \ 301 if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \ 302 return err; \ 303 } 304 305 #define GOOGLE_CHECK_GET_FLOAT(arg, value, err) \ 306 float value; \ 307 if (!CheckAndGetFloat(arg, &value)) { \ 308 return err; \ 309 } \ 310 311 #define GOOGLE_CHECK_GET_DOUBLE(arg, value, err) \ 312 double value; \ 313 if (!CheckAndGetDouble(arg, &value)) { \ 314 return err; \ 315 } 316 317 #define GOOGLE_CHECK_GET_BOOL(arg, value, err) \ 318 bool value; \ 319 if (!CheckAndGetBool(arg, &value)) { \ 320 return err; \ 321 } 322 323 324 extern PyObject* kPythonZero; 325 extern PyObject* kint32min_py; 326 extern PyObject* kint32max_py; 327 extern PyObject* kuint32max_py; 328 extern PyObject* kint64min_py; 329 extern PyObject* kint64max_py; 330 extern PyObject* kuint64max_py; 331 332 #define FULL_MODULE_NAME "google.protobuf.pyext._message" 333 334 void FormatTypeError(PyObject* arg, char* expected_types); 335 template<class T> 336 bool CheckAndGetInteger( 337 PyObject* arg, T* value, PyObject* min, PyObject* max); 338 bool CheckAndGetDouble(PyObject* arg, double* value); 339 bool CheckAndGetFloat(PyObject* arg, float* value); 340 bool CheckAndGetBool(PyObject* arg, bool* value); 341 PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor); 342 bool CheckAndSetString( 343 PyObject* arg, Message* message, 344 const FieldDescriptor* descriptor, 345 const Reflection* reflection, 346 bool append, 347 int index); 348 PyObject* ToStringObject(const FieldDescriptor* descriptor, string value); 349 350 // Check if the passed field descriptor belongs to the given message. 351 // If not, return false and set a Python exception (a KeyError) 352 bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor, 353 const Message* message); 354 355 extern PyObject* PickleError_class; 356 357 } // namespace python 358 } // namespace protobuf 359 360 } // namespace google 361 #endif // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__ 362