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 PyDescriptorPool; | 65 struct PyMessageFactory; |
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; |
115 } CMessage; | 118 } CMessage; |
116 | 119 |
| 120 extern PyTypeObject CMessageClass_Type; |
117 extern PyTypeObject CMessage_Type; | 121 extern PyTypeObject CMessage_Type; |
118 | 122 |
119 | 123 |
120 // The (meta) type of all Messages classes. | 124 // The (meta) type of all Messages classes. |
121 // It allows us to cache some C++ pointers in the class object itself, they are | 125 // 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. | 126 // faster to extract than from the type's dictionary. |
123 | 127 |
124 struct CMessageClass { | 128 struct CMessageClass { |
125 // This is how CPython subclasses C structures: the base structure must be | 129 // This is how CPython subclasses C structures: the base structure must be |
126 // the first member of the object. | 130 // the first member of the object. |
127 PyHeapTypeObject super; | 131 PyHeapTypeObject super; |
128 | 132 |
129 // C++ descriptor of this message. | 133 // C++ descriptor of this message. |
130 const Descriptor* message_descriptor; | 134 const Descriptor* message_descriptor; |
131 | 135 |
132 // Owned reference, used to keep the pointer above alive. | 136 // Owned reference, used to keep the pointer above alive. |
133 PyObject* py_message_descriptor; | 137 PyObject* py_message_descriptor; |
134 | 138 |
135 // The Python DescriptorPool used to create the class. It is needed to resolve | 139 // The Python MessageFactory used to create the class. It is needed to resolve |
136 // fields descriptors, including extensions fields; its C++ MessageFactory is | 140 // fields descriptors, including extensions fields; its C++ MessageFactory is |
137 // used to instantiate submessages. | 141 // used to instantiate submessages. |
138 // This can be different from DESCRIPTOR.file.pool, in the case of a custom | 142 // We own the reference, because it's important to keep the factory alive. |
139 // DescriptorPool which defines new extensions. | 143 PyMessageFactory* py_message_factory; |
140 // We own the reference, because it's important to keep the descriptors and | |
141 // factory alive. | |
142 PyDescriptorPool* py_descriptor_pool; | |
143 | 144 |
144 PyObject* AsPyObject() { | 145 PyObject* AsPyObject() { |
145 return reinterpret_cast<PyObject*>(this); | 146 return reinterpret_cast<PyObject*>(this); |
146 } | 147 } |
147 }; | 148 }; |
148 | 149 |
149 | 150 |
150 namespace cmessage { | 151 namespace cmessage { |
151 | 152 |
152 // Internal function to create a new empty Message Python object, but with empty | 153 // Internal function to create a new empty Message Python object, but with empty |
153 // pointers to the C++ objects. | 154 // pointers to the C++ objects. |
154 // The caller must fill self->message, self->owner and eventually self->parent. | 155 // The caller must fill self->message, self->owner and eventually self->parent. |
155 CMessage* NewEmptyMessage(CMessageClass* type); | 156 CMessage* NewEmptyMessage(CMessageClass* type); |
156 | 157 |
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. | 158 // Retrieves the C++ descriptor of a Python Extension descriptor. |
166 // On error, return NULL with an exception set. | 159 // On error, return NULL with an exception set. |
167 const FieldDescriptor* GetExtensionDescriptor(PyObject* extension); | 160 const FieldDescriptor* GetExtensionDescriptor(PyObject* extension); |
168 | 161 |
169 // Initializes a new CMessage instance for a submessage. Only called once per | 162 // Initializes a new CMessage instance for a submessage. Only called once per |
170 // submessage as the result is cached in composite_fields. | 163 // submessage as the result is cached in composite_fields. |
171 // | 164 // |
172 // Corresponds to reflection api method GetMessage. | 165 // Corresponds to reflection api method GetMessage. |
173 PyObject* InternalGetSubMessage( | 166 PyObject* InternalGetSubMessage( |
174 CMessage* self, const FieldDescriptor* field_descriptor); | 167 CMessage* self, const FieldDescriptor* field_descriptor); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 // Corresponds to reflection api method HasField | 223 // Corresponds to reflection api method HasField |
231 PyObject* HasFieldByDescriptor( | 224 PyObject* HasFieldByDescriptor( |
232 CMessage* self, const FieldDescriptor* field_descriptor); | 225 CMessage* self, const FieldDescriptor* field_descriptor); |
233 | 226 |
234 // Checks if the message has the named field. | 227 // Checks if the message has the named field. |
235 // | 228 // |
236 // Corresponds to reflection api method HasField. | 229 // Corresponds to reflection api method HasField. |
237 PyObject* HasField(CMessage* self, PyObject* arg); | 230 PyObject* HasField(CMessage* self, PyObject* arg); |
238 | 231 |
239 // Initializes values of fields on a newly constructed message. | 232 // Initializes values of fields on a newly constructed message. |
240 int InitAttributes(CMessage* self, PyObject* kwargs); | 233 // Note that positional arguments are disallowed: 'args' must be NULL or the |
| 234 // empty tuple. |
| 235 int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs); |
241 | 236 |
242 PyObject* MergeFrom(CMessage* self, PyObject* arg); | 237 PyObject* MergeFrom(CMessage* self, PyObject* arg); |
243 | 238 |
| 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 |
244 // Retrieves an attribute named 'name' from CMessage 'self'. Returns | 243 // Retrieves an attribute named 'name' from CMessage 'self'. Returns |
245 // the attribute value on success, or NULL on failure. | 244 // the attribute value on success, or NULL on failure. |
246 // | 245 // |
247 // Returns a new reference. | 246 // Returns a new reference. |
248 PyObject* GetAttr(CMessage* self, PyObject* name); | 247 PyObject* GetAttr(CMessage* self, PyObject* name); |
249 | 248 |
250 // Set the value of the attribute named 'name', for CMessage 'self', | 249 // Set the value of the attribute named 'name', for CMessage 'self', |
251 // to the value 'value'. Returns -1 on failure. | 250 // to the value 'value'. Returns -1 on failure. |
252 int SetAttr(CMessage* self, PyObject* name, PyObject* value); | 251 int SetAttr(CMessage* self, PyObject* name, PyObject* value); |
253 | 252 |
254 PyObject* FindInitializationErrors(CMessage* self); | 253 PyObject* FindInitializationErrors(CMessage* self); |
255 | 254 |
256 // Set the owner field of self and any children of self, recursively. | 255 // 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 | 256 // Used when self is being released and thus has a new owner (the |
258 // released Message.) | 257 // released Message.) |
259 int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner); | 258 int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner); |
260 | 259 |
261 int AssureWritable(CMessage* self); | 260 int AssureWritable(CMessage* self); |
262 | 261 |
263 // Returns the "best" DescriptorPool for the given message. | 262 // Returns the message factory for the given message. |
264 // This is often equivalent to message.DESCRIPTOR.pool, but not always, when | 263 // This is equivalent to message.MESSAGE_FACTORY |
265 // the message class was created from a MessageFactory using a custom pool which | |
266 // uses the generated pool as an underlay. | |
267 // | 264 // |
268 // The returned pool is suitable for finding fields and building submessages, | 265 // The returned factory is suitable for finding fields and building submessages, |
269 // even in the case of extensions. | 266 // even in the case of extensions. |
270 PyDescriptorPool* GetDescriptorPoolForMessage(CMessage* message); | 267 // Returns a *borrowed* reference, and never fails because we pass a CMessage. |
| 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, kint32min_py, kint32max_py)) { \ | 283 if (!CheckAndGetInteger(arg, &value)) { \ |
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, kint64min_py, kint64max_py)) { \ | 289 if (!CheckAndGetInteger(arg, &value)) { \ |
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, kPythonZero, kuint32max_py)) { \ | 295 if (!CheckAndGetInteger(arg, &value)) { \ |
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, kPythonZero, kuint64max_py)) { \ | 301 if (!CheckAndGetInteger(arg, &value)) { \ |
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 | |
332 #define FULL_MODULE_NAME "google.protobuf.pyext._message" | 324 #define FULL_MODULE_NAME "google.protobuf.pyext._message" |
333 | 325 |
334 void FormatTypeError(PyObject* arg, char* expected_types); | 326 void FormatTypeError(PyObject* arg, char* expected_types); |
335 template<class T> | 327 template<class T> |
336 bool CheckAndGetInteger( | 328 bool CheckAndGetInteger(PyObject* arg, T* value); |
337 PyObject* arg, T* value, PyObject* min, PyObject* max); | |
338 bool CheckAndGetDouble(PyObject* arg, double* value); | 329 bool CheckAndGetDouble(PyObject* arg, double* value); |
339 bool CheckAndGetFloat(PyObject* arg, float* value); | 330 bool CheckAndGetFloat(PyObject* arg, float* value); |
340 bool CheckAndGetBool(PyObject* arg, bool* value); | 331 bool CheckAndGetBool(PyObject* arg, bool* value); |
341 PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor); | 332 PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor); |
342 bool CheckAndSetString( | 333 bool CheckAndSetString( |
343 PyObject* arg, Message* message, | 334 PyObject* arg, Message* message, |
344 const FieldDescriptor* descriptor, | 335 const FieldDescriptor* descriptor, |
345 const Reflection* reflection, | 336 const Reflection* reflection, |
346 bool append, | 337 bool append, |
347 int index); | 338 int index); |
348 PyObject* ToStringObject(const FieldDescriptor* descriptor, string value); | 339 PyObject* ToStringObject(const FieldDescriptor* descriptor, string value); |
349 | 340 |
350 // Check if the passed field descriptor belongs to the given message. | 341 // Check if the passed field descriptor belongs to the given message. |
351 // If not, return false and set a Python exception (a KeyError) | 342 // If not, return false and set a Python exception (a KeyError) |
352 bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor, | 343 bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor, |
353 const Message* message); | 344 const Message* message); |
354 | 345 |
355 extern PyObject* PickleError_class; | 346 extern PyObject* PickleError_class; |
356 | 347 |
| 348 bool InitProto2MessageModule(PyObject *m); |
| 349 |
357 } // namespace python | 350 } // namespace python |
358 } // namespace protobuf | 351 } // namespace protobuf |
359 | 352 |
360 } // namespace google | 353 } // namespace google |
361 #endif // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__ | 354 #endif // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__ |
OLD | NEW |