blob: 72bcfa83d902c9a48551f315c394575e90db71d0 [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001// 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>
Brian Silverman9c614bc2016-02-15 20:20:02 -050040#include <string>
41
Austin Schuh40c16522018-10-28 20:27:54 -070042#include <google/protobuf/stubs/common.h>
43#include <google/protobuf/pyext/thread_unsafe_shared_ptr.h>
44
Brian Silverman9c614bc2016-02-15 20:20:02 -050045namespace google {
46namespace protobuf {
47
48class Message;
49class Reflection;
50class FieldDescriptor;
51class Descriptor;
52class DescriptorPool;
53class MessageFactory;
54
Brian Silverman9c614bc2016-02-15 20:20:02 -050055namespace python {
56
57struct ExtensionDict;
Austin Schuh40c16522018-10-28 20:27:54 -070058struct PyMessageFactory;
Brian Silverman9c614bc2016-02-15 20:20:02 -050059
60typedef struct CMessage {
61 PyObject_HEAD;
62
63 // This is the top-level C++ Message object that owns the whole
64 // proto tree. Every Python CMessage holds a reference to it in
65 // order to keep it alive as long as there's a Python object that
66 // references any part of the tree.
Austin Schuh40c16522018-10-28 20:27:54 -070067
68 typedef ThreadUnsafeSharedPtr<Message> OwnerRef;
69 OwnerRef owner;
Brian Silverman9c614bc2016-02-15 20:20:02 -050070
71 // Weak reference to a parent CMessage object. This is NULL for any top-level
72 // message and is set for any child message (i.e. a child submessage or a
73 // part of a repeated composite field).
74 //
75 // Used to make sure all ancestors are also mutable when first modifying
76 // a child submessage (in other words, turning a default message instance
77 // into a mutable one).
78 //
79 // If a submessage is released (becomes a new top-level message), this field
80 // MUST be set to NULL. The parent may get deallocated and further attempts
81 // to use this pointer will result in a crash.
82 struct CMessage* parent;
83
84 // Pointer to the parent's descriptor that describes this submessage.
85 // Used together with the parent's message when making a default message
86 // instance mutable.
87 // The pointer is owned by the global DescriptorPool.
88 const FieldDescriptor* parent_field_descriptor;
89
90 // Pointer to the C++ Message object for this CMessage. The
91 // CMessage does not own this pointer.
92 Message* message;
93
94 // Indicates this submessage is pointing to a default instance of a message.
95 // Submessages are always first created as read only messages and are then
96 // made writable, at which point this field is set to false.
97 bool read_only;
98
99 // A reference to a Python dictionary containing CMessage,
100 // RepeatedCompositeContainer, and RepeatedScalarContainer
101 // objects. Used as a cache to make sure we don't have to make a
102 // Python wrapper for the C++ Message objects on every access, or
103 // deal with the synchronization nightmare that could create.
104 PyObject* composite_fields;
105
106 // A reference to the dictionary containing the message's extensions.
107 // Similar to composite_fields, acting as a cache, but also contains the
108 // required extension dict logic.
109 ExtensionDict* extensions;
Austin Schuh40c16522018-10-28 20:27:54 -0700110
111 // Implements the "weakref" protocol for this object.
112 PyObject* weakreflist;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500113} CMessage;
114
Austin Schuh40c16522018-10-28 20:27:54 -0700115extern PyTypeObject CMessageClass_Type;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500116extern PyTypeObject CMessage_Type;
117
Austin Schuh40c16522018-10-28 20:27:54 -0700118
119// The (meta) type of all Messages classes.
120// It allows us to cache some C++ pointers in the class object itself, they are
121// faster to extract than from the type's dictionary.
122
123struct CMessageClass {
124 // This is how CPython subclasses C structures: the base structure must be
125 // the first member of the object.
126 PyHeapTypeObject super;
127
128 // C++ descriptor of this message.
129 const Descriptor* message_descriptor;
130
131 // Owned reference, used to keep the pointer above alive.
132 PyObject* py_message_descriptor;
133
134 // The Python MessageFactory used to create the class. It is needed to resolve
135 // fields descriptors, including extensions fields; its C++ MessageFactory is
136 // used to instantiate submessages.
137 // We own the reference, because it's important to keep the factory alive.
138 PyMessageFactory* py_message_factory;
139
140 PyObject* AsPyObject() {
141 return reinterpret_cast<PyObject*>(this);
142 }
143};
144
145
Brian Silverman9c614bc2016-02-15 20:20:02 -0500146namespace cmessage {
147
148// Internal function to create a new empty Message Python object, but with empty
149// pointers to the C++ objects.
150// The caller must fill self->message, self->owner and eventually self->parent.
Austin Schuh40c16522018-10-28 20:27:54 -0700151CMessage* NewEmptyMessage(CMessageClass* type);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500152
153// Retrieves the C++ descriptor of a Python Extension descriptor.
154// On error, return NULL with an exception set.
155const FieldDescriptor* GetExtensionDescriptor(PyObject* extension);
156
157// Initializes a new CMessage instance for a submessage. Only called once per
158// submessage as the result is cached in composite_fields.
159//
160// Corresponds to reflection api method GetMessage.
161PyObject* InternalGetSubMessage(
162 CMessage* self, const FieldDescriptor* field_descriptor);
163
164// Deletes a range of C++ submessages in a repeated field (following a
165// removal in a RepeatedCompositeContainer).
166//
167// Releases messages to the provided cmessage_list if it is not NULL rather
168// than just removing them from the underlying proto. This cmessage_list must
169// have a CMessage for each underlying submessage. The CMessages referred to
170// by slice will be removed from cmessage_list by this function.
171//
172// Corresponds to reflection api method RemoveLast.
173int InternalDeleteRepeatedField(CMessage* self,
174 const FieldDescriptor* field_descriptor,
175 PyObject* slice, PyObject* cmessage_list);
176
177// Sets the specified scalar value to the message.
178int InternalSetScalar(CMessage* self,
179 const FieldDescriptor* field_descriptor,
180 PyObject* value);
181
182// Sets the specified scalar value to the message. Requires it is not a Oneof.
183int InternalSetNonOneofScalar(Message* message,
184 const FieldDescriptor* field_descriptor,
185 PyObject* arg);
186
187// Retrieves the specified scalar value from the message.
188//
189// Returns a new python reference.
190PyObject* InternalGetScalar(const Message* message,
191 const FieldDescriptor* field_descriptor);
192
193// Clears the message, removing all contained data. Extension dictionary and
194// submessages are released first if there are remaining external references.
195//
196// Corresponds to message api method Clear.
197PyObject* Clear(CMessage* self);
198
199// Clears the data described by the given descriptor. Used to clear extensions
200// (which don't have names). Extension release is handled by ExtensionDict
201// class, not this function.
202// TODO(anuraag): Try to make this discrepancy in release semantics with
203// ClearField less confusing.
204//
205// Corresponds to reflection api method ClearField.
206PyObject* ClearFieldByDescriptor(
207 CMessage* self, const FieldDescriptor* descriptor);
208
209// Clears the data for the given field name. The message is released if there
210// are any external references.
211//
212// Corresponds to reflection api method ClearField.
213PyObject* ClearField(CMessage* self, PyObject* arg);
214
215// Checks if the message has the field described by the descriptor. Used for
216// extensions (which have no name).
217//
218// Corresponds to reflection api method HasField
219PyObject* HasFieldByDescriptor(
220 CMessage* self, const FieldDescriptor* field_descriptor);
221
222// Checks if the message has the named field.
223//
224// Corresponds to reflection api method HasField.
225PyObject* HasField(CMessage* self, PyObject* arg);
226
227// Initializes values of fields on a newly constructed message.
Austin Schuh40c16522018-10-28 20:27:54 -0700228// Note that positional arguments are disallowed: 'args' must be NULL or the
229// empty tuple.
230int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500231
232PyObject* MergeFrom(CMessage* self, PyObject* arg);
233
Austin Schuh40c16522018-10-28 20:27:54 -0700234// This method does not do anything beyond checking that no other extension
235// has been registered with the same field number on this class.
236PyObject* RegisterExtension(PyObject* cls, PyObject* extension_handle);
237
238// Retrieves an attribute named 'name' from 'self', which is interpreted as a
239// CMessage. Returns the attribute value on success, or null on failure.
Brian Silverman9c614bc2016-02-15 20:20:02 -0500240//
241// Returns a new reference.
Austin Schuh40c16522018-10-28 20:27:54 -0700242PyObject* GetAttr(PyObject* self, PyObject* name);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500243
Austin Schuh40c16522018-10-28 20:27:54 -0700244// Set the value of the attribute named 'name', for 'self', which is interpreted
245// as a CMessage, to the value 'value'. Returns -1 on failure.
246int SetAttr(PyObject* self, PyObject* name, PyObject* value);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500247
248PyObject* FindInitializationErrors(CMessage* self);
249
250// Set the owner field of self and any children of self, recursively.
251// Used when self is being released and thus has a new owner (the
252// released Message.)
Austin Schuh40c16522018-10-28 20:27:54 -0700253int SetOwner(CMessage* self, const CMessage::OwnerRef& new_owner);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500254
255int AssureWritable(CMessage* self);
256
Austin Schuh40c16522018-10-28 20:27:54 -0700257// Returns the message factory for the given message.
258// This is equivalent to message.MESSAGE_FACTORY
Brian Silverman9c614bc2016-02-15 20:20:02 -0500259//
Austin Schuh40c16522018-10-28 20:27:54 -0700260// The returned factory is suitable for finding fields and building submessages,
Brian Silverman9c614bc2016-02-15 20:20:02 -0500261// even in the case of extensions.
Austin Schuh40c16522018-10-28 20:27:54 -0700262// Returns a *borrowed* reference, and never fails because we pass a CMessage.
263PyMessageFactory* GetFactoryForMessage(CMessage* message);
264
265PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500266
267} // namespace cmessage
268
269
270/* Is 64bit */
271#define IS_64BIT (SIZEOF_LONG == 8)
272
273#define FIELD_IS_REPEATED(field_descriptor) \
274 ((field_descriptor)->label() == FieldDescriptor::LABEL_REPEATED)
275
276#define GOOGLE_CHECK_GET_INT32(arg, value, err) \
277 int32 value; \
Austin Schuh40c16522018-10-28 20:27:54 -0700278 if (!CheckAndGetInteger(arg, &value)) { \
Brian Silverman9c614bc2016-02-15 20:20:02 -0500279 return err; \
280 }
281
282#define GOOGLE_CHECK_GET_INT64(arg, value, err) \
283 int64 value; \
Austin Schuh40c16522018-10-28 20:27:54 -0700284 if (!CheckAndGetInteger(arg, &value)) { \
Brian Silverman9c614bc2016-02-15 20:20:02 -0500285 return err; \
286 }
287
288#define GOOGLE_CHECK_GET_UINT32(arg, value, err) \
289 uint32 value; \
Austin Schuh40c16522018-10-28 20:27:54 -0700290 if (!CheckAndGetInteger(arg, &value)) { \
Brian Silverman9c614bc2016-02-15 20:20:02 -0500291 return err; \
292 }
293
294#define GOOGLE_CHECK_GET_UINT64(arg, value, err) \
295 uint64 value; \
Austin Schuh40c16522018-10-28 20:27:54 -0700296 if (!CheckAndGetInteger(arg, &value)) { \
Brian Silverman9c614bc2016-02-15 20:20:02 -0500297 return err; \
298 }
299
300#define GOOGLE_CHECK_GET_FLOAT(arg, value, err) \
301 float value; \
302 if (!CheckAndGetFloat(arg, &value)) { \
303 return err; \
304 } \
305
306#define GOOGLE_CHECK_GET_DOUBLE(arg, value, err) \
307 double value; \
308 if (!CheckAndGetDouble(arg, &value)) { \
309 return err; \
310 }
311
312#define GOOGLE_CHECK_GET_BOOL(arg, value, err) \
313 bool value; \
314 if (!CheckAndGetBool(arg, &value)) { \
315 return err; \
316 }
317
318
Brian Silverman9c614bc2016-02-15 20:20:02 -0500319#define FULL_MODULE_NAME "google.protobuf.pyext._message"
320
321void FormatTypeError(PyObject* arg, char* expected_types);
322template<class T>
Austin Schuh40c16522018-10-28 20:27:54 -0700323bool CheckAndGetInteger(PyObject* arg, T* value);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500324bool CheckAndGetDouble(PyObject* arg, double* value);
325bool CheckAndGetFloat(PyObject* arg, float* value);
326bool CheckAndGetBool(PyObject* arg, bool* value);
327PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor);
328bool CheckAndSetString(
329 PyObject* arg, Message* message,
330 const FieldDescriptor* descriptor,
331 const Reflection* reflection,
332 bool append,
333 int index);
Austin Schuh40c16522018-10-28 20:27:54 -0700334PyObject* ToStringObject(const FieldDescriptor* descriptor,
335 const string& value);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500336
337// Check if the passed field descriptor belongs to the given message.
338// If not, return false and set a Python exception (a KeyError)
339bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor,
340 const Message* message);
341
342extern PyObject* PickleError_class;
343
Austin Schuh40c16522018-10-28 20:27:54 -0700344bool InitProto2MessageModule(PyObject *m);
345
346#if LANG_CXX11
347// These are referenced by repeated_scalar_container, and must
348// be explicitly instantiated.
349extern template bool CheckAndGetInteger<int32>(PyObject*, int32*);
350extern template bool CheckAndGetInteger<int64>(PyObject*, int64*);
351extern template bool CheckAndGetInteger<uint32>(PyObject*, uint32*);
352extern template bool CheckAndGetInteger<uint64>(PyObject*, uint64*);
353#endif
354
Brian Silverman9c614bc2016-02-15 20:20:02 -0500355} // namespace python
356} // namespace protobuf
357
358} // namespace google
359#endif // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__