| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 | 47 |
| 48 class Message; | 48 class Message; |
| 49 class Reflection; | 49 class Reflection; |
| 50 class FieldDescriptor; | 50 class FieldDescriptor; |
| 51 class Descriptor; | 51 class Descriptor; |
| 52 class DescriptorPool; | 52 class DescriptorPool; |
| 53 class MessageFactory; | 53 class MessageFactory; |
| 54 | 54 |
| 55 #ifdef _SHARED_PTR_H | 55 #ifdef _SHARED_PTR_H |
| 56 using std::shared_ptr; | 56 using std::shared_ptr; |
| 57 using std::string; | 57 using ::std::string; |
| 58 #else | 58 #else |
| 59 using internal::shared_ptr; | 59 using internal::shared_ptr; |
| 60 #endif | 60 #endif |
| 61 | 61 |
| 62 namespace python { | 62 namespace python { |
| 63 | 63 |
| 64 struct ExtensionDict; | 64 struct ExtensionDict; |
| 65 struct PyMessageFactory; | 65 struct PyDescriptorPool; |
| 66 | 66 |
| 67 typedef struct CMessage { | 67 typedef struct CMessage { |
| 68 PyObject_HEAD; | 68 PyObject_HEAD; |
| 69 | 69 |
| 70 // This is the top-level C++ Message object that owns the whole | 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 | 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 | 72 // order to keep it alive as long as there's a Python object that |
| 73 // references any part of the tree. | 73 // references any part of the tree. |
| 74 shared_ptr<Message> owner; | 74 shared_ptr<Message> owner; |
| 75 | 75 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 105 // RepeatedCompositeContainer, and RepeatedScalarContainer | 105 // RepeatedCompositeContainer, and RepeatedScalarContainer |
| 106 // objects. Used as a cache to make sure we don't have to make a | 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 | 107 // Python wrapper for the C++ Message objects on every access, or |
| 108 // deal with the synchronization nightmare that could create. | 108 // deal with the synchronization nightmare that could create. |
| 109 PyObject* composite_fields; | 109 PyObject* composite_fields; |
| 110 | 110 |
| 111 // A reference to the dictionary containing the message's extensions. | 111 // A reference to the dictionary containing the message's extensions. |
| 112 // Similar to composite_fields, acting as a cache, but also contains the | 112 // Similar to composite_fields, acting as a cache, but also contains the |
| 113 // required extension dict logic. | 113 // required extension dict logic. |
| 114 ExtensionDict* extensions; | 114 ExtensionDict* extensions; |
| 115 | |
| 116 // Implements the "weakref" protocol for this object. | |
| 117 PyObject* weakreflist; | |
| 118 } CMessage; | 115 } CMessage; |
| 119 | 116 |
| 120 extern PyTypeObject CMessageClass_Type; | |
| 121 extern PyTypeObject CMessage_Type; | 117 extern PyTypeObject CMessage_Type; |
| 122 | 118 |
| 123 | 119 |
| 124 // The (meta) type of all Messages classes. | 120 // The (meta) type of all Messages classes. |
| 125 // It allows us to cache some C++ pointers in the class object itself, they are | 121 // It allows us to cache some C++ pointers in the class object itself, they are |
| 126 // faster to extract than from the type's dictionary. | 122 // faster to extract than from the type's dictionary. |
| 127 | 123 |
| 128 struct CMessageClass { | 124 struct CMessageClass { |
| 129 // This is how CPython subclasses C structures: the base structure must be | 125 // This is how CPython subclasses C structures: the base structure must be |
| 130 // the first member of the object. | 126 // the first member of the object. |
| 131 PyHeapTypeObject super; | 127 PyHeapTypeObject super; |
| 132 | 128 |
| 133 // C++ descriptor of this message. | 129 // C++ descriptor of this message. |
| 134 const Descriptor* message_descriptor; | 130 const Descriptor* message_descriptor; |
| 135 | 131 |
| 136 // Owned reference, used to keep the pointer above alive. | 132 // Owned reference, used to keep the pointer above alive. |
| 137 PyObject* py_message_descriptor; | 133 PyObject* py_message_descriptor; |
| 138 | 134 |
| 139 // The Python MessageFactory used to create the class. It is needed to resolve | 135 // The Python DescriptorPool used to create the class. It is needed to resolve |
| 140 // fields descriptors, including extensions fields; its C++ MessageFactory is | 136 // fields descriptors, including extensions fields; its C++ MessageFactory is |
| 141 // used to instantiate submessages. | 137 // used to instantiate submessages. |
| 142 // We own the reference, because it's important to keep the factory alive. | 138 // This can be different from DESCRIPTOR.file.pool, in the case of a custom |
| 143 PyMessageFactory* py_message_factory; | 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; |
| 144 | 143 |
| 145 PyObject* AsPyObject() { | 144 PyObject* AsPyObject() { |
| 146 return reinterpret_cast<PyObject*>(this); | 145 return reinterpret_cast<PyObject*>(this); |
| 147 } | 146 } |
| 148 }; | 147 }; |
| 149 | 148 |
| 150 | 149 |
| 151 namespace cmessage { | 150 namespace cmessage { |
| 152 | 151 |
| 153 // Internal function to create a new empty Message Python object, but with empty | 152 // Internal function to create a new empty Message Python object, but with empty |
| 154 // pointers to the C++ objects. | 153 // pointers to the C++ objects. |
| 155 // The caller must fill self->message, self->owner and eventually self->parent. | 154 // The caller must fill self->message, self->owner and eventually self->parent. |
| 156 CMessage* NewEmptyMessage(CMessageClass* type); | 155 CMessage* NewEmptyMessage(CMessageClass* type); |
| 157 | 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 |
| 158 // Retrieves the C++ descriptor of a Python Extension descriptor. | 165 // Retrieves the C++ descriptor of a Python Extension descriptor. |
| 159 // On error, return NULL with an exception set. | 166 // On error, return NULL with an exception set. |
| 160 const FieldDescriptor* GetExtensionDescriptor(PyObject* extension); | 167 const FieldDescriptor* GetExtensionDescriptor(PyObject* extension); |
| 161 | 168 |
| 162 // Initializes a new CMessage instance for a submessage. Only called once per | 169 // Initializes a new CMessage instance for a submessage. Only called once per |
| 163 // submessage as the result is cached in composite_fields. | 170 // submessage as the result is cached in composite_fields. |
| 164 // | 171 // |
| 165 // Corresponds to reflection api method GetMessage. | 172 // Corresponds to reflection api method GetMessage. |
| 166 PyObject* InternalGetSubMessage( | 173 PyObject* InternalGetSubMessage( |
| 167 CMessage* self, const FieldDescriptor* field_descriptor); | 174 CMessage* self, const FieldDescriptor* field_descriptor); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 // Corresponds to reflection api method HasField | 230 // Corresponds to reflection api method HasField |
| 224 PyObject* HasFieldByDescriptor( | 231 PyObject* HasFieldByDescriptor( |
| 225 CMessage* self, const FieldDescriptor* field_descriptor); | 232 CMessage* self, const FieldDescriptor* field_descriptor); |
| 226 | 233 |
| 227 // Checks if the message has the named field. | 234 // Checks if the message has the named field. |
| 228 // | 235 // |
| 229 // Corresponds to reflection api method HasField. | 236 // Corresponds to reflection api method HasField. |
| 230 PyObject* HasField(CMessage* self, PyObject* arg); | 237 PyObject* HasField(CMessage* self, PyObject* arg); |
| 231 | 238 |
| 232 // Initializes values of fields on a newly constructed message. | 239 // Initializes values of fields on a newly constructed message. |
| 233 // Note that positional arguments are disallowed: 'args' must be NULL or the | 240 int InitAttributes(CMessage* self, PyObject* kwargs); |
| 234 // empty tuple. | |
| 235 int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs); | |
| 236 | 241 |
| 237 PyObject* MergeFrom(CMessage* self, PyObject* arg); | 242 PyObject* MergeFrom(CMessage* self, PyObject* arg); |
| 238 | 243 |
| 239 // This method does not do anything beyond checking that no other extension | |
| 240 // has been registered with the same field number on this class. | |
| 241 PyObject* RegisterExtension(PyObject* cls, PyObject* extension_handle); | |
| 242 | |
| 243 // Retrieves an attribute named 'name' from CMessage 'self'. Returns | 244 // Retrieves an attribute named 'name' from CMessage 'self'. Returns |
| 244 // the attribute value on success, or NULL on failure. | 245 // the attribute value on success, or NULL on failure. |
| 245 // | 246 // |
| 246 // Returns a new reference. | 247 // Returns a new reference. |
| 247 PyObject* GetAttr(CMessage* self, PyObject* name); | 248 PyObject* GetAttr(CMessage* self, PyObject* name); |
| 248 | 249 |
| 249 // Set the value of the attribute named 'name', for CMessage 'self', | 250 // Set the value of the attribute named 'name', for CMessage 'self', |
| 250 // to the value 'value'. Returns -1 on failure. | 251 // to the value 'value'. Returns -1 on failure. |
| 251 int SetAttr(CMessage* self, PyObject* name, PyObject* value); | 252 int SetAttr(CMessage* self, PyObject* name, PyObject* value); |
| 252 | 253 |
| 253 PyObject* FindInitializationErrors(CMessage* self); | 254 PyObject* FindInitializationErrors(CMessage* self); |
| 254 | 255 |
| 255 // Set the owner field of self and any children of self, recursively. | 256 // Set the owner field of self and any children of self, recursively. |
| 256 // Used when self is being released and thus has a new owner (the | 257 // Used when self is being released and thus has a new owner (the |
| 257 // released Message.) | 258 // released Message.) |
| 258 int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner); | 259 int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner); |
| 259 | 260 |
| 260 int AssureWritable(CMessage* self); | 261 int AssureWritable(CMessage* self); |
| 261 | 262 |
| 262 // Returns the message factory for the given message. | 263 // Returns the "best" DescriptorPool for the given message. |
| 263 // This is equivalent to message.MESSAGE_FACTORY | 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. |
| 264 // | 267 // |
| 265 // The returned factory is suitable for finding fields and building submessages, | 268 // The returned pool is suitable for finding fields and building submessages, |
| 266 // even in the case of extensions. | 269 // even in the case of extensions. |
| 267 // Returns a *borrowed* reference, and never fails because we pass a CMessage. | 270 PyDescriptorPool* GetDescriptorPoolForMessage(CMessage* message); |
| 268 PyMessageFactory* GetFactoryForMessage(CMessage* message); | |
| 269 | |
| 270 PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg); | |
| 271 | 271 |
| 272 } // namespace cmessage | 272 } // namespace cmessage |
| 273 | 273 |
| 274 | 274 |
| 275 /* Is 64bit */ | 275 /* Is 64bit */ |
| 276 #define IS_64BIT (SIZEOF_LONG == 8) | 276 #define IS_64BIT (SIZEOF_LONG == 8) |
| 277 | 277 |
| 278 #define FIELD_IS_REPEATED(field_descriptor) \ | 278 #define FIELD_IS_REPEATED(field_descriptor) \ |
| 279 ((field_descriptor)->label() == FieldDescriptor::LABEL_REPEATED) | 279 ((field_descriptor)->label() == FieldDescriptor::LABEL_REPEATED) |
| 280 | 280 |
| 281 #define GOOGLE_CHECK_GET_INT32(arg, value, err) \ | 281 #define GOOGLE_CHECK_GET_INT32(arg, value, err) \ |
| 282 int32 value; \ | 282 int32 value; \ |
| 283 if (!CheckAndGetInteger(arg, &value)) { \ | 283 if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \ |
| 284 return err; \ | 284 return err; \ |
| 285 } | 285 } |
| 286 | 286 |
| 287 #define GOOGLE_CHECK_GET_INT64(arg, value, err) \ | 287 #define GOOGLE_CHECK_GET_INT64(arg, value, err) \ |
| 288 int64 value; \ | 288 int64 value; \ |
| 289 if (!CheckAndGetInteger(arg, &value)) { \ | 289 if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \ |
| 290 return err; \ | 290 return err; \ |
| 291 } | 291 } |
| 292 | 292 |
| 293 #define GOOGLE_CHECK_GET_UINT32(arg, value, err) \ | 293 #define GOOGLE_CHECK_GET_UINT32(arg, value, err) \ |
| 294 uint32 value; \ | 294 uint32 value; \ |
| 295 if (!CheckAndGetInteger(arg, &value)) { \ | 295 if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \ |
| 296 return err; \ | 296 return err; \ |
| 297 } | 297 } |
| 298 | 298 |
| 299 #define GOOGLE_CHECK_GET_UINT64(arg, value, err) \ | 299 #define GOOGLE_CHECK_GET_UINT64(arg, value, err) \ |
| 300 uint64 value; \ | 300 uint64 value; \ |
| 301 if (!CheckAndGetInteger(arg, &value)) { \ | 301 if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \ |
| 302 return err; \ | 302 return err; \ |
| 303 } | 303 } |
| 304 | 304 |
| 305 #define GOOGLE_CHECK_GET_FLOAT(arg, value, err) \ | 305 #define GOOGLE_CHECK_GET_FLOAT(arg, value, err) \ |
| 306 float value; \ | 306 float value; \ |
| 307 if (!CheckAndGetFloat(arg, &value)) { \ | 307 if (!CheckAndGetFloat(arg, &value)) { \ |
| 308 return err; \ | 308 return err; \ |
| 309 } \ | 309 } \ |
| 310 | 310 |
| 311 #define GOOGLE_CHECK_GET_DOUBLE(arg, value, err) \ | 311 #define GOOGLE_CHECK_GET_DOUBLE(arg, value, err) \ |
| 312 double value; \ | 312 double value; \ |
| 313 if (!CheckAndGetDouble(arg, &value)) { \ | 313 if (!CheckAndGetDouble(arg, &value)) { \ |
| 314 return err; \ | 314 return err; \ |
| 315 } | 315 } |
| 316 | 316 |
| 317 #define GOOGLE_CHECK_GET_BOOL(arg, value, err) \ | 317 #define GOOGLE_CHECK_GET_BOOL(arg, value, err) \ |
| 318 bool value; \ | 318 bool value; \ |
| 319 if (!CheckAndGetBool(arg, &value)) { \ | 319 if (!CheckAndGetBool(arg, &value)) { \ |
| 320 return err; \ | 320 return err; \ |
| 321 } | 321 } |
| 322 | 322 |
| 323 | 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 |
| 324 #define FULL_MODULE_NAME "google.protobuf.pyext._message" | 332 #define FULL_MODULE_NAME "google.protobuf.pyext._message" |
| 325 | 333 |
| 326 void FormatTypeError(PyObject* arg, char* expected_types); | 334 void FormatTypeError(PyObject* arg, char* expected_types); |
| 327 template<class T> | 335 template<class T> |
| 328 bool CheckAndGetInteger(PyObject* arg, T* value); | 336 bool CheckAndGetInteger( |
| 337 PyObject* arg, T* value, PyObject* min, PyObject* max); |
| 329 bool CheckAndGetDouble(PyObject* arg, double* value); | 338 bool CheckAndGetDouble(PyObject* arg, double* value); |
| 330 bool CheckAndGetFloat(PyObject* arg, float* value); | 339 bool CheckAndGetFloat(PyObject* arg, float* value); |
| 331 bool CheckAndGetBool(PyObject* arg, bool* value); | 340 bool CheckAndGetBool(PyObject* arg, bool* value); |
| 332 PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor); | 341 PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor); |
| 333 bool CheckAndSetString( | 342 bool CheckAndSetString( |
| 334 PyObject* arg, Message* message, | 343 PyObject* arg, Message* message, |
| 335 const FieldDescriptor* descriptor, | 344 const FieldDescriptor* descriptor, |
| 336 const Reflection* reflection, | 345 const Reflection* reflection, |
| 337 bool append, | 346 bool append, |
| 338 int index); | 347 int index); |
| 339 PyObject* ToStringObject(const FieldDescriptor* descriptor, string value); | 348 PyObject* ToStringObject(const FieldDescriptor* descriptor, string value); |
| 340 | 349 |
| 341 // Check if the passed field descriptor belongs to the given message. | 350 // Check if the passed field descriptor belongs to the given message. |
| 342 // If not, return false and set a Python exception (a KeyError) | 351 // If not, return false and set a Python exception (a KeyError) |
| 343 bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor, | 352 bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor, |
| 344 const Message* message); | 353 const Message* message); |
| 345 | 354 |
| 346 extern PyObject* PickleError_class; | 355 extern PyObject* PickleError_class; |
| 347 | 356 |
| 348 bool InitProto2MessageModule(PyObject *m); | |
| 349 | |
| 350 } // namespace python | 357 } // namespace python |
| 351 } // namespace protobuf | 358 } // namespace protobuf |
| 352 | 359 |
| 353 } // namespace google | 360 } // namespace google |
| 354 #endif // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__ | 361 #endif // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__ |
| OLD | NEW |