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 |