blob: c2b626496dc96ea2b646b027c9bdd8d97c3159b6 [file] [log] [blame]
jieluo@google.combde4a322014-08-12 21:10:30 +00001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
Feng Xiaoe4288622014-10-01 16:26:23 -07003// https://developers.google.com/protocol-buffers/
jieluo@google.combde4a322014-08-12 21:10:30 +00004//
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
jieluo@google.combde4a322014-08-12 21:10:30 +000045namespace google {
46namespace protobuf {
47
48class Message;
49class Reflection;
50class FieldDescriptor;
Feng Xiao6ef984a2014-11-10 17:34:54 -080051class Descriptor;
Jisi Liu46e8ff62015-10-05 11:59:43 -070052class DescriptorPool;
53class MessageFactory;
jieluo@google.combde4a322014-08-12 21:10:30 +000054
Manjunath Kudlur3f9b4f22015-12-07 14:15:29 -080055#ifdef _SHARED_PTR_H
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070056using shared_ptr;
57using std::std::string;
Manjunath Kudlur96537c42015-12-09 07:40:30 -080058#else
59using internal::shared_ptr;
Manjunath Kudlur3f9b4f22015-12-07 14:15:29 -080060#endif
jieluo@google.combde4a322014-08-12 21:10:30 +000061
62namespace python {
63
jieluo@google.combde4a322014-08-12 21:10:30 +000064struct ExtensionDict;
Jisi Liu46e8ff62015-10-05 11:59:43 -070065struct PyDescriptorPool;
jieluo@google.combde4a322014-08-12 21:10:30 +000066
67typedef 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
Feng Xiao6ef984a2014-11-10 17:34:54 -080089 // Pointer to the parent's descriptor that describes this submessage.
jieluo@google.combde4a322014-08-12 21:10:30 +000090 // Used together with the parent's message when making a default message
91 // instance mutable.
Feng Xiao6ef984a2014-11-10 17:34:54 -080092 // The pointer is owned by the global DescriptorPool.
Jisi Liuada65562015-02-25 16:39:11 -080093 const FieldDescriptor* parent_field_descriptor;
jieluo@google.combde4a322014-08-12 21:10:30 +000094
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
117extern PyTypeObject CMessage_Type;
118
119namespace cmessage {
120
Feng Xiao6ef984a2014-11-10 17:34:54 -0800121// Internal function to create a new empty Message Python object, but with empty
122// pointers to the C++ objects.
123// The caller must fill self->message, self->owner and eventually self->parent.
Jisi Liuada65562015-02-25 16:39:11 -0800124CMessage* NewEmptyMessage(PyObject* type, const Descriptor* descriptor);
jieluo@google.combde4a322014-08-12 21:10:30 +0000125
126// Release a submessage from its proto tree, making it a new top-level messgae.
127// A new message will be created if this is a read-only default instance.
128//
129// Corresponds to reflection api method ReleaseMessage.
Bo Yang5db21732015-05-21 14:28:59 -0700130int ReleaseSubMessage(CMessage* self,
Jisi Liuada65562015-02-25 16:39:11 -0800131 const FieldDescriptor* field_descriptor,
jieluo@google.combde4a322014-08-12 21:10:30 +0000132 CMessage* child_cmessage);
133
Feng Xiao6ef984a2014-11-10 17:34:54 -0800134// Retrieves the C++ descriptor of a Python Extension descriptor.
135// On error, return NULL with an exception set.
Jisi Liuada65562015-02-25 16:39:11 -0800136const FieldDescriptor* GetExtensionDescriptor(PyObject* extension);
Feng Xiao6ef984a2014-11-10 17:34:54 -0800137
jieluo@google.combde4a322014-08-12 21:10:30 +0000138// Initializes a new CMessage instance for a submessage. Only called once per
139// submessage as the result is cached in composite_fields.
140//
141// Corresponds to reflection api method GetMessage.
Feng Xiao6ef984a2014-11-10 17:34:54 -0800142PyObject* InternalGetSubMessage(
Jisi Liuada65562015-02-25 16:39:11 -0800143 CMessage* self, const FieldDescriptor* field_descriptor);
jieluo@google.combde4a322014-08-12 21:10:30 +0000144
145// Deletes a range of C++ submessages in a repeated field (following a
146// removal in a RepeatedCompositeContainer).
147//
148// Releases messages to the provided cmessage_list if it is not NULL rather
149// than just removing them from the underlying proto. This cmessage_list must
Veres Lajosc7680722014-11-08 22:59:34 +0000150// have a CMessage for each underlying submessage. The CMessages referred to
jieluo@google.combde4a322014-08-12 21:10:30 +0000151// by slice will be removed from cmessage_list by this function.
152//
153// Corresponds to reflection api method RemoveLast.
Bo Yang5db21732015-05-21 14:28:59 -0700154int InternalDeleteRepeatedField(CMessage* self,
Jisi Liuada65562015-02-25 16:39:11 -0800155 const FieldDescriptor* field_descriptor,
jieluo@google.combde4a322014-08-12 21:10:30 +0000156 PyObject* slice, PyObject* cmessage_list);
157
158// Sets the specified scalar value to the message.
159int InternalSetScalar(CMessage* self,
Jisi Liuada65562015-02-25 16:39:11 -0800160 const FieldDescriptor* field_descriptor,
jieluo@google.combde4a322014-08-12 21:10:30 +0000161 PyObject* value);
162
Bo Yang5db21732015-05-21 14:28:59 -0700163// Sets the specified scalar value to the message. Requires it is not a Oneof.
164int InternalSetNonOneofScalar(Message* message,
165 const FieldDescriptor* field_descriptor,
166 PyObject* arg);
167
jieluo@google.combde4a322014-08-12 21:10:30 +0000168// Retrieves the specified scalar value from the message.
169//
170// Returns a new python reference.
Bo Yang5db21732015-05-21 14:28:59 -0700171PyObject* InternalGetScalar(const Message* message,
Jisi Liuada65562015-02-25 16:39:11 -0800172 const FieldDescriptor* field_descriptor);
jieluo@google.combde4a322014-08-12 21:10:30 +0000173
174// Clears the message, removing all contained data. Extension dictionary and
175// submessages are released first if there are remaining external references.
176//
177// Corresponds to message api method Clear.
178PyObject* Clear(CMessage* self);
179
180// Clears the data described by the given descriptor. Used to clear extensions
181// (which don't have names). Extension release is handled by ExtensionDict
182// class, not this function.
183// TODO(anuraag): Try to make this discrepancy in release semantics with
184// ClearField less confusing.
185//
186// Corresponds to reflection api method ClearField.
187PyObject* ClearFieldByDescriptor(
Jisi Liuada65562015-02-25 16:39:11 -0800188 CMessage* self, const FieldDescriptor* descriptor);
jieluo@google.combde4a322014-08-12 21:10:30 +0000189
190// Clears the data for the given field name. The message is released if there
191// are any external references.
192//
193// Corresponds to reflection api method ClearField.
194PyObject* ClearField(CMessage* self, PyObject* arg);
195
196// Checks if the message has the field described by the descriptor. Used for
197// extensions (which have no name).
198//
199// Corresponds to reflection api method HasField
200PyObject* HasFieldByDescriptor(
Jisi Liuada65562015-02-25 16:39:11 -0800201 CMessage* self, const FieldDescriptor* field_descriptor);
jieluo@google.combde4a322014-08-12 21:10:30 +0000202
203// Checks if the message has the named field.
204//
205// Corresponds to reflection api method HasField.
206PyObject* HasField(CMessage* self, PyObject* arg);
207
Feng Xiao6ef984a2014-11-10 17:34:54 -0800208// Initializes values of fields on a newly constructed message.
209int InitAttributes(CMessage* self, PyObject* kwargs);
jieluo@google.combde4a322014-08-12 21:10:30 +0000210
211PyObject* MergeFrom(CMessage* self, PyObject* arg);
212
213// Retrieves an attribute named 'name' from CMessage 'self'. Returns
214// the attribute value on success, or NULL on failure.
215//
216// Returns a new reference.
217PyObject* GetAttr(CMessage* self, PyObject* name);
218
219// Set the value of the attribute named 'name', for CMessage 'self',
220// to the value 'value'. Returns -1 on failure.
221int SetAttr(CMessage* self, PyObject* name, PyObject* value);
222
223PyObject* FindInitializationErrors(CMessage* self);
224
225// Set the owner field of self and any children of self, recursively.
226// Used when self is being released and thus has a new owner (the
227// released Message.)
228int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner);
229
230int AssureWritable(CMessage* self);
Jisi Liu46e8ff62015-10-05 11:59:43 -0700231
232// Returns the "best" DescriptorPool for the given message.
233// This is often equivalent to message.DESCRIPTOR.pool, but not always, when
234// the message class was created from a MessageFactory using a custom pool which
235// uses the generated pool as an underlay.
236//
237// The returned pool is suitable for finding fields and building submessages,
238// even in the case of extensions.
239PyDescriptorPool* GetDescriptorPoolForMessage(CMessage* message);
240
jieluo@google.combde4a322014-08-12 21:10:30 +0000241} // namespace cmessage
242
Feng Xiao6ef984a2014-11-10 17:34:54 -0800243
jieluo@google.combde4a322014-08-12 21:10:30 +0000244/* Is 64bit */
245#define IS_64BIT (SIZEOF_LONG == 8)
246
jieluo@google.combde4a322014-08-12 21:10:30 +0000247#define FIELD_IS_REPEATED(field_descriptor) \
Jisi Liuada65562015-02-25 16:39:11 -0800248 ((field_descriptor)->label() == FieldDescriptor::LABEL_REPEATED)
jieluo@google.combde4a322014-08-12 21:10:30 +0000249
250#define GOOGLE_CHECK_GET_INT32(arg, value, err) \
251 int32 value; \
252 if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \
253 return err; \
254 }
255
256#define GOOGLE_CHECK_GET_INT64(arg, value, err) \
257 int64 value; \
258 if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \
259 return err; \
260 }
261
262#define GOOGLE_CHECK_GET_UINT32(arg, value, err) \
263 uint32 value; \
264 if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \
265 return err; \
266 }
267
268#define GOOGLE_CHECK_GET_UINT64(arg, value, err) \
269 uint64 value; \
270 if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \
271 return err; \
272 }
273
274#define GOOGLE_CHECK_GET_FLOAT(arg, value, err) \
275 float value; \
276 if (!CheckAndGetFloat(arg, &value)) { \
277 return err; \
278 } \
279
280#define GOOGLE_CHECK_GET_DOUBLE(arg, value, err) \
281 double value; \
282 if (!CheckAndGetDouble(arg, &value)) { \
283 return err; \
284 }
285
286#define GOOGLE_CHECK_GET_BOOL(arg, value, err) \
287 bool value; \
288 if (!CheckAndGetBool(arg, &value)) { \
289 return err; \
290 }
291
292
293extern PyObject* kPythonZero;
294extern PyObject* kint32min_py;
295extern PyObject* kint32max_py;
296extern PyObject* kuint32max_py;
297extern PyObject* kint64min_py;
298extern PyObject* kint64max_py;
299extern PyObject* kuint64max_py;
300
Bo Yang5db21732015-05-21 14:28:59 -0700301#define FULL_MODULE_NAME "google.protobuf.pyext._message"
jieluo@google.combde4a322014-08-12 21:10:30 +0000302
303void FormatTypeError(PyObject* arg, char* expected_types);
304template<class T>
305bool CheckAndGetInteger(
306 PyObject* arg, T* value, PyObject* min, PyObject* max);
307bool CheckAndGetDouble(PyObject* arg, double* value);
308bool CheckAndGetFloat(PyObject* arg, float* value);
309bool CheckAndGetBool(PyObject* arg, bool* value);
Feng Xiaoe841bac2015-12-11 17:09:20 -0800310PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor);
jieluo@google.combde4a322014-08-12 21:10:30 +0000311bool CheckAndSetString(
Jisi Liuada65562015-02-25 16:39:11 -0800312 PyObject* arg, Message* message,
313 const FieldDescriptor* descriptor,
314 const Reflection* reflection,
jieluo@google.combde4a322014-08-12 21:10:30 +0000315 bool append,
316 int index);
Jisi Liuada65562015-02-25 16:39:11 -0800317PyObject* ToStringObject(const FieldDescriptor* descriptor, string value);
jieluo@google.combde4a322014-08-12 21:10:30 +0000318
Feng Xiao6ef984a2014-11-10 17:34:54 -0800319// Check if the passed field descriptor belongs to the given message.
320// If not, return false and set a Python exception (a KeyError)
Jisi Liuada65562015-02-25 16:39:11 -0800321bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor,
322 const Message* message);
Feng Xiao6ef984a2014-11-10 17:34:54 -0800323
jieluo@google.combde4a322014-08-12 21:10:30 +0000324extern PyObject* PickleError_class;
325
326} // namespace python
327} // namespace protobuf
328
329} // namespace google
330#endif // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__