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 // Note that positional arguments are disallowed: 'args' must be NULL or the 241 // empty tuple. 242 int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs); 243 244 PyObject* MergeFrom(CMessage* self, PyObject* arg); 245 246 // Retrieves an attribute named 'name' from CMessage 'self'. Returns 247 // the attribute value on success, or NULL on failure. 248 // 249 // Returns a new reference. 250 PyObject* GetAttr(CMessage* self, PyObject* name); 251 252 // Set the value of the attribute named 'name', for CMessage 'self', 253 // to the value 'value'. Returns -1 on failure. 254 int SetAttr(CMessage* self, PyObject* name, PyObject* value); 255 256 PyObject* FindInitializationErrors(CMessage* self); 257 258 // Set the owner field of self and any children of self, recursively. 259 // Used when self is being released and thus has a new owner (the 260 // released Message.) 261 int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner); 262 263 int AssureWritable(CMessage* self); 264 265 // Returns the "best" DescriptorPool for the given message. 266 // This is often equivalent to message.DESCRIPTOR.pool, but not always, when 267 // the message class was created from a MessageFactory using a custom pool which 268 // uses the generated pool as an underlay. 269 // 270 // The returned pool is suitable for finding fields and building submessages, 271 // even in the case of extensions. 272 PyDescriptorPool* GetDescriptorPoolForMessage(CMessage* message); 273 274 PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg); 275 276 } // namespace cmessage 277 278 279 /* Is 64bit */ 280 #define IS_64BIT (SIZEOF_LONG == 8) 281 282 #define FIELD_IS_REPEATED(field_descriptor) \ 283 ((field_descriptor)->label() == FieldDescriptor::LABEL_REPEATED) 284 285 #define GOOGLE_CHECK_GET_INT32(arg, value, err) \ 286 int32 value; \ 287 if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \ 288 return err; \ 289 } 290 291 #define GOOGLE_CHECK_GET_INT64(arg, value, err) \ 292 int64 value; \ 293 if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \ 294 return err; \ 295 } 296 297 #define GOOGLE_CHECK_GET_UINT32(arg, value, err) \ 298 uint32 value; \ 299 if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \ 300 return err; \ 301 } 302 303 #define GOOGLE_CHECK_GET_UINT64(arg, value, err) \ 304 uint64 value; \ 305 if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \ 306 return err; \ 307 } 308 309 #define GOOGLE_CHECK_GET_FLOAT(arg, value, err) \ 310 float value; \ 311 if (!CheckAndGetFloat(arg, &value)) { \ 312 return err; \ 313 } \ 314 315 #define GOOGLE_CHECK_GET_DOUBLE(arg, value, err) \ 316 double value; \ 317 if (!CheckAndGetDouble(arg, &value)) { \ 318 return err; \ 319 } 320 321 #define GOOGLE_CHECK_GET_BOOL(arg, value, err) \ 322 bool value; \ 323 if (!CheckAndGetBool(arg, &value)) { \ 324 return err; \ 325 } 326 327 328 extern PyObject* kPythonZero; 329 extern PyObject* kint32min_py; 330 extern PyObject* kint32max_py; 331 extern PyObject* kuint32max_py; 332 extern PyObject* kint64min_py; 333 extern PyObject* kint64max_py; 334 extern PyObject* kuint64max_py; 335 336 #define FULL_MODULE_NAME "google.protobuf.pyext._message" 337 338 void FormatTypeError(PyObject* arg, char* expected_types); 339 template<class T> 340 bool CheckAndGetInteger( 341 PyObject* arg, T* value, PyObject* min, PyObject* max); 342 bool CheckAndGetDouble(PyObject* arg, double* value); 343 bool CheckAndGetFloat(PyObject* arg, float* value); 344 bool CheckAndGetBool(PyObject* arg, bool* value); 345 PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor); 346 bool CheckAndSetString( 347 PyObject* arg, Message* message, 348 const FieldDescriptor* descriptor, 349 const Reflection* reflection, 350 bool append, 351 int index); 352 PyObject* ToStringObject(const FieldDescriptor* descriptor, string value); 353 354 // Check if the passed field descriptor belongs to the given message. 355 // If not, return false and set a Python exception (a KeyError) 356 bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor, 357 const Message* message); 358 359 extern PyObject* PickleError_class; 360 361 bool InitProto2MessageModule(PyObject *m); 362 363 } // namespace python 364 } // namespace protobuf 365 366 } // namespace google 367 #endif // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__ 368