blob: 60ec9c1b966d6c5515fcc59cbc8a0393552ba206 [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#include <google/protobuf/pyext/message.h>
35
Feng Xiaoe841bac2015-12-11 17:09:20 -080036#include <map>
jieluo@google.combde4a322014-08-12 21:10:30 +000037#include <memory>
38#ifndef _SHARED_PTR_H
39#include <google/protobuf/stubs/shared_ptr.h>
40#endif
41#include <string>
42#include <vector>
Jisi Liuada65562015-02-25 16:39:11 -080043#include <structmember.h> // A Python header file.
jieluo@google.combde4a322014-08-12 21:10:30 +000044
45#ifndef PyVarObject_HEAD_INIT
46#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
47#endif
48#ifndef Py_TYPE
49#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
50#endif
51#include <google/protobuf/descriptor.pb.h>
52#include <google/protobuf/stubs/common.h>
Feng Xiaoeee38b02015-08-22 18:25:48 -070053#include <google/protobuf/stubs/logging.h>
jieluo@google.combde4a322014-08-12 21:10:30 +000054#include <google/protobuf/io/coded_stream.h>
Feng Xiaoeee38b02015-08-22 18:25:48 -070055#include <google/protobuf/util/message_differencer.h>
jieluo@google.combde4a322014-08-12 21:10:30 +000056#include <google/protobuf/descriptor.h>
jieluo@google.combde4a322014-08-12 21:10:30 +000057#include <google/protobuf/message.h>
58#include <google/protobuf/text_format.h>
Jisi Liu46e8ff62015-10-05 11:59:43 -070059#include <google/protobuf/unknown_field_set.h>
jieluo@google.combde4a322014-08-12 21:10:30 +000060#include <google/protobuf/pyext/descriptor.h>
Jisi Liuada65562015-02-25 16:39:11 -080061#include <google/protobuf/pyext/descriptor_pool.h>
jieluo@google.combde4a322014-08-12 21:10:30 +000062#include <google/protobuf/pyext/extension_dict.h>
63#include <google/protobuf/pyext/repeated_composite_container.h>
64#include <google/protobuf/pyext/repeated_scalar_container.h>
Feng Xiaoe841bac2015-12-11 17:09:20 -080065#include <google/protobuf/pyext/map_container.h>
jieluo@google.combde4a322014-08-12 21:10:30 +000066#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
Jisi Liuada65562015-02-25 16:39:11 -080067#include <google/protobuf/stubs/strutil.h>
jieluo@google.combde4a322014-08-12 21:10:30 +000068
69#if PY_MAJOR_VERSION >= 3
70 #define PyInt_Check PyLong_Check
71 #define PyInt_AsLong PyLong_AsLong
72 #define PyInt_FromLong PyLong_FromLong
73 #define PyInt_FromSize_t PyLong_FromSize_t
74 #define PyString_Check PyUnicode_Check
75 #define PyString_FromString PyUnicode_FromString
76 #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
77 #if PY_VERSION_HEX < 0x03030000
78 #error "Python 3.0 - 3.2 are not supported."
79 #else
80 #define PyString_AsString(ob) \
Feng Xiao6ef984a2014-11-10 17:34:54 -080081 (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AsString(ob))
Jisi Liuada65562015-02-25 16:39:11 -080082 #define PyString_AsStringAndSize(ob, charpp, sizep) \
83 (PyUnicode_Check(ob)? \
84 ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
85 PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
jieluo@google.combde4a322014-08-12 21:10:30 +000086 #endif
87#endif
88
89namespace google {
90namespace protobuf {
91namespace python {
92
Feng Xiaoeee38b02015-08-22 18:25:48 -070093static PyObject* kDESCRIPTOR;
94static PyObject* k_extensions_by_name;
95static PyObject* k_extensions_by_number;
96PyObject* EnumTypeWrapper_class;
97static PyObject* PythonMessage_class;
98static PyObject* kEmptyWeakref;
Feng Xiaoe841bac2015-12-11 17:09:20 -080099static PyObject* WKT_classes = NULL;
Feng Xiaoeee38b02015-08-22 18:25:48 -0700100
101// Defines the Metaclass of all Message classes.
102// It allows us to cache some C++ pointers in the class object itself, they are
103// faster to extract than from the type's dictionary.
104
105struct PyMessageMeta {
106 // This is how CPython subclasses C structures: the base structure must be
107 // the first member of the object.
108 PyHeapTypeObject super;
109
110 // C++ descriptor of this message.
111 const Descriptor* message_descriptor;
Jisi Liu46e8ff62015-10-05 11:59:43 -0700112
Feng Xiaoeee38b02015-08-22 18:25:48 -0700113 // Owned reference, used to keep the pointer above alive.
114 PyObject* py_message_descriptor;
Jisi Liu46e8ff62015-10-05 11:59:43 -0700115
116 // The Python DescriptorPool used to create the class. It is needed to resolve
117 // fields descriptors, including extensions fields; its C++ MessageFactory is
118 // used to instantiate submessages.
119 // This can be different from DESCRIPTOR.file.pool, in the case of a custom
120 // DescriptorPool which defines new extensions.
121 // We own the reference, because it's important to keep the descriptors and
122 // factory alive.
123 PyDescriptorPool* py_descriptor_pool;
Feng Xiaoeee38b02015-08-22 18:25:48 -0700124};
125
126namespace message_meta {
127
128static int InsertEmptyWeakref(PyTypeObject* base);
129
130// Add the number of a field descriptor to the containing message class.
131// Equivalent to:
132// _cls.<field>_FIELD_NUMBER = <number>
133static bool AddFieldNumberToClass(
134 PyObject* cls, const FieldDescriptor* field_descriptor) {
135 string constant_name = field_descriptor->name() + "_FIELD_NUMBER";
136 UpperString(&constant_name);
137 ScopedPyObjectPtr attr_name(PyString_FromStringAndSize(
138 constant_name.c_str(), constant_name.size()));
139 if (attr_name == NULL) {
140 return false;
141 }
142 ScopedPyObjectPtr number(PyInt_FromLong(field_descriptor->number()));
143 if (number == NULL) {
144 return false;
145 }
Josh Haberman00700b72015-10-06 14:13:09 -0700146 if (PyObject_SetAttr(cls, attr_name.get(), number.get()) == -1) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700147 return false;
148 }
149 return true;
150}
151
152
153// Finalize the creation of the Message class.
Jisi Liu46e8ff62015-10-05 11:59:43 -0700154static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700155 // If there are extension_ranges, the message is "extendable", and extension
156 // classes will register themselves in this class.
Jisi Liu46e8ff62015-10-05 11:59:43 -0700157 if (descriptor->extension_range_count() > 0) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700158 ScopedPyObjectPtr by_name(PyDict_New());
Josh Haberman00700b72015-10-06 14:13:09 -0700159 if (PyObject_SetAttr(cls, k_extensions_by_name, by_name.get()) < 0) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700160 return -1;
161 }
162 ScopedPyObjectPtr by_number(PyDict_New());
Josh Haberman00700b72015-10-06 14:13:09 -0700163 if (PyObject_SetAttr(cls, k_extensions_by_number, by_number.get()) < 0) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700164 return -1;
165 }
166 }
167
168 // For each field set: cls.<field>_FIELD_NUMBER = <number>
Jisi Liu46e8ff62015-10-05 11:59:43 -0700169 for (int i = 0; i < descriptor->field_count(); ++i) {
170 if (!AddFieldNumberToClass(cls, descriptor->field(i))) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700171 return -1;
172 }
173 }
174
175 // For each enum set cls.<enum name> = EnumTypeWrapper(<enum descriptor>).
176 //
177 // The enum descriptor we get from
178 // <messagedescriptor>.enum_types_by_name[name]
179 // which was built previously.
Jisi Liu46e8ff62015-10-05 11:59:43 -0700180 for (int i = 0; i < descriptor->enum_type_count(); ++i) {
181 const EnumDescriptor* enum_descriptor = descriptor->enum_type(i);
Feng Xiaoeee38b02015-08-22 18:25:48 -0700182 ScopedPyObjectPtr enum_type(
183 PyEnumDescriptor_FromDescriptor(enum_descriptor));
184 if (enum_type == NULL) {
185 return -1;
186 }
187 // Add wrapped enum type to message class.
188 ScopedPyObjectPtr wrapped(PyObject_CallFunctionObjArgs(
189 EnumTypeWrapper_class, enum_type.get(), NULL));
190 if (wrapped == NULL) {
191 return -1;
192 }
193 if (PyObject_SetAttrString(
Josh Haberman00700b72015-10-06 14:13:09 -0700194 cls, enum_descriptor->name().c_str(), wrapped.get()) == -1) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700195 return -1;
196 }
197
198 // For each enum value add cls.<name> = <number>
199 for (int j = 0; j < enum_descriptor->value_count(); ++j) {
200 const EnumValueDescriptor* enum_value_descriptor =
201 enum_descriptor->value(j);
202 ScopedPyObjectPtr value_number(PyInt_FromLong(
203 enum_value_descriptor->number()));
204 if (value_number == NULL) {
205 return -1;
206 }
Josh Haberman00700b72015-10-06 14:13:09 -0700207 if (PyObject_SetAttrString(cls, enum_value_descriptor->name().c_str(),
208 value_number.get()) == -1) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700209 return -1;
210 }
211 }
212 }
213
214 // For each extension set cls.<extension name> = <extension descriptor>.
215 //
216 // Extension descriptors come from
217 // <message descriptor>.extensions_by_name[name]
218 // which was defined previously.
Jisi Liu46e8ff62015-10-05 11:59:43 -0700219 for (int i = 0; i < descriptor->extension_count(); ++i) {
220 const google::protobuf::FieldDescriptor* field = descriptor->extension(i);
Feng Xiaoeee38b02015-08-22 18:25:48 -0700221 ScopedPyObjectPtr extension_field(PyFieldDescriptor_FromDescriptor(field));
222 if (extension_field == NULL) {
223 return -1;
224 }
225
226 // Add the extension field to the message class.
227 if (PyObject_SetAttrString(
Josh Haberman00700b72015-10-06 14:13:09 -0700228 cls, field->name().c_str(), extension_field.get()) == -1) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700229 return -1;
230 }
231
232 // For each extension set cls.<extension name>_FIELD_NUMBER = <number>.
233 if (!AddFieldNumberToClass(cls, field)) {
234 return -1;
235 }
236 }
237
238 return 0;
239}
240
241static PyObject* New(PyTypeObject* type,
242 PyObject* args, PyObject* kwargs) {
243 static char *kwlist[] = {"name", "bases", "dict", 0};
244 PyObject *bases, *dict;
245 const char* name;
246
247 // Check arguments: (name, bases, dict)
248 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO!O!:type", kwlist,
249 &name,
250 &PyTuple_Type, &bases,
251 &PyDict_Type, &dict)) {
252 return NULL;
253 }
254
255 // Check bases: only (), or (message.Message,) are allowed
256 if (!(PyTuple_GET_SIZE(bases) == 0 ||
257 (PyTuple_GET_SIZE(bases) == 1 &&
258 PyTuple_GET_ITEM(bases, 0) == PythonMessage_class))) {
259 PyErr_SetString(PyExc_TypeError,
260 "A Message class can only inherit from Message");
261 return NULL;
262 }
263
264 // Check dict['DESCRIPTOR']
Jisi Liu46e8ff62015-10-05 11:59:43 -0700265 PyObject* py_descriptor = PyDict_GetItem(dict, kDESCRIPTOR);
266 if (py_descriptor == NULL) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700267 PyErr_SetString(PyExc_TypeError, "Message class has no DESCRIPTOR");
268 return NULL;
269 }
Jisi Liu46e8ff62015-10-05 11:59:43 -0700270 if (!PyObject_TypeCheck(py_descriptor, &PyMessageDescriptor_Type)) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700271 PyErr_Format(PyExc_TypeError, "Expected a message Descriptor, got %s",
Jisi Liu46e8ff62015-10-05 11:59:43 -0700272 py_descriptor->ob_type->tp_name);
Feng Xiaoeee38b02015-08-22 18:25:48 -0700273 return NULL;
274 }
275
276 // Build the arguments to the base metaclass.
277 // We change the __bases__ classes.
Feng Xiaoe841bac2015-12-11 17:09:20 -0800278 ScopedPyObjectPtr new_args;
279 const Descriptor* message_descriptor =
280 PyMessageDescriptor_AsDescriptor(py_descriptor);
281 if (message_descriptor == NULL) {
282 return NULL;
283 }
284
285 if (WKT_classes == NULL) {
286 ScopedPyObjectPtr well_known_types(PyImport_ImportModule(
287 "google.protobuf.internal.well_known_types"));
288 GOOGLE_DCHECK(well_known_types != NULL);
289
290 WKT_classes = PyObject_GetAttrString(well_known_types.get(), "WKTBASES");
291 GOOGLE_DCHECK(WKT_classes != NULL);
292 }
293
294 PyObject* well_known_class = PyDict_GetItemString(
295 WKT_classes, message_descriptor->full_name().c_str());
296 if (well_known_class == NULL) {
297 new_args.reset(Py_BuildValue("s(OO)O", name, &CMessage_Type,
298 PythonMessage_class, dict));
299 } else {
300 new_args.reset(Py_BuildValue("s(OOO)O", name, &CMessage_Type,
301 PythonMessage_class, well_known_class, dict));
302 }
303
Feng Xiaoeee38b02015-08-22 18:25:48 -0700304 if (new_args == NULL) {
305 return NULL;
306 }
307 // Call the base metaclass.
Josh Haberman00700b72015-10-06 14:13:09 -0700308 ScopedPyObjectPtr result(PyType_Type.tp_new(type, new_args.get(), NULL));
Feng Xiaoeee38b02015-08-22 18:25:48 -0700309 if (result == NULL) {
310 return NULL;
311 }
312 PyMessageMeta* newtype = reinterpret_cast<PyMessageMeta*>(result.get());
313
314 // Insert the empty weakref into the base classes.
315 if (InsertEmptyWeakref(
316 reinterpret_cast<PyTypeObject*>(PythonMessage_class)) < 0 ||
317 InsertEmptyWeakref(&CMessage_Type) < 0) {
318 return NULL;
319 }
320
321 // Cache the descriptor, both as Python object and as C++ pointer.
Jisi Liu46e8ff62015-10-05 11:59:43 -0700322 const Descriptor* descriptor =
323 PyMessageDescriptor_AsDescriptor(py_descriptor);
324 if (descriptor == NULL) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700325 return NULL;
326 }
Jisi Liu46e8ff62015-10-05 11:59:43 -0700327 Py_INCREF(py_descriptor);
328 newtype->py_message_descriptor = py_descriptor;
329 newtype->message_descriptor = descriptor;
330 // TODO(amauryfa): Don't always use the canonical pool of the descriptor,
331 // use the MessageFactory optionally passed in the class dict.
332 newtype->py_descriptor_pool = GetDescriptorPool_FromPool(
333 descriptor->file()->pool());
334 if (newtype->py_descriptor_pool == NULL) {
335 return NULL;
336 }
337 Py_INCREF(newtype->py_descriptor_pool);
338
339 // Add the message to the DescriptorPool.
340 if (cdescriptor_pool::RegisterMessageClass(newtype->py_descriptor_pool,
Josh Haberman70ffefa2015-10-06 14:53:47 -0700341 descriptor, result.get()) < 0) {
Jisi Liu46e8ff62015-10-05 11:59:43 -0700342 return NULL;
343 }
Feng Xiaoeee38b02015-08-22 18:25:48 -0700344
345 // Continue with type initialization: add other descriptors, enum values...
Josh Haberman00700b72015-10-06 14:13:09 -0700346 if (AddDescriptors(result.get(), descriptor) < 0) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700347 return NULL;
348 }
349 return result.release();
350}
351
352static void Dealloc(PyMessageMeta *self) {
353 Py_DECREF(self->py_message_descriptor);
Jisi Liu46e8ff62015-10-05 11:59:43 -0700354 Py_DECREF(self->py_descriptor_pool);
Feng Xiaoeee38b02015-08-22 18:25:48 -0700355 Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
356}
357
Feng Xiaoeee38b02015-08-22 18:25:48 -0700358
359// This function inserts and empty weakref at the end of the list of
360// subclasses for the main protocol buffer Message class.
361//
362// This eliminates a O(n^2) behaviour in the internal add_subclass
363// routine.
364static int InsertEmptyWeakref(PyTypeObject *base_type) {
365#if PY_MAJOR_VERSION >= 3
366 // Python 3.4 has already included the fix for the issue that this
367 // hack addresses. For further background and the fix please see
368 // https://bugs.python.org/issue17936.
369 return 0;
370#else
371 PyObject *subclasses = base_type->tp_subclasses;
372 if (subclasses && PyList_CheckExact(subclasses)) {
373 return PyList_Append(subclasses, kEmptyWeakref);
374 }
375 return 0;
376#endif // PY_MAJOR_VERSION >= 3
377}
378
379} // namespace message_meta
380
Josh Haberman4472b4a2015-08-28 19:21:49 -0700381PyTypeObject PyMessageMeta_Type = {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700382 PyVarObject_HEAD_INIT(&PyType_Type, 0)
383 FULL_MODULE_NAME ".MessageMeta", // tp_name
384 sizeof(PyMessageMeta), // tp_basicsize
385 0, // tp_itemsize
386 (destructor)message_meta::Dealloc, // tp_dealloc
387 0, // tp_print
388 0, // tp_getattr
389 0, // tp_setattr
390 0, // tp_compare
391 0, // tp_repr
392 0, // tp_as_number
393 0, // tp_as_sequence
394 0, // tp_as_mapping
395 0, // tp_hash
396 0, // tp_call
397 0, // tp_str
398 0, // tp_getattro
399 0, // tp_setattro
400 0, // tp_as_buffer
401 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags
402 "The metaclass of ProtocolMessages", // tp_doc
403 0, // tp_traverse
404 0, // tp_clear
405 0, // tp_richcompare
406 0, // tp_weaklistoffset
407 0, // tp_iter
408 0, // tp_iternext
409 0, // tp_methods
410 0, // tp_members
411 0, // tp_getset
412 0, // tp_base
413 0, // tp_dict
414 0, // tp_descr_get
415 0, // tp_descr_set
416 0, // tp_dictoffset
417 0, // tp_init
418 0, // tp_alloc
419 message_meta::New, // tp_new
420};
421
Jisi Liu46e8ff62015-10-05 11:59:43 -0700422static PyMessageMeta* CheckMessageClass(PyTypeObject* cls) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700423 if (!PyObject_TypeCheck(cls, &PyMessageMeta_Type)) {
424 PyErr_Format(PyExc_TypeError, "Class %s is not a Message", cls->tp_name);
425 return NULL;
426 }
Jisi Liu46e8ff62015-10-05 11:59:43 -0700427 return reinterpret_cast<PyMessageMeta*>(cls);
428}
429
430static const Descriptor* GetMessageDescriptor(PyTypeObject* cls) {
431 PyMessageMeta* type = CheckMessageClass(cls);
432 if (type == NULL) {
433 return NULL;
434 }
435 return type->message_descriptor;
Feng Xiaoeee38b02015-08-22 18:25:48 -0700436}
437
jieluo@google.combde4a322014-08-12 21:10:30 +0000438// Forward declarations
439namespace cmessage {
jieluo@google.combde4a322014-08-12 21:10:30 +0000440int InternalReleaseFieldByDescriptor(
Bo Yang5db21732015-05-21 14:28:59 -0700441 CMessage* self,
Jisi Liuada65562015-02-25 16:39:11 -0800442 const FieldDescriptor* field_descriptor,
Bo Yang5db21732015-05-21 14:28:59 -0700443 PyObject* composite_field);
jieluo@google.combde4a322014-08-12 21:10:30 +0000444} // namespace cmessage
445
446// ---------------------------------------------------------------------
447// Visiting the composite children of a CMessage
448
449struct ChildVisitor {
450 // Returns 0 on success, -1 on failure.
451 int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
452 return 0;
453 }
454
455 // Returns 0 on success, -1 on failure.
456 int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
457 return 0;
458 }
459
460 // Returns 0 on success, -1 on failure.
461 int VisitCMessage(CMessage* cmessage,
Jisi Liuada65562015-02-25 16:39:11 -0800462 const FieldDescriptor* field_descriptor) {
jieluo@google.combde4a322014-08-12 21:10:30 +0000463 return 0;
464 }
465};
466
467// Apply a function to a composite field. Does nothing if child is of
468// non-composite type.
469template<class Visitor>
470static int VisitCompositeField(const FieldDescriptor* descriptor,
471 PyObject* child,
472 Visitor visitor) {
Jisi Liuada65562015-02-25 16:39:11 -0800473 if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
474 if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
Bo Yang5db21732015-05-21 14:28:59 -0700475 if (descriptor->is_map()) {
Feng Xiaoe841bac2015-12-11 17:09:20 -0800476 MapContainer* container = reinterpret_cast<MapContainer*>(child);
477 if (visitor.VisitMapContainer(container) == -1) {
478 return -1;
Bo Yang5db21732015-05-21 14:28:59 -0700479 }
480 } else {
481 RepeatedCompositeContainer* container =
482 reinterpret_cast<RepeatedCompositeContainer*>(child);
483 if (visitor.VisitRepeatedCompositeContainer(container) == -1)
484 return -1;
485 }
jieluo@google.combde4a322014-08-12 21:10:30 +0000486 } else {
487 RepeatedScalarContainer* container =
488 reinterpret_cast<RepeatedScalarContainer*>(child);
489 if (visitor.VisitRepeatedScalarContainer(container) == -1)
490 return -1;
491 }
Jisi Liuada65562015-02-25 16:39:11 -0800492 } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
jieluo@google.combde4a322014-08-12 21:10:30 +0000493 CMessage* cmsg = reinterpret_cast<CMessage*>(child);
494 if (visitor.VisitCMessage(cmsg, descriptor) == -1)
495 return -1;
496 }
497 // The ExtensionDict might contain non-composite fields, which we
498 // skip here.
499 return 0;
500}
501
502// Visit each composite field and extension field of this CMessage.
503// Returns -1 on error and 0 on success.
504template<class Visitor>
505int ForEachCompositeField(CMessage* self, Visitor visitor) {
506 Py_ssize_t pos = 0;
507 PyObject* key;
508 PyObject* field;
509
510 // Visit normal fields.
Jisi Liuada65562015-02-25 16:39:11 -0800511 if (self->composite_fields) {
512 // Never use self->message in this function, it may be already freed.
513 const Descriptor* message_descriptor =
Feng Xiaoeee38b02015-08-22 18:25:48 -0700514 GetMessageDescriptor(Py_TYPE(self));
Jisi Liuada65562015-02-25 16:39:11 -0800515 while (PyDict_Next(self->composite_fields, &pos, &key, &field)) {
516 Py_ssize_t key_str_size;
517 char *key_str_data;
518 if (PyString_AsStringAndSize(key, &key_str_data, &key_str_size) != 0)
jieluo@google.combde4a322014-08-12 21:10:30 +0000519 return -1;
Jisi Liuada65562015-02-25 16:39:11 -0800520 const string key_str(key_str_data, key_str_size);
521 const FieldDescriptor* descriptor =
522 message_descriptor->FindFieldByName(key_str);
523 if (descriptor != NULL) {
524 if (VisitCompositeField(descriptor, field, visitor) == -1)
525 return -1;
526 }
jieluo@google.combde4a322014-08-12 21:10:30 +0000527 }
528 }
529
530 // Visit extension fields.
531 if (self->extensions != NULL) {
Jisi Liuada65562015-02-25 16:39:11 -0800532 pos = 0;
jieluo@google.combde4a322014-08-12 21:10:30 +0000533 while (PyDict_Next(self->extensions->values, &pos, &key, &field)) {
Jisi Liuada65562015-02-25 16:39:11 -0800534 const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key);
Feng Xiao6ef984a2014-11-10 17:34:54 -0800535 if (descriptor == NULL)
jieluo@google.combde4a322014-08-12 21:10:30 +0000536 return -1;
Feng Xiao6ef984a2014-11-10 17:34:54 -0800537 if (VisitCompositeField(descriptor, field, visitor) == -1)
jieluo@google.combde4a322014-08-12 21:10:30 +0000538 return -1;
539 }
540 }
541
542 return 0;
543}
544
545// ---------------------------------------------------------------------
546
547// Constants used for integer type range checking.
548PyObject* kPythonZero;
549PyObject* kint32min_py;
550PyObject* kint32max_py;
551PyObject* kuint32max_py;
552PyObject* kint64min_py;
553PyObject* kint64max_py;
554PyObject* kuint64max_py;
555
jieluo@google.combde4a322014-08-12 21:10:30 +0000556PyObject* EncodeError_class;
557PyObject* DecodeError_class;
558PyObject* PickleError_class;
559
560// Constant PyString values used for GetAttr/GetItem.
Feng Xiao6ef984a2014-11-10 17:34:54 -0800561static PyObject* k_cdescriptor;
jieluo@google.combde4a322014-08-12 21:10:30 +0000562static PyObject* kfull_name;
jieluo@google.combde4a322014-08-12 21:10:30 +0000563
564/* Is 64bit */
565void FormatTypeError(PyObject* arg, char* expected_types) {
566 PyObject* repr = PyObject_Repr(arg);
567 if (repr) {
568 PyErr_Format(PyExc_TypeError,
569 "%.100s has type %.100s, but expected one of: %s",
570 PyString_AsString(repr),
571 Py_TYPE(arg)->tp_name,
572 expected_types);
573 Py_DECREF(repr);
574 }
575}
576
577template<class T>
578bool CheckAndGetInteger(
579 PyObject* arg, T* value, PyObject* min, PyObject* max) {
580 bool is_long = PyLong_Check(arg);
581#if PY_MAJOR_VERSION < 3
582 if (!PyInt_Check(arg) && !is_long) {
583 FormatTypeError(arg, "int, long");
584 return false;
585 }
586 if (PyObject_Compare(min, arg) > 0 || PyObject_Compare(max, arg) < 0) {
587#else
588 if (!is_long) {
589 FormatTypeError(arg, "int");
590 return false;
591 }
592 if (PyObject_RichCompareBool(min, arg, Py_LE) != 1 ||
593 PyObject_RichCompareBool(max, arg, Py_GE) != 1) {
594#endif
Feng Xiaoe841bac2015-12-11 17:09:20 -0800595 if (!PyErr_Occurred()) {
596 PyObject *s = PyObject_Str(arg);
597 if (s) {
598 PyErr_Format(PyExc_ValueError,
599 "Value out of range: %s",
600 PyString_AsString(s));
601 Py_DECREF(s);
602 }
jieluo@google.combde4a322014-08-12 21:10:30 +0000603 }
604 return false;
605 }
606#if PY_MAJOR_VERSION < 3
607 if (!is_long) {
608 *value = static_cast<T>(PyInt_AsLong(arg));
609 } else // NOLINT
610#endif
611 {
612 if (min == kPythonZero) {
613 *value = static_cast<T>(PyLong_AsUnsignedLongLong(arg));
614 } else {
615 *value = static_cast<T>(PyLong_AsLongLong(arg));
616 }
617 }
618 return true;
619}
620
621// These are referenced by repeated_scalar_container, and must
622// be explicitly instantiated.
623template bool CheckAndGetInteger<int32>(
624 PyObject*, int32*, PyObject*, PyObject*);
625template bool CheckAndGetInteger<int64>(
626 PyObject*, int64*, PyObject*, PyObject*);
627template bool CheckAndGetInteger<uint32>(
628 PyObject*, uint32*, PyObject*, PyObject*);
629template bool CheckAndGetInteger<uint64>(
630 PyObject*, uint64*, PyObject*, PyObject*);
631
632bool CheckAndGetDouble(PyObject* arg, double* value) {
633 if (!PyInt_Check(arg) && !PyLong_Check(arg) &&
634 !PyFloat_Check(arg)) {
635 FormatTypeError(arg, "int, long, float");
636 return false;
637 }
638 *value = PyFloat_AsDouble(arg);
639 return true;
640}
641
642bool CheckAndGetFloat(PyObject* arg, float* value) {
643 double double_value;
644 if (!CheckAndGetDouble(arg, &double_value)) {
645 return false;
646 }
647 *value = static_cast<float>(double_value);
648 return true;
649}
650
651bool CheckAndGetBool(PyObject* arg, bool* value) {
652 if (!PyInt_Check(arg) && !PyBool_Check(arg) && !PyLong_Check(arg)) {
653 FormatTypeError(arg, "int, long, bool");
654 return false;
655 }
656 *value = static_cast<bool>(PyInt_AsLong(arg));
657 return true;
658}
659
Feng Xiaoe841bac2015-12-11 17:09:20 -0800660// Checks whether the given object (which must be "bytes" or "unicode") contains
661// valid UTF-8.
662bool IsValidUTF8(PyObject* obj) {
663 if (PyBytes_Check(obj)) {
664 PyObject* unicode = PyUnicode_FromEncodedObject(obj, "utf-8", NULL);
665
666 // Clear the error indicator; we report our own error when desired.
667 PyErr_Clear();
668
669 if (unicode) {
670 Py_DECREF(unicode);
671 return true;
672 } else {
673 return false;
674 }
675 } else {
676 // Unicode object, known to be valid UTF-8.
677 return true;
678 }
679}
680
681bool AllowInvalidUTF8(const FieldDescriptor* field) { return false; }
682
683PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor) {
Jisi Liuada65562015-02-25 16:39:11 -0800684 GOOGLE_DCHECK(descriptor->type() == FieldDescriptor::TYPE_STRING ||
685 descriptor->type() == FieldDescriptor::TYPE_BYTES);
686 if (descriptor->type() == FieldDescriptor::TYPE_STRING) {
jieluo@google.combde4a322014-08-12 21:10:30 +0000687 if (!PyBytes_Check(arg) && !PyUnicode_Check(arg)) {
688 FormatTypeError(arg, "bytes, unicode");
Feng Xiaoe841bac2015-12-11 17:09:20 -0800689 return NULL;
jieluo@google.combde4a322014-08-12 21:10:30 +0000690 }
691
Feng Xiaoe841bac2015-12-11 17:09:20 -0800692 if (!IsValidUTF8(arg) && !AllowInvalidUTF8(descriptor)) {
693 PyObject* repr = PyObject_Repr(arg);
694 PyErr_Format(PyExc_ValueError,
695 "%s has type str, but isn't valid UTF-8 "
696 "encoding. Non-UTF-8 strings must be converted to "
697 "unicode objects before being added.",
698 PyString_AsString(repr));
699 Py_DECREF(repr);
700 return NULL;
jieluo@google.combde4a322014-08-12 21:10:30 +0000701 }
702 } else if (!PyBytes_Check(arg)) {
703 FormatTypeError(arg, "bytes");
Feng Xiaoe841bac2015-12-11 17:09:20 -0800704 return NULL;
jieluo@google.combde4a322014-08-12 21:10:30 +0000705 }
706
707 PyObject* encoded_string = NULL;
Jisi Liuada65562015-02-25 16:39:11 -0800708 if (descriptor->type() == FieldDescriptor::TYPE_STRING) {
jieluo@google.combde4a322014-08-12 21:10:30 +0000709 if (PyBytes_Check(arg)) {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800710 // The bytes were already validated as correctly encoded UTF-8 above.
jieluo@google.combde4a322014-08-12 21:10:30 +0000711 encoded_string = arg; // Already encoded.
712 Py_INCREF(encoded_string);
jieluo@google.combde4a322014-08-12 21:10:30 +0000713 } else {
714 encoded_string = PyUnicode_AsEncodedObject(arg, "utf-8", NULL);
715 }
716 } else {
717 // In this case field type is "bytes".
718 encoded_string = arg;
719 Py_INCREF(encoded_string);
720 }
721
Feng Xiaoe841bac2015-12-11 17:09:20 -0800722 return encoded_string;
723}
724
725bool CheckAndSetString(
726 PyObject* arg, Message* message,
727 const FieldDescriptor* descriptor,
728 const Reflection* reflection,
729 bool append,
730 int index) {
731 ScopedPyObjectPtr encoded_string(CheckString(arg, descriptor));
732
733 if (encoded_string.get() == NULL) {
jieluo@google.combde4a322014-08-12 21:10:30 +0000734 return false;
735 }
736
737 char* value;
738 Py_ssize_t value_len;
Feng Xiaoe841bac2015-12-11 17:09:20 -0800739 if (PyBytes_AsStringAndSize(encoded_string.get(), &value, &value_len) < 0) {
jieluo@google.combde4a322014-08-12 21:10:30 +0000740 return false;
741 }
742
743 string value_string(value, value_len);
744 if (append) {
745 reflection->AddString(message, descriptor, value_string);
746 } else if (index < 0) {
747 reflection->SetString(message, descriptor, value_string);
748 } else {
749 reflection->SetRepeatedString(message, descriptor, index, value_string);
750 }
jieluo@google.combde4a322014-08-12 21:10:30 +0000751 return true;
752}
753
Jisi Liuada65562015-02-25 16:39:11 -0800754PyObject* ToStringObject(const FieldDescriptor* descriptor, string value) {
755 if (descriptor->type() != FieldDescriptor::TYPE_STRING) {
jieluo@google.combde4a322014-08-12 21:10:30 +0000756 return PyBytes_FromStringAndSize(value.c_str(), value.length());
757 }
758
759 PyObject* result = PyUnicode_DecodeUTF8(value.c_str(), value.length(), NULL);
760 // If the string can't be decoded in UTF-8, just return a string object that
761 // contains the raw bytes. This can't happen if the value was assigned using
762 // the members of the Python message object, but can happen if the values were
763 // parsed from the wire (binary).
764 if (result == NULL) {
765 PyErr_Clear();
766 result = PyBytes_FromStringAndSize(value.c_str(), value.length());
767 }
768 return result;
769}
770
Jisi Liuada65562015-02-25 16:39:11 -0800771bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor,
772 const Message* message) {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800773 if (message->GetDescriptor() == field_descriptor->containing_type()) {
774 return true;
775 }
776 PyErr_Format(PyExc_KeyError, "Field '%s' does not belong to message '%s'",
777 field_descriptor->full_name().c_str(),
778 message->GetDescriptor()->full_name().c_str());
779 return false;
780}
781
jieluo@google.combde4a322014-08-12 21:10:30 +0000782namespace cmessage {
783
Jisi Liu46e8ff62015-10-05 11:59:43 -0700784PyDescriptorPool* GetDescriptorPoolForMessage(CMessage* message) {
785 // No need to check the type: the type of instances of CMessage is always
786 // an instance of PyMessageMeta. Let's prove it with a debug-only check.
787 GOOGLE_DCHECK(PyObject_TypeCheck(message, &CMessage_Type));
788 return reinterpret_cast<PyMessageMeta*>(Py_TYPE(message))->py_descriptor_pool;
789}
790
791MessageFactory* GetFactoryForMessage(CMessage* message) {
792 return GetDescriptorPoolForMessage(message)->message_factory;
793}
794
jieluo@google.combde4a322014-08-12 21:10:30 +0000795static int MaybeReleaseOverlappingOneofField(
796 CMessage* cmessage,
Jisi Liuada65562015-02-25 16:39:11 -0800797 const FieldDescriptor* field) {
jieluo@google.combde4a322014-08-12 21:10:30 +0000798#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
Jisi Liuada65562015-02-25 16:39:11 -0800799 Message* message = cmessage->message;
800 const Reflection* reflection = message->GetReflection();
jieluo@google.combde4a322014-08-12 21:10:30 +0000801 if (!field->containing_oneof() ||
802 !reflection->HasOneof(*message, field->containing_oneof()) ||
803 reflection->HasField(*message, field)) {
804 // No other field in this oneof, no need to release.
805 return 0;
806 }
807
808 const OneofDescriptor* oneof = field->containing_oneof();
809 const FieldDescriptor* existing_field =
810 reflection->GetOneofFieldDescriptor(*message, oneof);
Jisi Liuada65562015-02-25 16:39:11 -0800811 if (existing_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
jieluo@google.combde4a322014-08-12 21:10:30 +0000812 // Non-message fields don't need to be released.
813 return 0;
814 }
815 const char* field_name = existing_field->name().c_str();
Jisi Liuada65562015-02-25 16:39:11 -0800816 PyObject* child_message = cmessage->composite_fields ?
817 PyDict_GetItemString(cmessage->composite_fields, field_name) : NULL;
jieluo@google.combde4a322014-08-12 21:10:30 +0000818 if (child_message == NULL) {
819 // No python reference to this field so no need to release.
820 return 0;
821 }
822
823 if (InternalReleaseFieldByDescriptor(
Bo Yang5db21732015-05-21 14:28:59 -0700824 cmessage, existing_field, child_message) < 0) {
jieluo@google.combde4a322014-08-12 21:10:30 +0000825 return -1;
826 }
827 return PyDict_DelItemString(cmessage->composite_fields, field_name);
828#else
829 return 0;
830#endif
831}
832
833// ---------------------------------------------------------------------
834// Making a message writable
835
Jisi Liuada65562015-02-25 16:39:11 -0800836static Message* GetMutableMessage(
jieluo@google.combde4a322014-08-12 21:10:30 +0000837 CMessage* parent,
Jisi Liuada65562015-02-25 16:39:11 -0800838 const FieldDescriptor* parent_field) {
839 Message* parent_message = parent->message;
840 const Reflection* reflection = parent_message->GetReflection();
jieluo@google.combde4a322014-08-12 21:10:30 +0000841 if (MaybeReleaseOverlappingOneofField(parent, parent_field) < 0) {
842 return NULL;
843 }
844 return reflection->MutableMessage(
Jisi Liu46e8ff62015-10-05 11:59:43 -0700845 parent_message, parent_field, GetFactoryForMessage(parent));
jieluo@google.combde4a322014-08-12 21:10:30 +0000846}
847
848struct FixupMessageReference : public ChildVisitor {
849 // message must outlive this object.
Jisi Liuada65562015-02-25 16:39:11 -0800850 explicit FixupMessageReference(Message* message) :
jieluo@google.combde4a322014-08-12 21:10:30 +0000851 message_(message) {}
852
853 int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
854 container->message = message_;
855 return 0;
856 }
857
858 int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
859 container->message = message_;
860 return 0;
861 }
862
Feng Xiaoe841bac2015-12-11 17:09:20 -0800863 int VisitMapContainer(MapContainer* container) {
Bo Yang5db21732015-05-21 14:28:59 -0700864 container->message = message_;
865 return 0;
866 }
867
jieluo@google.combde4a322014-08-12 21:10:30 +0000868 private:
Jisi Liuada65562015-02-25 16:39:11 -0800869 Message* message_;
jieluo@google.combde4a322014-08-12 21:10:30 +0000870};
871
872int AssureWritable(CMessage* self) {
873 if (self == NULL || !self->read_only) {
874 return 0;
875 }
876
877 if (self->parent == NULL) {
878 // If parent is NULL but we are trying to modify a read-only message, this
879 // is a reference to a constant default instance that needs to be replaced
880 // with a mutable top-level message.
Jisi Liu46e8ff62015-10-05 11:59:43 -0700881 self->message = self->message->New();
jieluo@google.combde4a322014-08-12 21:10:30 +0000882 self->owner.reset(self->message);
Bo Yang5db21732015-05-21 14:28:59 -0700883 // Cascade the new owner to eventual children: even if this message is
884 // empty, some submessages or repeated containers might exist already.
885 SetOwner(self, self->owner);
jieluo@google.combde4a322014-08-12 21:10:30 +0000886 } else {
887 // Otherwise, we need a mutable child message.
888 if (AssureWritable(self->parent) == -1)
889 return -1;
890
891 // Make self->message writable.
Jisi Liuada65562015-02-25 16:39:11 -0800892 Message* mutable_message = GetMutableMessage(
jieluo@google.combde4a322014-08-12 21:10:30 +0000893 self->parent,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800894 self->parent_field_descriptor);
jieluo@google.combde4a322014-08-12 21:10:30 +0000895 if (mutable_message == NULL) {
896 return -1;
897 }
898 self->message = mutable_message;
899 }
900 self->read_only = false;
901
902 // When a CMessage is made writable its Message pointer is updated
903 // to point to a new mutable Message. When that happens we need to
904 // update any references to the old, read-only CMessage. There are
Feng Xiaoe841bac2015-12-11 17:09:20 -0800905 // four places such references occur: RepeatedScalarContainer,
906 // RepeatedCompositeContainer, MapContainer, and ExtensionDict.
jieluo@google.combde4a322014-08-12 21:10:30 +0000907 if (self->extensions != NULL)
908 self->extensions->message = self->message;
909 if (ForEachCompositeField(self, FixupMessageReference(self->message)) == -1)
910 return -1;
911
912 return 0;
913}
914
915// --- Globals:
916
Feng Xiao6ef984a2014-11-10 17:34:54 -0800917// Retrieve a C++ FieldDescriptor for a message attribute.
918// The C++ message must be valid.
919// TODO(amauryfa): This function should stay internal, because exception
920// handling is not consistent.
Jisi Liuada65562015-02-25 16:39:11 -0800921static const FieldDescriptor* GetFieldDescriptor(
Feng Xiao6ef984a2014-11-10 17:34:54 -0800922 CMessage* self, PyObject* name) {
Jisi Liuada65562015-02-25 16:39:11 -0800923 const Descriptor *message_descriptor = self->message->GetDescriptor();
924 char* field_name;
925 Py_ssize_t size;
926 if (PyString_AsStringAndSize(name, &field_name, &size) < 0) {
jieluo@google.combde4a322014-08-12 21:10:30 +0000927 return NULL;
928 }
Jisi Liuada65562015-02-25 16:39:11 -0800929 const FieldDescriptor *field_descriptor =
930 message_descriptor->FindFieldByName(string(field_name, size));
Feng Xiao6ef984a2014-11-10 17:34:54 -0800931 if (field_descriptor == NULL) {
932 // Note: No exception is set!
933 return NULL;
934 }
935 return field_descriptor;
936}
937
938// Retrieve a C++ FieldDescriptor for an extension handle.
Jisi Liuada65562015-02-25 16:39:11 -0800939const FieldDescriptor* GetExtensionDescriptor(PyObject* extension) {
940 ScopedPyObjectPtr cdescriptor;
941 if (!PyObject_TypeCheck(extension, &PyFieldDescriptor_Type)) {
942 // Most callers consider extensions as a plain dictionary. We should
943 // allow input which is not a field descriptor, and simply pretend it does
944 // not exist.
945 PyErr_SetObject(PyExc_KeyError, extension);
Feng Xiao6ef984a2014-11-10 17:34:54 -0800946 return NULL;
947 }
Jisi Liuada65562015-02-25 16:39:11 -0800948 return PyFieldDescriptor_AsDescriptor(extension);
jieluo@google.combde4a322014-08-12 21:10:30 +0000949}
950
Bo Yang5db21732015-05-21 14:28:59 -0700951// If value is a string, convert it into an enum value based on the labels in
952// descriptor, otherwise simply return value. Always returns a new reference.
953static PyObject* GetIntegerEnumValue(const FieldDescriptor& descriptor,
954 PyObject* value) {
955 if (PyString_Check(value) || PyUnicode_Check(value)) {
956 const EnumDescriptor* enum_descriptor = descriptor.enum_type();
957 if (enum_descriptor == NULL) {
958 PyErr_SetString(PyExc_TypeError, "not an enum field");
959 return NULL;
960 }
961 char* enum_label;
962 Py_ssize_t size;
963 if (PyString_AsStringAndSize(value, &enum_label, &size) < 0) {
964 return NULL;
965 }
966 const EnumValueDescriptor* enum_value_descriptor =
967 enum_descriptor->FindValueByName(string(enum_label, size));
968 if (enum_value_descriptor == NULL) {
969 PyErr_SetString(PyExc_ValueError, "unknown enum label");
970 return NULL;
971 }
972 return PyInt_FromLong(enum_value_descriptor->number());
973 }
974 Py_INCREF(value);
975 return value;
976}
977
jieluo@google.combde4a322014-08-12 21:10:30 +0000978// If cmessage_list is not NULL, this function releases values into the
979// container CMessages instead of just removing. Repeated composite container
980// needs to do this to make sure CMessages stay alive if they're still
981// referenced after deletion. Repeated scalar container doesn't need to worry.
982int InternalDeleteRepeatedField(
Bo Yang5db21732015-05-21 14:28:59 -0700983 CMessage* self,
Jisi Liuada65562015-02-25 16:39:11 -0800984 const FieldDescriptor* field_descriptor,
jieluo@google.combde4a322014-08-12 21:10:30 +0000985 PyObject* slice,
986 PyObject* cmessage_list) {
Bo Yang5db21732015-05-21 14:28:59 -0700987 Message* message = self->message;
jieluo@google.combde4a322014-08-12 21:10:30 +0000988 Py_ssize_t length, from, to, step, slice_length;
Jisi Liuada65562015-02-25 16:39:11 -0800989 const Reflection* reflection = message->GetReflection();
jieluo@google.combde4a322014-08-12 21:10:30 +0000990 int min, max;
991 length = reflection->FieldSize(*message, field_descriptor);
992
993 if (PyInt_Check(slice) || PyLong_Check(slice)) {
994 from = to = PyLong_AsLong(slice);
995 if (from < 0) {
996 from = to = length + from;
997 }
998 step = 1;
999 min = max = from;
1000
1001 // Range check.
1002 if (from < 0 || from >= length) {
1003 PyErr_Format(PyExc_IndexError, "list assignment index out of range");
1004 return -1;
1005 }
1006 } else if (PySlice_Check(slice)) {
1007 from = to = step = slice_length = 0;
1008 PySlice_GetIndicesEx(
1009#if PY_MAJOR_VERSION < 3
1010 reinterpret_cast<PySliceObject*>(slice),
1011#else
1012 slice,
1013#endif
1014 length, &from, &to, &step, &slice_length);
1015 if (from < to) {
1016 min = from;
1017 max = to - 1;
1018 } else {
1019 min = to + 1;
1020 max = from;
1021 }
1022 } else {
1023 PyErr_SetString(PyExc_TypeError, "list indices must be integers");
1024 return -1;
1025 }
1026
1027 Py_ssize_t i = from;
1028 std::vector<bool> to_delete(length, false);
1029 while (i >= min && i <= max) {
1030 to_delete[i] = true;
1031 i += step;
1032 }
1033
1034 to = 0;
1035 for (i = 0; i < length; ++i) {
1036 if (!to_delete[i]) {
1037 if (i != to) {
1038 reflection->SwapElements(message, field_descriptor, i, to);
1039 if (cmessage_list != NULL) {
1040 // If a list of cmessages is passed in (i.e. from a repeated
1041 // composite container), swap those as well to correspond to the
1042 // swaps in the underlying message so they're in the right order
1043 // when we start releasing.
1044 PyObject* tmp = PyList_GET_ITEM(cmessage_list, i);
1045 PyList_SET_ITEM(cmessage_list, i,
1046 PyList_GET_ITEM(cmessage_list, to));
1047 PyList_SET_ITEM(cmessage_list, to, tmp);
1048 }
1049 }
1050 ++to;
1051 }
1052 }
1053
1054 while (i > to) {
1055 if (cmessage_list == NULL) {
1056 reflection->RemoveLast(message, field_descriptor);
1057 } else {
1058 CMessage* last_cmessage = reinterpret_cast<CMessage*>(
1059 PyList_GET_ITEM(cmessage_list, PyList_GET_SIZE(cmessage_list) - 1));
1060 repeated_composite_container::ReleaseLastTo(
Bo Yang5db21732015-05-21 14:28:59 -07001061 self, field_descriptor, last_cmessage);
jieluo@google.combde4a322014-08-12 21:10:30 +00001062 if (PySequence_DelItem(cmessage_list, -1) < 0) {
1063 return -1;
1064 }
1065 }
1066 --i;
1067 }
1068
1069 return 0;
1070}
1071
Feng Xiao6ef984a2014-11-10 17:34:54 -08001072// Initializes fields of a message. Used in constructors.
1073int InitAttributes(CMessage* self, PyObject* kwargs) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001074 if (kwargs == NULL) {
1075 return 0;
1076 }
1077
1078 Py_ssize_t pos = 0;
1079 PyObject* name;
1080 PyObject* value;
1081 while (PyDict_Next(kwargs, &pos, &name, &value)) {
1082 if (!PyString_Check(name)) {
1083 PyErr_SetString(PyExc_ValueError, "Field name must be a string");
1084 return -1;
1085 }
Jisi Liuada65562015-02-25 16:39:11 -08001086 const FieldDescriptor* descriptor = GetFieldDescriptor(self, name);
Feng Xiao6ef984a2014-11-10 17:34:54 -08001087 if (descriptor == NULL) {
Feng Xiaoe841bac2015-12-11 17:09:20 -08001088 PyErr_Format(PyExc_ValueError, "Protocol message %s has no \"%s\" field.",
1089 self->message->GetDescriptor()->name().c_str(),
jieluo@google.combde4a322014-08-12 21:10:30 +00001090 PyString_AsString(name));
1091 return -1;
1092 }
Bo Yang5db21732015-05-21 14:28:59 -07001093 if (descriptor->is_map()) {
1094 ScopedPyObjectPtr map(GetAttr(self, name));
1095 const FieldDescriptor* value_descriptor =
1096 descriptor->message_type()->FindFieldByName("value");
1097 if (value_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1098 Py_ssize_t map_pos = 0;
1099 PyObject* map_key;
1100 PyObject* map_value;
1101 while (PyDict_Next(value, &map_pos, &map_key, &map_value)) {
1102 ScopedPyObjectPtr function_return;
1103 function_return.reset(PyObject_GetItem(map.get(), map_key));
1104 if (function_return.get() == NULL) {
1105 return -1;
1106 }
1107 ScopedPyObjectPtr ok(PyObject_CallMethod(
1108 function_return.get(), "MergeFrom", "O", map_value));
1109 if (ok.get() == NULL) {
1110 return -1;
1111 }
1112 }
1113 } else {
1114 ScopedPyObjectPtr function_return;
1115 function_return.reset(
1116 PyObject_CallMethod(map.get(), "update", "O", value));
1117 if (function_return.get() == NULL) {
1118 return -1;
1119 }
1120 }
1121 } else if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001122 ScopedPyObjectPtr container(GetAttr(self, name));
1123 if (container == NULL) {
1124 return -1;
1125 }
Jisi Liuada65562015-02-25 16:39:11 -08001126 if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
Bo Yang5db21732015-05-21 14:28:59 -07001127 RepeatedCompositeContainer* rc_container =
1128 reinterpret_cast<RepeatedCompositeContainer*>(container.get());
1129 ScopedPyObjectPtr iter(PyObject_GetIter(value));
1130 if (iter == NULL) {
1131 PyErr_SetString(PyExc_TypeError, "Value must be iterable");
1132 return -1;
1133 }
1134 ScopedPyObjectPtr next;
Josh Haberman00700b72015-10-06 14:13:09 -07001135 while ((next.reset(PyIter_Next(iter.get()))) != NULL) {
1136 PyObject* kwargs = (PyDict_Check(next.get()) ? next.get() : NULL);
Bo Yang5db21732015-05-21 14:28:59 -07001137 ScopedPyObjectPtr new_msg(
1138 repeated_composite_container::Add(rc_container, NULL, kwargs));
1139 if (new_msg == NULL) {
1140 return -1;
1141 }
1142 if (kwargs == NULL) {
1143 // next was not a dict, it's a message we need to merge
Josh Haberman00700b72015-10-06 14:13:09 -07001144 ScopedPyObjectPtr merged(MergeFrom(
1145 reinterpret_cast<CMessage*>(new_msg.get()), next.get()));
1146 if (merged.get() == NULL) {
Bo Yang5db21732015-05-21 14:28:59 -07001147 return -1;
1148 }
1149 }
1150 }
1151 if (PyErr_Occurred()) {
1152 // Check to see how PyIter_Next() exited.
1153 return -1;
1154 }
1155 } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
1156 RepeatedScalarContainer* rs_container =
1157 reinterpret_cast<RepeatedScalarContainer*>(container.get());
1158 ScopedPyObjectPtr iter(PyObject_GetIter(value));
1159 if (iter == NULL) {
1160 PyErr_SetString(PyExc_TypeError, "Value must be iterable");
1161 return -1;
1162 }
1163 ScopedPyObjectPtr next;
Josh Haberman00700b72015-10-06 14:13:09 -07001164 while ((next.reset(PyIter_Next(iter.get()))) != NULL) {
1165 ScopedPyObjectPtr enum_value(
1166 GetIntegerEnumValue(*descriptor, next.get()));
Bo Yang5db21732015-05-21 14:28:59 -07001167 if (enum_value == NULL) {
1168 return -1;
1169 }
Josh Haberman00700b72015-10-06 14:13:09 -07001170 ScopedPyObjectPtr new_msg(repeated_scalar_container::Append(
1171 rs_container, enum_value.get()));
Bo Yang5db21732015-05-21 14:28:59 -07001172 if (new_msg == NULL) {
1173 return -1;
1174 }
1175 }
1176 if (PyErr_Occurred()) {
1177 // Check to see how PyIter_Next() exited.
jieluo@google.combde4a322014-08-12 21:10:30 +00001178 return -1;
1179 }
1180 } else {
Feng Xiaoeee38b02015-08-22 18:25:48 -07001181 if (ScopedPyObjectPtr(repeated_scalar_container::Extend(
jieluo@google.combde4a322014-08-12 21:10:30 +00001182 reinterpret_cast<RepeatedScalarContainer*>(container.get()),
Feng Xiaoeee38b02015-08-22 18:25:48 -07001183 value)) ==
jieluo@google.combde4a322014-08-12 21:10:30 +00001184 NULL) {
1185 return -1;
1186 }
1187 }
Jisi Liuada65562015-02-25 16:39:11 -08001188 } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001189 ScopedPyObjectPtr message(GetAttr(self, name));
1190 if (message == NULL) {
1191 return -1;
1192 }
Bo Yang5db21732015-05-21 14:28:59 -07001193 CMessage* cmessage = reinterpret_cast<CMessage*>(message.get());
1194 if (PyDict_Check(value)) {
1195 if (InitAttributes(cmessage, value) < 0) {
1196 return -1;
1197 }
1198 } else {
1199 ScopedPyObjectPtr merged(MergeFrom(cmessage, value));
1200 if (merged == NULL) {
1201 return -1;
1202 }
jieluo@google.combde4a322014-08-12 21:10:30 +00001203 }
1204 } else {
Bo Yang5db21732015-05-21 14:28:59 -07001205 ScopedPyObjectPtr new_val;
1206 if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
1207 new_val.reset(GetIntegerEnumValue(*descriptor, value));
1208 if (new_val == NULL) {
1209 return -1;
1210 }
1211 }
Josh Haberman00700b72015-10-06 14:13:09 -07001212 if (SetAttr(self, name, (new_val.get() == NULL) ? value : new_val.get()) <
1213 0) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001214 return -1;
1215 }
1216 }
1217 }
1218 return 0;
1219}
1220
Feng Xiao6ef984a2014-11-10 17:34:54 -08001221// Allocates an incomplete Python Message: the caller must fill self->message,
1222// self->owner and eventually self->parent.
Jisi Liuada65562015-02-25 16:39:11 -08001223CMessage* NewEmptyMessage(PyObject* type, const Descriptor *descriptor) {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001224 CMessage* self = reinterpret_cast<CMessage*>(
1225 PyType_GenericAlloc(reinterpret_cast<PyTypeObject*>(type), 0));
jieluo@google.combde4a322014-08-12 21:10:30 +00001226 if (self == NULL) {
1227 return NULL;
1228 }
1229
1230 self->message = NULL;
1231 self->parent = NULL;
Feng Xiao6ef984a2014-11-10 17:34:54 -08001232 self->parent_field_descriptor = NULL;
jieluo@google.combde4a322014-08-12 21:10:30 +00001233 self->read_only = false;
1234 self->extensions = NULL;
1235
Jisi Liuada65562015-02-25 16:39:11 -08001236 self->composite_fields = NULL;
Feng Xiao6ef984a2014-11-10 17:34:54 -08001237
Feng Xiao6ef984a2014-11-10 17:34:54 -08001238 return self;
1239}
1240
1241// The __new__ method of Message classes.
1242// Creates a new C++ message and takes ownership.
Jisi Liu46e8ff62015-10-05 11:59:43 -07001243static PyObject* New(PyTypeObject* cls,
Feng Xiao6ef984a2014-11-10 17:34:54 -08001244 PyObject* unused_args, PyObject* unused_kwargs) {
Jisi Liu46e8ff62015-10-05 11:59:43 -07001245 PyMessageMeta* type = CheckMessageClass(cls);
1246 if (type == NULL) {
1247 return NULL;
1248 }
Feng Xiao6ef984a2014-11-10 17:34:54 -08001249 // Retrieve the message descriptor and the default instance (=prototype).
Jisi Liu46e8ff62015-10-05 11:59:43 -07001250 const Descriptor* message_descriptor = type->message_descriptor;
Feng Xiao6ef984a2014-11-10 17:34:54 -08001251 if (message_descriptor == NULL) {
1252 return NULL;
1253 }
Jisi Liu46e8ff62015-10-05 11:59:43 -07001254 const Message* default_message = type->py_descriptor_pool->message_factory
1255 ->GetPrototype(message_descriptor);
Feng Xiao6ef984a2014-11-10 17:34:54 -08001256 if (default_message == NULL) {
1257 PyErr_SetString(PyExc_TypeError, message_descriptor->full_name().c_str());
1258 return NULL;
1259 }
1260
1261 CMessage* self = NewEmptyMessage(reinterpret_cast<PyObject*>(type),
1262 message_descriptor);
1263 if (self == NULL) {
1264 return NULL;
1265 }
1266 self->message = default_message->New();
1267 self->owner.reset(self->message);
jieluo@google.combde4a322014-08-12 21:10:30 +00001268 return reinterpret_cast<PyObject*>(self);
1269}
1270
Feng Xiao6ef984a2014-11-10 17:34:54 -08001271// The __init__ method of Message classes.
1272// It initializes fields from keywords passed to the constructor.
jieluo@google.combde4a322014-08-12 21:10:30 +00001273static int Init(CMessage* self, PyObject* args, PyObject* kwargs) {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001274 if (PyTuple_Size(args) != 0) {
1275 PyErr_SetString(PyExc_TypeError, "No positional arguments allowed");
jieluo@google.combde4a322014-08-12 21:10:30 +00001276 return -1;
1277 }
1278
Feng Xiao6ef984a2014-11-10 17:34:54 -08001279 return InitAttributes(self, kwargs);
jieluo@google.combde4a322014-08-12 21:10:30 +00001280}
1281
1282// ---------------------------------------------------------------------
1283// Deallocating a CMessage
1284//
1285// Deallocating a CMessage requires that we clear any weak references
1286// from children to the message being deallocated.
1287
1288// Clear the weak reference from the child to the parent.
1289struct ClearWeakReferences : public ChildVisitor {
1290 int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
1291 container->parent = NULL;
1292 // The elements in the container have the same parent as the
1293 // container itself, so NULL out that pointer as well.
1294 const Py_ssize_t n = PyList_GET_SIZE(container->child_messages);
1295 for (Py_ssize_t i = 0; i < n; ++i) {
1296 CMessage* child_cmessage = reinterpret_cast<CMessage*>(
1297 PyList_GET_ITEM(container->child_messages, i));
1298 child_cmessage->parent = NULL;
1299 }
1300 return 0;
1301 }
1302
1303 int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
1304 container->parent = NULL;
1305 return 0;
1306 }
1307
Feng Xiaoe841bac2015-12-11 17:09:20 -08001308 int VisitMapContainer(MapContainer* container) {
Bo Yang5db21732015-05-21 14:28:59 -07001309 container->parent = NULL;
1310 return 0;
1311 }
1312
jieluo@google.combde4a322014-08-12 21:10:30 +00001313 int VisitCMessage(CMessage* cmessage,
Jisi Liuada65562015-02-25 16:39:11 -08001314 const FieldDescriptor* field_descriptor) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001315 cmessage->parent = NULL;
1316 return 0;
1317 }
1318};
1319
1320static void Dealloc(CMessage* self) {
1321 // Null out all weak references from children to this message.
1322 GOOGLE_CHECK_EQ(0, ForEachCompositeField(self, ClearWeakReferences()));
Feng Xiaoe841bac2015-12-11 17:09:20 -08001323 if (self->extensions) {
1324 self->extensions->parent = NULL;
1325 }
jieluo@google.combde4a322014-08-12 21:10:30 +00001326
1327 Py_CLEAR(self->extensions);
1328 Py_CLEAR(self->composite_fields);
1329 self->owner.reset();
1330 Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
1331}
1332
1333// ---------------------------------------------------------------------
1334
1335
1336PyObject* IsInitialized(CMessage* self, PyObject* args) {
1337 PyObject* errors = NULL;
1338 if (PyArg_ParseTuple(args, "|O", &errors) < 0) {
1339 return NULL;
1340 }
1341 if (self->message->IsInitialized()) {
1342 Py_RETURN_TRUE;
1343 }
1344 if (errors != NULL) {
1345 ScopedPyObjectPtr initialization_errors(
1346 FindInitializationErrors(self));
1347 if (initialization_errors == NULL) {
1348 return NULL;
1349 }
1350 ScopedPyObjectPtr extend_name(PyString_FromString("extend"));
1351 if (extend_name == NULL) {
1352 return NULL;
1353 }
1354 ScopedPyObjectPtr result(PyObject_CallMethodObjArgs(
1355 errors,
1356 extend_name.get(),
1357 initialization_errors.get(),
1358 NULL));
1359 if (result == NULL) {
1360 return NULL;
1361 }
1362 }
1363 Py_RETURN_FALSE;
1364}
1365
1366PyObject* HasFieldByDescriptor(
Jisi Liuada65562015-02-25 16:39:11 -08001367 CMessage* self, const FieldDescriptor* field_descriptor) {
1368 Message* message = self->message;
Feng Xiao6ef984a2014-11-10 17:34:54 -08001369 if (!CheckFieldBelongsToMessage(field_descriptor, message)) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001370 return NULL;
1371 }
Jisi Liuada65562015-02-25 16:39:11 -08001372 if (field_descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001373 PyErr_SetString(PyExc_KeyError,
1374 "Field is repeated. A singular method is required.");
1375 return NULL;
1376 }
1377 bool has_field =
1378 message->GetReflection()->HasField(*message, field_descriptor);
1379 return PyBool_FromLong(has_field ? 1 : 0);
1380}
1381
Jisi Liuada65562015-02-25 16:39:11 -08001382const FieldDescriptor* FindFieldWithOneofs(
1383 const Message* message, const string& field_name, bool* in_oneof) {
1384 *in_oneof = false;
1385 const Descriptor* descriptor = message->GetDescriptor();
1386 const FieldDescriptor* field_descriptor =
jieluo@google.combde4a322014-08-12 21:10:30 +00001387 descriptor->FindFieldByName(field_name);
Jisi Liuada65562015-02-25 16:39:11 -08001388 if (field_descriptor != NULL) {
1389 return field_descriptor;
1390 }
1391 const OneofDescriptor* oneof_desc =
1392 descriptor->FindOneofByName(field_name);
1393 if (oneof_desc != NULL) {
1394 *in_oneof = true;
1395 return message->GetReflection()->GetOneofFieldDescriptor(*message,
1396 oneof_desc);
1397 }
1398 return NULL;
1399}
1400
1401bool CheckHasPresence(const FieldDescriptor* field_descriptor, bool in_oneof) {
1402 if (field_descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
1403 PyErr_Format(PyExc_ValueError,
1404 "Protocol message has no singular \"%s\" field.",
1405 field_descriptor->name().c_str());
1406 return false;
1407 }
1408
1409 if (field_descriptor->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
1410 // HasField() for a oneof *itself* isn't supported.
1411 if (in_oneof) {
1412 PyErr_Format(PyExc_ValueError,
1413 "Can't test oneof field \"%s\" for presence in proto3, use "
1414 "WhichOneof instead.",
1415 field_descriptor->containing_oneof()->name().c_str());
1416 return false;
1417 }
1418
1419 // ...but HasField() for fields *in* a oneof is supported.
1420 if (field_descriptor->containing_oneof() != NULL) {
1421 return true;
1422 }
1423
1424 if (field_descriptor->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
1425 PyErr_Format(
1426 PyExc_ValueError,
1427 "Can't test non-submessage field \"%s\" for presence in proto3.",
1428 field_descriptor->name().c_str());
1429 return false;
jieluo@google.combde4a322014-08-12 21:10:30 +00001430 }
1431 }
Jisi Liuada65562015-02-25 16:39:11 -08001432
1433 return true;
jieluo@google.combde4a322014-08-12 21:10:30 +00001434}
1435
1436PyObject* HasField(CMessage* self, PyObject* arg) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001437 char* field_name;
Jisi Liuada65562015-02-25 16:39:11 -08001438 Py_ssize_t size;
1439#if PY_MAJOR_VERSION < 3
1440 if (PyString_AsStringAndSize(arg, &field_name, &size) < 0) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001441 return NULL;
1442 }
Jisi Liuada65562015-02-25 16:39:11 -08001443#else
1444 field_name = PyUnicode_AsUTF8AndSize(arg, &size);
1445 if (!field_name) {
1446 return NULL;
1447 }
1448#endif
jieluo@google.combde4a322014-08-12 21:10:30 +00001449
Jisi Liuada65562015-02-25 16:39:11 -08001450 Message* message = self->message;
jieluo@google.combde4a322014-08-12 21:10:30 +00001451 bool is_in_oneof;
Jisi Liuada65562015-02-25 16:39:11 -08001452 const FieldDescriptor* field_descriptor =
1453 FindFieldWithOneofs(message, string(field_name, size), &is_in_oneof);
jieluo@google.combde4a322014-08-12 21:10:30 +00001454 if (field_descriptor == NULL) {
1455 if (!is_in_oneof) {
1456 PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name);
1457 return NULL;
1458 } else {
1459 Py_RETURN_FALSE;
1460 }
1461 }
1462
Jisi Liuada65562015-02-25 16:39:11 -08001463 if (!CheckHasPresence(field_descriptor, is_in_oneof)) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001464 return NULL;
1465 }
1466
Jisi Liuada65562015-02-25 16:39:11 -08001467 if (message->GetReflection()->HasField(*message, field_descriptor)) {
1468 Py_RETURN_TRUE;
1469 }
1470 if (!message->GetReflection()->SupportsUnknownEnumValues() &&
1471 field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
1472 // Special case: Python HasField() differs in semantics from C++
1473 // slightly: we return HasField('enum_field') == true if there is
1474 // an unknown enum value present. To implement this we have to
1475 // look in the UnknownFieldSet.
1476 const UnknownFieldSet& unknown_field_set =
jieluo@google.combde4a322014-08-12 21:10:30 +00001477 message->GetReflection()->GetUnknownFields(*message);
1478 for (int i = 0; i < unknown_field_set.field_count(); ++i) {
1479 if (unknown_field_set.field(i).number() == field_descriptor->number()) {
1480 Py_RETURN_TRUE;
1481 }
1482 }
jieluo@google.combde4a322014-08-12 21:10:30 +00001483 }
Jisi Liuada65562015-02-25 16:39:11 -08001484 Py_RETURN_FALSE;
jieluo@google.combde4a322014-08-12 21:10:30 +00001485}
1486
Feng Xiaoe841bac2015-12-11 17:09:20 -08001487PyObject* ClearExtension(CMessage* self, PyObject* extension) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001488 if (self->extensions != NULL) {
Feng Xiaoe841bac2015-12-11 17:09:20 -08001489 return extension_dict::ClearExtension(self->extensions, extension);
1490 } else {
1491 const FieldDescriptor* descriptor = GetExtensionDescriptor(extension);
1492 if (descriptor == NULL) {
1493 return NULL;
1494 }
1495 if (ScopedPyObjectPtr(ClearFieldByDescriptor(self, descriptor)) == NULL) {
1496 return NULL;
1497 }
jieluo@google.combde4a322014-08-12 21:10:30 +00001498 }
Feng Xiaoe841bac2015-12-11 17:09:20 -08001499 Py_RETURN_NONE;
jieluo@google.combde4a322014-08-12 21:10:30 +00001500}
1501
Feng Xiaoe841bac2015-12-11 17:09:20 -08001502PyObject* HasExtension(CMessage* self, PyObject* extension) {
1503 const FieldDescriptor* descriptor = GetExtensionDescriptor(extension);
1504 if (descriptor == NULL) {
1505 return NULL;
jieluo@google.combde4a322014-08-12 21:10:30 +00001506 }
Feng Xiaoe841bac2015-12-11 17:09:20 -08001507 return HasFieldByDescriptor(self, descriptor);
jieluo@google.combde4a322014-08-12 21:10:30 +00001508}
1509
1510// ---------------------------------------------------------------------
1511// Releasing messages
1512//
1513// The Python API's ClearField() and Clear() methods behave
1514// differently than their C++ counterparts. While the C++ versions
1515// clears the children the Python versions detaches the children,
1516// without touching their content. This impedance mismatch causes
1517// some complexity in the implementation, which is captured in this
1518// section.
1519//
1520// When a CMessage field is cleared we need to:
1521//
1522// * Release the Message used as the backing store for the CMessage
1523// from its parent.
1524//
1525// * Change the owner field of the released CMessage and all of its
1526// children to point to the newly released Message.
1527//
1528// * Clear the weak references from the released CMessage to the
1529// parent.
1530//
1531// When a RepeatedCompositeContainer field is cleared we need to:
1532//
1533// * Release all the Message used as the backing store for the
1534// CMessages stored in the container.
1535//
1536// * Change the owner field of all the released CMessage and all of
1537// their children to point to the newly released Messages.
1538//
1539// * Clear the weak references from the released container to the
1540// parent.
1541
1542struct SetOwnerVisitor : public ChildVisitor {
1543 // new_owner must outlive this object.
1544 explicit SetOwnerVisitor(const shared_ptr<Message>& new_owner)
1545 : new_owner_(new_owner) {}
1546
1547 int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
1548 repeated_composite_container::SetOwner(container, new_owner_);
1549 return 0;
1550 }
1551
1552 int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
1553 repeated_scalar_container::SetOwner(container, new_owner_);
1554 return 0;
1555 }
1556
Feng Xiaoe841bac2015-12-11 17:09:20 -08001557 int VisitMapContainer(MapContainer* container) {
1558 container->SetOwner(new_owner_);
Bo Yang5db21732015-05-21 14:28:59 -07001559 return 0;
1560 }
1561
jieluo@google.combde4a322014-08-12 21:10:30 +00001562 int VisitCMessage(CMessage* cmessage,
Jisi Liuada65562015-02-25 16:39:11 -08001563 const FieldDescriptor* field_descriptor) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001564 return SetOwner(cmessage, new_owner_);
1565 }
1566
1567 private:
1568 const shared_ptr<Message>& new_owner_;
1569};
1570
1571// Change the owner of this CMessage and all its children, recursively.
1572int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner) {
1573 self->owner = new_owner;
1574 if (ForEachCompositeField(self, SetOwnerVisitor(new_owner)) == -1)
1575 return -1;
1576 return 0;
1577}
1578
1579// Releases the message specified by 'field' and returns the
1580// pointer. If the field does not exist a new message is created using
1581// 'descriptor'. The caller takes ownership of the returned pointer.
Bo Yang5db21732015-05-21 14:28:59 -07001582Message* ReleaseMessage(CMessage* self,
Jisi Liuada65562015-02-25 16:39:11 -08001583 const Descriptor* descriptor,
1584 const FieldDescriptor* field_descriptor) {
Jisi Liu46e8ff62015-10-05 11:59:43 -07001585 MessageFactory* message_factory = GetFactoryForMessage(self);
Bo Yang5db21732015-05-21 14:28:59 -07001586 Message* released_message = self->message->GetReflection()->ReleaseMessage(
1587 self->message, field_descriptor, message_factory);
jieluo@google.combde4a322014-08-12 21:10:30 +00001588 // ReleaseMessage will return NULL which differs from
1589 // child_cmessage->message, if the field does not exist. In this case,
1590 // the latter points to the default instance via a const_cast<>, so we
1591 // have to reset it to a new mutable object since we are taking ownership.
1592 if (released_message == NULL) {
Jisi Liuada65562015-02-25 16:39:11 -08001593 const Message* prototype = message_factory->GetPrototype(descriptor);
jieluo@google.combde4a322014-08-12 21:10:30 +00001594 GOOGLE_DCHECK(prototype != NULL);
1595 released_message = prototype->New();
1596 }
1597
1598 return released_message;
1599}
1600
Bo Yang5db21732015-05-21 14:28:59 -07001601int ReleaseSubMessage(CMessage* self,
Jisi Liuada65562015-02-25 16:39:11 -08001602 const FieldDescriptor* field_descriptor,
jieluo@google.combde4a322014-08-12 21:10:30 +00001603 CMessage* child_cmessage) {
1604 // Release the Message
1605 shared_ptr<Message> released_message(ReleaseMessage(
Bo Yang5db21732015-05-21 14:28:59 -07001606 self, child_cmessage->message->GetDescriptor(), field_descriptor));
jieluo@google.combde4a322014-08-12 21:10:30 +00001607 child_cmessage->message = released_message.get();
1608 child_cmessage->owner.swap(released_message);
1609 child_cmessage->parent = NULL;
Feng Xiao6ef984a2014-11-10 17:34:54 -08001610 child_cmessage->parent_field_descriptor = NULL;
jieluo@google.combde4a322014-08-12 21:10:30 +00001611 child_cmessage->read_only = false;
1612 return ForEachCompositeField(child_cmessage,
1613 SetOwnerVisitor(child_cmessage->owner));
1614}
1615
1616struct ReleaseChild : public ChildVisitor {
1617 // message must outlive this object.
Bo Yang5db21732015-05-21 14:28:59 -07001618 explicit ReleaseChild(CMessage* parent) :
1619 parent_(parent) {}
jieluo@google.combde4a322014-08-12 21:10:30 +00001620
1621 int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
1622 return repeated_composite_container::Release(
1623 reinterpret_cast<RepeatedCompositeContainer*>(container));
1624 }
1625
1626 int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
1627 return repeated_scalar_container::Release(
1628 reinterpret_cast<RepeatedScalarContainer*>(container));
1629 }
1630
Feng Xiaoe841bac2015-12-11 17:09:20 -08001631 int VisitMapContainer(MapContainer* container) {
1632 return reinterpret_cast<MapContainer*>(container)->Release();
Bo Yang5db21732015-05-21 14:28:59 -07001633 }
1634
jieluo@google.combde4a322014-08-12 21:10:30 +00001635 int VisitCMessage(CMessage* cmessage,
Jisi Liuada65562015-02-25 16:39:11 -08001636 const FieldDescriptor* field_descriptor) {
Bo Yang5db21732015-05-21 14:28:59 -07001637 return ReleaseSubMessage(parent_, field_descriptor,
jieluo@google.combde4a322014-08-12 21:10:30 +00001638 reinterpret_cast<CMessage*>(cmessage));
1639 }
1640
Bo Yang5db21732015-05-21 14:28:59 -07001641 CMessage* parent_;
jieluo@google.combde4a322014-08-12 21:10:30 +00001642};
1643
1644int InternalReleaseFieldByDescriptor(
Bo Yang5db21732015-05-21 14:28:59 -07001645 CMessage* self,
Jisi Liuada65562015-02-25 16:39:11 -08001646 const FieldDescriptor* field_descriptor,
Bo Yang5db21732015-05-21 14:28:59 -07001647 PyObject* composite_field) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001648 return VisitCompositeField(
1649 field_descriptor,
1650 composite_field,
Bo Yang5db21732015-05-21 14:28:59 -07001651 ReleaseChild(self));
jieluo@google.combde4a322014-08-12 21:10:30 +00001652}
1653
jieluo@google.combde4a322014-08-12 21:10:30 +00001654PyObject* ClearFieldByDescriptor(
1655 CMessage* self,
Jisi Liuada65562015-02-25 16:39:11 -08001656 const FieldDescriptor* descriptor) {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001657 if (!CheckFieldBelongsToMessage(descriptor, self->message)) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001658 return NULL;
1659 }
1660 AssureWritable(self);
1661 self->message->GetReflection()->ClearField(self->message, descriptor);
1662 Py_RETURN_NONE;
1663}
1664
1665PyObject* ClearField(CMessage* self, PyObject* arg) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001666 if (!PyString_Check(arg)) {
1667 PyErr_SetString(PyExc_TypeError, "field name must be a string");
1668 return NULL;
1669 }
1670#if PY_MAJOR_VERSION < 3
Jisi Liuada65562015-02-25 16:39:11 -08001671 const char* field_name = PyString_AS_STRING(arg);
1672 Py_ssize_t size = PyString_GET_SIZE(arg);
jieluo@google.combde4a322014-08-12 21:10:30 +00001673#else
Jisi Liuada65562015-02-25 16:39:11 -08001674 Py_ssize_t size;
1675 const char* field_name = PyUnicode_AsUTF8AndSize(arg, &size);
jieluo@google.combde4a322014-08-12 21:10:30 +00001676#endif
1677 AssureWritable(self);
Jisi Liuada65562015-02-25 16:39:11 -08001678 Message* message = self->message;
jieluo@google.combde4a322014-08-12 21:10:30 +00001679 ScopedPyObjectPtr arg_in_oneof;
1680 bool is_in_oneof;
Jisi Liuada65562015-02-25 16:39:11 -08001681 const FieldDescriptor* field_descriptor =
1682 FindFieldWithOneofs(message, string(field_name, size), &is_in_oneof);
jieluo@google.combde4a322014-08-12 21:10:30 +00001683 if (field_descriptor == NULL) {
1684 if (!is_in_oneof) {
1685 PyErr_Format(PyExc_ValueError,
1686 "Protocol message has no \"%s\" field.", field_name);
1687 return NULL;
1688 } else {
1689 Py_RETURN_NONE;
1690 }
1691 } else if (is_in_oneof) {
Jisi Liuada65562015-02-25 16:39:11 -08001692 const string& name = field_descriptor->name();
1693 arg_in_oneof.reset(PyString_FromStringAndSize(name.c_str(), name.size()));
jieluo@google.combde4a322014-08-12 21:10:30 +00001694 arg = arg_in_oneof.get();
1695 }
1696
Jisi Liuada65562015-02-25 16:39:11 -08001697 PyObject* composite_field = self->composite_fields ?
1698 PyDict_GetItem(self->composite_fields, arg) : NULL;
jieluo@google.combde4a322014-08-12 21:10:30 +00001699
1700 // Only release the field if there's a possibility that there are
1701 // references to it.
1702 if (composite_field != NULL) {
Bo Yang5db21732015-05-21 14:28:59 -07001703 if (InternalReleaseFieldByDescriptor(self, field_descriptor,
1704 composite_field) < 0) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001705 return NULL;
1706 }
1707 PyDict_DelItem(self->composite_fields, arg);
1708 }
1709 message->GetReflection()->ClearField(message, field_descriptor);
Jisi Liuada65562015-02-25 16:39:11 -08001710 if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
1711 !message->GetReflection()->SupportsUnknownEnumValues()) {
1712 UnknownFieldSet* unknown_field_set =
jieluo@google.combde4a322014-08-12 21:10:30 +00001713 message->GetReflection()->MutableUnknownFields(message);
1714 unknown_field_set->DeleteByNumber(field_descriptor->number());
1715 }
1716
1717 Py_RETURN_NONE;
1718}
1719
1720PyObject* Clear(CMessage* self) {
1721 AssureWritable(self);
Bo Yang5db21732015-05-21 14:28:59 -07001722 if (ForEachCompositeField(self, ReleaseChild(self)) == -1)
jieluo@google.combde4a322014-08-12 21:10:30 +00001723 return NULL;
Feng Xiaoe841bac2015-12-11 17:09:20 -08001724 Py_CLEAR(self->extensions);
Jisi Liuada65562015-02-25 16:39:11 -08001725 if (self->composite_fields) {
1726 PyDict_Clear(self->composite_fields);
1727 }
jieluo@google.combde4a322014-08-12 21:10:30 +00001728 self->message->Clear();
1729 Py_RETURN_NONE;
1730}
1731
1732// ---------------------------------------------------------------------
1733
1734static string GetMessageName(CMessage* self) {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001735 if (self->parent_field_descriptor != NULL) {
1736 return self->parent_field_descriptor->full_name();
jieluo@google.combde4a322014-08-12 21:10:30 +00001737 } else {
1738 return self->message->GetDescriptor()->full_name();
1739 }
1740}
1741
1742static PyObject* SerializeToString(CMessage* self, PyObject* args) {
1743 if (!self->message->IsInitialized()) {
1744 ScopedPyObjectPtr errors(FindInitializationErrors(self));
1745 if (errors == NULL) {
1746 return NULL;
1747 }
1748 ScopedPyObjectPtr comma(PyString_FromString(","));
1749 if (comma == NULL) {
1750 return NULL;
1751 }
1752 ScopedPyObjectPtr joined(
1753 PyObject_CallMethod(comma.get(), "join", "O", errors.get()));
1754 if (joined == NULL) {
1755 return NULL;
1756 }
Josh Haberman0b70a432015-02-25 20:17:32 -08001757
1758 // TODO(haberman): this is a (hopefully temporary) hack. The unit testing
1759 // infrastructure reloads all pure-Python modules for every test, but not
1760 // C++ modules (because that's generally impossible:
1761 // http://bugs.python.org/issue1144263). But if we cache EncodeError, we'll
1762 // return the EncodeError from a previous load of the module, which won't
1763 // match a user's attempt to catch EncodeError. So we have to look it up
1764 // again every time.
1765 ScopedPyObjectPtr message_module(PyImport_ImportModule(
1766 "google.protobuf.message"));
1767 if (message_module.get() == NULL) {
1768 return NULL;
1769 }
1770
1771 ScopedPyObjectPtr encode_error(
Josh Haberman00700b72015-10-06 14:13:09 -07001772 PyObject_GetAttrString(message_module.get(), "EncodeError"));
Josh Haberman0b70a432015-02-25 20:17:32 -08001773 if (encode_error.get() == NULL) {
1774 return NULL;
1775 }
1776 PyErr_Format(encode_error.get(),
1777 "Message %s is missing required fields: %s",
Josh Haberman00700b72015-10-06 14:13:09 -07001778 GetMessageName(self).c_str(), PyString_AsString(joined.get()));
jieluo@google.combde4a322014-08-12 21:10:30 +00001779 return NULL;
1780 }
1781 int size = self->message->ByteSize();
1782 if (size <= 0) {
1783 return PyBytes_FromString("");
1784 }
1785 PyObject* result = PyBytes_FromStringAndSize(NULL, size);
1786 if (result == NULL) {
1787 return NULL;
1788 }
1789 char* buffer = PyBytes_AS_STRING(result);
1790 self->message->SerializeWithCachedSizesToArray(
1791 reinterpret_cast<uint8*>(buffer));
1792 return result;
1793}
1794
1795static PyObject* SerializePartialToString(CMessage* self) {
1796 string contents;
1797 self->message->SerializePartialToString(&contents);
1798 return PyBytes_FromStringAndSize(contents.c_str(), contents.size());
1799}
1800
1801// Formats proto fields for ascii dumps using python formatting functions where
1802// appropriate.
Jisi Liuada65562015-02-25 16:39:11 -08001803class PythonFieldValuePrinter : public TextFormat::FieldValuePrinter {
jieluo@google.combde4a322014-08-12 21:10:30 +00001804 public:
jieluo@google.combde4a322014-08-12 21:10:30 +00001805 // Python has some differences from C++ when printing floating point numbers.
1806 //
1807 // 1) Trailing .0 is always printed.
Feng Xiaoeee38b02015-08-22 18:25:48 -07001808 // 2) (Python2) Output is rounded to 12 digits.
1809 // 3) (Python3) The full precision of the double is preserved (and Python uses
1810 // David M. Gay's dtoa(), when the C++ code uses SimpleDtoa. There are some
1811 // differences, but they rarely happen)
jieluo@google.combde4a322014-08-12 21:10:30 +00001812 //
1813 // We override floating point printing with the C-API function for printing
1814 // Python floats to ensure consistency.
1815 string PrintFloat(float value) const { return PrintDouble(value); }
1816 string PrintDouble(double value) const {
Josh Habermanfc80fad2015-08-28 16:34:48 -07001817 // This implementation is not highly optimized (it allocates two temporary
1818 // Python objects) but it is simple and portable. If this is shown to be a
1819 // performance bottleneck, we can optimize it, but the results will likely
1820 // be more complicated to accommodate the differing behavior of double
1821 // formatting between Python 2 and Python 3.
1822 //
1823 // (Though a valid question is: do we really want to make out output
1824 // dependent on the Python version?)
1825 ScopedPyObjectPtr py_value(PyFloat_FromDouble(value));
1826 if (!py_value.get()) {
Feng Xiaoeee38b02015-08-22 18:25:48 -07001827 return string();
1828 }
Josh Habermanfc80fad2015-08-28 16:34:48 -07001829
1830 ScopedPyObjectPtr py_str(PyObject_Str(py_value.get()));
1831 if (!py_str.get()) {
1832 return string();
1833 }
1834
1835 return string(PyString_AsString(py_str.get()));
jieluo@google.combde4a322014-08-12 21:10:30 +00001836 }
jieluo@google.combde4a322014-08-12 21:10:30 +00001837};
1838
1839static PyObject* ToStr(CMessage* self) {
Jisi Liuada65562015-02-25 16:39:11 -08001840 TextFormat::Printer printer;
jieluo@google.combde4a322014-08-12 21:10:30 +00001841 // Passes ownership
1842 printer.SetDefaultFieldValuePrinter(new PythonFieldValuePrinter());
1843 printer.SetHideUnknownFields(true);
1844 string output;
1845 if (!printer.PrintToString(*self->message, &output)) {
1846 PyErr_SetString(PyExc_ValueError, "Unable to convert message to str");
1847 return NULL;
1848 }
1849 return PyString_FromString(output.c_str());
1850}
1851
1852PyObject* MergeFrom(CMessage* self, PyObject* arg) {
1853 CMessage* other_message;
1854 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
1855 PyErr_SetString(PyExc_TypeError, "Must be a message");
1856 return NULL;
1857 }
1858
1859 other_message = reinterpret_cast<CMessage*>(arg);
1860 if (other_message->message->GetDescriptor() !=
1861 self->message->GetDescriptor()) {
1862 PyErr_Format(PyExc_TypeError,
1863 "Tried to merge from a message with a different type. "
1864 "to: %s, from: %s",
1865 self->message->GetDescriptor()->full_name().c_str(),
1866 other_message->message->GetDescriptor()->full_name().c_str());
1867 return NULL;
1868 }
1869 AssureWritable(self);
1870
1871 // TODO(tibell): Message::MergeFrom might turn some child Messages
1872 // into mutable messages, invalidating the message field in the
1873 // corresponding CMessages. We should run a FixupMessageReferences
1874 // pass here.
1875
1876 self->message->MergeFrom(*other_message->message);
1877 Py_RETURN_NONE;
1878}
1879
1880static PyObject* CopyFrom(CMessage* self, PyObject* arg) {
1881 CMessage* other_message;
1882 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
1883 PyErr_SetString(PyExc_TypeError, "Must be a message");
1884 return NULL;
1885 }
1886
1887 other_message = reinterpret_cast<CMessage*>(arg);
1888
1889 if (self == other_message) {
1890 Py_RETURN_NONE;
1891 }
1892
1893 if (other_message->message->GetDescriptor() !=
1894 self->message->GetDescriptor()) {
1895 PyErr_Format(PyExc_TypeError,
1896 "Tried to copy from a message with a different type. "
1897 "to: %s, from: %s",
1898 self->message->GetDescriptor()->full_name().c_str(),
1899 other_message->message->GetDescriptor()->full_name().c_str());
1900 return NULL;
1901 }
1902
1903 AssureWritable(self);
1904
1905 // CopyFrom on the message will not clean up self->composite_fields,
1906 // which can leave us in an inconsistent state, so clear it out here.
Feng Xiaoeee38b02015-08-22 18:25:48 -07001907 (void)ScopedPyObjectPtr(Clear(self));
jieluo@google.combde4a322014-08-12 21:10:30 +00001908
1909 self->message->CopyFrom(*other_message->message);
1910
1911 Py_RETURN_NONE;
1912}
1913
1914static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
1915 const void* data;
1916 Py_ssize_t data_length;
1917 if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) {
1918 return NULL;
1919 }
1920
1921 AssureWritable(self);
Jisi Liuada65562015-02-25 16:39:11 -08001922 io::CodedInputStream input(
jieluo@google.combde4a322014-08-12 21:10:30 +00001923 reinterpret_cast<const uint8*>(data), data_length);
Manjunath Kudlur99a3e302016-02-16 15:17:10 -08001924#if PROTOBUF_PYTHON_ALLOW_OVERSIZE_PROTOS
1925 // Protobuf has a 64MB limit built in, this code will override this. Please do
1926 // not enable this unless you fully understand the implications: protobufs
1927 // must all be kept in memory at the same time, so if they grow too big you
1928 // may get OOM errors. The protobuf APIs do not provide any tools for
1929 // processing protobufs in chunks. If you have protos this big you should
1930 // break them up if it is at all convenient to do so.
1931 input.SetTotalBytesLimit(INT_MAX, INT_MAX);
1932#endif // PROTOBUF_PYTHON_ALLOW_OVERSIZE_PROTOS
Jisi Liu46e8ff62015-10-05 11:59:43 -07001933 PyDescriptorPool* pool = GetDescriptorPoolForMessage(self);
1934 input.SetExtensionRegistry(pool->pool, pool->message_factory);
jieluo@google.combde4a322014-08-12 21:10:30 +00001935 bool success = self->message->MergePartialFromCodedStream(&input);
1936 if (success) {
1937 return PyInt_FromLong(input.CurrentPosition());
1938 } else {
1939 PyErr_Format(DecodeError_class, "Error parsing message");
1940 return NULL;
1941 }
1942}
1943
1944static PyObject* ParseFromString(CMessage* self, PyObject* arg) {
Feng Xiaoeee38b02015-08-22 18:25:48 -07001945 if (ScopedPyObjectPtr(Clear(self)) == NULL) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001946 return NULL;
1947 }
1948 return MergeFromString(self, arg);
1949}
1950
1951static PyObject* ByteSize(CMessage* self, PyObject* args) {
1952 return PyLong_FromLong(self->message->ByteSize());
1953}
1954
1955static PyObject* RegisterExtension(PyObject* cls,
1956 PyObject* extension_handle) {
Jisi Liuada65562015-02-25 16:39:11 -08001957 const FieldDescriptor* descriptor =
1958 GetExtensionDescriptor(extension_handle);
1959 if (descriptor == NULL) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001960 return NULL;
1961 }
Jisi Liuada65562015-02-25 16:39:11 -08001962
jieluo@google.combde4a322014-08-12 21:10:30 +00001963 ScopedPyObjectPtr extensions_by_name(
1964 PyObject_GetAttr(cls, k_extensions_by_name));
1965 if (extensions_by_name == NULL) {
1966 PyErr_SetString(PyExc_TypeError, "no extensions_by_name on class");
1967 return NULL;
1968 }
1969 ScopedPyObjectPtr full_name(PyObject_GetAttr(extension_handle, kfull_name));
1970 if (full_name == NULL) {
1971 return NULL;
1972 }
Jisi Liuada65562015-02-25 16:39:11 -08001973
1974 // If the extension was already registered, check that it is the same.
Josh Haberman00700b72015-10-06 14:13:09 -07001975 PyObject* existing_extension =
1976 PyDict_GetItem(extensions_by_name.get(), full_name.get());
Jisi Liuada65562015-02-25 16:39:11 -08001977 if (existing_extension != NULL) {
1978 const FieldDescriptor* existing_extension_descriptor =
1979 GetExtensionDescriptor(existing_extension);
1980 if (existing_extension_descriptor != descriptor) {
1981 PyErr_SetString(PyExc_ValueError, "Double registration of Extensions");
1982 return NULL;
1983 }
1984 // Nothing else to do.
1985 Py_RETURN_NONE;
1986 }
1987
Josh Haberman00700b72015-10-06 14:13:09 -07001988 if (PyDict_SetItem(extensions_by_name.get(), full_name.get(),
1989 extension_handle) < 0) {
jieluo@google.combde4a322014-08-12 21:10:30 +00001990 return NULL;
1991 }
1992
1993 // Also store a mapping from extension number to implementing class.
1994 ScopedPyObjectPtr extensions_by_number(
1995 PyObject_GetAttr(cls, k_extensions_by_number));
1996 if (extensions_by_number == NULL) {
1997 PyErr_SetString(PyExc_TypeError, "no extensions_by_number on class");
1998 return NULL;
1999 }
2000 ScopedPyObjectPtr number(PyObject_GetAttrString(extension_handle, "number"));
2001 if (number == NULL) {
2002 return NULL;
2003 }
Josh Haberman00700b72015-10-06 14:13:09 -07002004 if (PyDict_SetItem(extensions_by_number.get(), number.get(),
2005 extension_handle) < 0) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002006 return NULL;
2007 }
2008
jieluo@google.combde4a322014-08-12 21:10:30 +00002009 // Check if it's a message set
2010 if (descriptor->is_extension() &&
2011 descriptor->containing_type()->options().message_set_wire_format() &&
Jisi Liuada65562015-02-25 16:39:11 -08002012 descriptor->type() == FieldDescriptor::TYPE_MESSAGE &&
Jisi Liuada65562015-02-25 16:39:11 -08002013 descriptor->label() == FieldDescriptor::LABEL_OPTIONAL) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002014 ScopedPyObjectPtr message_name(PyString_FromStringAndSize(
2015 descriptor->message_type()->full_name().c_str(),
2016 descriptor->message_type()->full_name().size()));
2017 if (message_name == NULL) {
2018 return NULL;
2019 }
Josh Haberman00700b72015-10-06 14:13:09 -07002020 PyDict_SetItem(extensions_by_name.get(), message_name.get(),
2021 extension_handle);
jieluo@google.combde4a322014-08-12 21:10:30 +00002022 }
2023
2024 Py_RETURN_NONE;
2025}
2026
2027static PyObject* SetInParent(CMessage* self, PyObject* args) {
2028 AssureWritable(self);
2029 Py_RETURN_NONE;
2030}
2031
2032static PyObject* WhichOneof(CMessage* self, PyObject* arg) {
Jisi Liuada65562015-02-25 16:39:11 -08002033 Py_ssize_t name_size;
2034 char *name_data;
2035 if (PyString_AsStringAndSize(arg, &name_data, &name_size) < 0)
jieluo@google.combde4a322014-08-12 21:10:30 +00002036 return NULL;
Jisi Liuada65562015-02-25 16:39:11 -08002037 string oneof_name = string(name_data, name_size);
2038 const OneofDescriptor* oneof_desc =
jieluo@google.combde4a322014-08-12 21:10:30 +00002039 self->message->GetDescriptor()->FindOneofByName(oneof_name);
2040 if (oneof_desc == NULL) {
2041 PyErr_Format(PyExc_ValueError,
Jisi Liuada65562015-02-25 16:39:11 -08002042 "Protocol message has no oneof \"%s\" field.",
2043 oneof_name.c_str());
jieluo@google.combde4a322014-08-12 21:10:30 +00002044 return NULL;
2045 }
Jisi Liuada65562015-02-25 16:39:11 -08002046 const FieldDescriptor* field_in_oneof =
jieluo@google.combde4a322014-08-12 21:10:30 +00002047 self->message->GetReflection()->GetOneofFieldDescriptor(
2048 *self->message, oneof_desc);
2049 if (field_in_oneof == NULL) {
2050 Py_RETURN_NONE;
2051 } else {
Jisi Liuada65562015-02-25 16:39:11 -08002052 const string& name = field_in_oneof->name();
2053 return PyString_FromStringAndSize(name.c_str(), name.size());
jieluo@google.combde4a322014-08-12 21:10:30 +00002054 }
2055}
2056
Feng Xiaoe841bac2015-12-11 17:09:20 -08002057static PyObject* GetExtensionDict(CMessage* self, void *closure);
2058
jieluo@google.combde4a322014-08-12 21:10:30 +00002059static PyObject* ListFields(CMessage* self) {
Jisi Liuada65562015-02-25 16:39:11 -08002060 vector<const FieldDescriptor*> fields;
jieluo@google.combde4a322014-08-12 21:10:30 +00002061 self->message->GetReflection()->ListFields(*self->message, &fields);
2062
jieluo@google.combde4a322014-08-12 21:10:30 +00002063 // Normally, the list will be exactly the size of the fields.
Jisi Liuada65562015-02-25 16:39:11 -08002064 ScopedPyObjectPtr all_fields(PyList_New(fields.size()));
jieluo@google.combde4a322014-08-12 21:10:30 +00002065 if (all_fields == NULL) {
2066 return NULL;
2067 }
2068
2069 // When there are unknown extensions, the py list will *not* contain
2070 // the field information. Thus the actual size of the py list will be
2071 // smaller than the size of fields. Set the actual size at the end.
2072 Py_ssize_t actual_size = 0;
Josh Haberman00700b72015-10-06 14:13:09 -07002073 for (size_t i = 0; i < fields.size(); ++i) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002074 ScopedPyObjectPtr t(PyTuple_New(2));
2075 if (t == NULL) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002076 return NULL;
2077 }
2078
2079 if (fields[i]->is_extension()) {
Bo Yang5db21732015-05-21 14:28:59 -07002080 ScopedPyObjectPtr extension_field(
2081 PyFieldDescriptor_FromDescriptor(fields[i]));
jieluo@google.combde4a322014-08-12 21:10:30 +00002082 if (extension_field == NULL) {
Jisi Liuada65562015-02-25 16:39:11 -08002083 return NULL;
2084 }
2085 // With C++ descriptors, the field can always be retrieved, but for
2086 // unknown extensions which have not been imported in Python code, there
2087 // is no message class and we cannot retrieve the value.
2088 // TODO(amauryfa): consider building the class on the fly!
2089 if (fields[i]->message_type() != NULL &&
2090 cdescriptor_pool::GetMessageClass(
Jisi Liu46e8ff62015-10-05 11:59:43 -07002091 GetDescriptorPoolForMessage(self),
2092 fields[i]->message_type()) == NULL) {
Jisi Liuada65562015-02-25 16:39:11 -08002093 PyErr_Clear();
jieluo@google.combde4a322014-08-12 21:10:30 +00002094 continue;
2095 }
Feng Xiaoe841bac2015-12-11 17:09:20 -08002096 ScopedPyObjectPtr extensions(GetExtensionDict(self, NULL));
jieluo@google.combde4a322014-08-12 21:10:30 +00002097 if (extensions == NULL) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002098 return NULL;
2099 }
2100 // 'extension' reference later stolen by PyTuple_SET_ITEM.
Feng Xiaoe841bac2015-12-11 17:09:20 -08002101 PyObject* extension = PyObject_GetItem(
2102 extensions.get(), extension_field.get());
jieluo@google.combde4a322014-08-12 21:10:30 +00002103 if (extension == NULL) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002104 return NULL;
2105 }
Jisi Liuada65562015-02-25 16:39:11 -08002106 PyTuple_SET_ITEM(t.get(), 0, extension_field.release());
jieluo@google.combde4a322014-08-12 21:10:30 +00002107 // Steals reference to 'extension'
2108 PyTuple_SET_ITEM(t.get(), 1, extension);
2109 } else {
Feng Xiaoeee38b02015-08-22 18:25:48 -07002110 // Normal field
jieluo@google.combde4a322014-08-12 21:10:30 +00002111 const string& field_name = fields[i]->name();
2112 ScopedPyObjectPtr py_field_name(PyString_FromStringAndSize(
2113 field_name.c_str(), field_name.length()));
2114 if (py_field_name == NULL) {
2115 PyErr_SetString(PyExc_ValueError, "bad string");
jieluo@google.combde4a322014-08-12 21:10:30 +00002116 return NULL;
2117 }
Bo Yang5db21732015-05-21 14:28:59 -07002118 ScopedPyObjectPtr field_descriptor(
2119 PyFieldDescriptor_FromDescriptor(fields[i]));
jieluo@google.combde4a322014-08-12 21:10:30 +00002120 if (field_descriptor == NULL) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002121 return NULL;
2122 }
2123
Josh Haberman00700b72015-10-06 14:13:09 -07002124 PyObject* field_value = GetAttr(self, py_field_name.get());
jieluo@google.combde4a322014-08-12 21:10:30 +00002125 if (field_value == NULL) {
Josh Haberman00700b72015-10-06 14:13:09 -07002126 PyErr_SetObject(PyExc_ValueError, py_field_name.get());
jieluo@google.combde4a322014-08-12 21:10:30 +00002127 return NULL;
2128 }
Jisi Liuada65562015-02-25 16:39:11 -08002129 PyTuple_SET_ITEM(t.get(), 0, field_descriptor.release());
jieluo@google.combde4a322014-08-12 21:10:30 +00002130 PyTuple_SET_ITEM(t.get(), 1, field_value);
2131 }
Jisi Liuada65562015-02-25 16:39:11 -08002132 PyList_SET_ITEM(all_fields.get(), actual_size, t.release());
jieluo@google.combde4a322014-08-12 21:10:30 +00002133 ++actual_size;
2134 }
Jisi Liuada65562015-02-25 16:39:11 -08002135 Py_SIZE(all_fields.get()) = actual_size;
2136 return all_fields.release();
jieluo@google.combde4a322014-08-12 21:10:30 +00002137}
2138
2139PyObject* FindInitializationErrors(CMessage* self) {
Jisi Liuada65562015-02-25 16:39:11 -08002140 Message* message = self->message;
jieluo@google.combde4a322014-08-12 21:10:30 +00002141 vector<string> errors;
2142 message->FindInitializationErrors(&errors);
2143
2144 PyObject* error_list = PyList_New(errors.size());
2145 if (error_list == NULL) {
2146 return NULL;
2147 }
Josh Haberman00700b72015-10-06 14:13:09 -07002148 for (size_t i = 0; i < errors.size(); ++i) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002149 const string& error = errors[i];
2150 PyObject* error_string = PyString_FromStringAndSize(
2151 error.c_str(), error.length());
2152 if (error_string == NULL) {
2153 Py_DECREF(error_list);
2154 return NULL;
2155 }
2156 PyList_SET_ITEM(error_list, i, error_string);
2157 }
2158 return error_list;
2159}
2160
2161static PyObject* RichCompare(CMessage* self, PyObject* other, int opid) {
Feng Xiaoeee38b02015-08-22 18:25:48 -07002162 // Only equality comparisons are implemented.
2163 if (opid != Py_EQ && opid != Py_NE) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002164 Py_INCREF(Py_NotImplemented);
2165 return Py_NotImplemented;
2166 }
Feng Xiaoeee38b02015-08-22 18:25:48 -07002167 bool equals = true;
2168 // If other is not a message, it cannot be equal.
2169 if (!PyObject_TypeCheck(other, &CMessage_Type)) {
2170 equals = false;
2171 }
2172 const google::protobuf::Message* other_message =
2173 reinterpret_cast<CMessage*>(other)->message;
2174 // If messages don't have the same descriptors, they are not equal.
2175 if (equals &&
2176 self->message->GetDescriptor() != other_message->GetDescriptor()) {
2177 equals = false;
2178 }
2179 // Check the message contents.
2180 if (equals && !google::protobuf::util::MessageDifferencer::Equals(
2181 *self->message,
2182 *reinterpret_cast<CMessage*>(other)->message)) {
2183 equals = false;
2184 }
2185 if (equals ^ (opid == Py_EQ)) {
2186 Py_RETURN_FALSE;
2187 } else {
2188 Py_RETURN_TRUE;
2189 }
jieluo@google.combde4a322014-08-12 21:10:30 +00002190}
2191
Bo Yang5db21732015-05-21 14:28:59 -07002192PyObject* InternalGetScalar(const Message* message,
2193 const FieldDescriptor* field_descriptor) {
Jisi Liuada65562015-02-25 16:39:11 -08002194 const Reflection* reflection = message->GetReflection();
jieluo@google.combde4a322014-08-12 21:10:30 +00002195
Feng Xiao6ef984a2014-11-10 17:34:54 -08002196 if (!CheckFieldBelongsToMessage(field_descriptor, message)) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002197 return NULL;
2198 }
2199
2200 PyObject* result = NULL;
2201 switch (field_descriptor->cpp_type()) {
Jisi Liuada65562015-02-25 16:39:11 -08002202 case FieldDescriptor::CPPTYPE_INT32: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002203 int32 value = reflection->GetInt32(*message, field_descriptor);
2204 result = PyInt_FromLong(value);
2205 break;
2206 }
Jisi Liuada65562015-02-25 16:39:11 -08002207 case FieldDescriptor::CPPTYPE_INT64: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002208 int64 value = reflection->GetInt64(*message, field_descriptor);
2209 result = PyLong_FromLongLong(value);
2210 break;
2211 }
Jisi Liuada65562015-02-25 16:39:11 -08002212 case FieldDescriptor::CPPTYPE_UINT32: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002213 uint32 value = reflection->GetUInt32(*message, field_descriptor);
2214 result = PyInt_FromSize_t(value);
2215 break;
2216 }
Jisi Liuada65562015-02-25 16:39:11 -08002217 case FieldDescriptor::CPPTYPE_UINT64: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002218 uint64 value = reflection->GetUInt64(*message, field_descriptor);
2219 result = PyLong_FromUnsignedLongLong(value);
2220 break;
2221 }
Jisi Liuada65562015-02-25 16:39:11 -08002222 case FieldDescriptor::CPPTYPE_FLOAT: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002223 float value = reflection->GetFloat(*message, field_descriptor);
2224 result = PyFloat_FromDouble(value);
2225 break;
2226 }
Jisi Liuada65562015-02-25 16:39:11 -08002227 case FieldDescriptor::CPPTYPE_DOUBLE: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002228 double value = reflection->GetDouble(*message, field_descriptor);
2229 result = PyFloat_FromDouble(value);
2230 break;
2231 }
Jisi Liuada65562015-02-25 16:39:11 -08002232 case FieldDescriptor::CPPTYPE_BOOL: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002233 bool value = reflection->GetBool(*message, field_descriptor);
2234 result = PyBool_FromLong(value);
2235 break;
2236 }
Jisi Liuada65562015-02-25 16:39:11 -08002237 case FieldDescriptor::CPPTYPE_STRING: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002238 string value = reflection->GetString(*message, field_descriptor);
2239 result = ToStringObject(field_descriptor, value);
2240 break;
2241 }
Jisi Liuada65562015-02-25 16:39:11 -08002242 case FieldDescriptor::CPPTYPE_ENUM: {
2243 if (!message->GetReflection()->SupportsUnknownEnumValues() &&
2244 !message->GetReflection()->HasField(*message, field_descriptor)) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002245 // Look for the value in the unknown fields.
Bo Yang5db21732015-05-21 14:28:59 -07002246 const UnknownFieldSet& unknown_field_set =
2247 message->GetReflection()->GetUnknownFields(*message);
2248 for (int i = 0; i < unknown_field_set.field_count(); ++i) {
2249 if (unknown_field_set.field(i).number() ==
Jisi Liu46e8ff62015-10-05 11:59:43 -07002250 field_descriptor->number() &&
2251 unknown_field_set.field(i).type() ==
2252 google::protobuf::UnknownField::TYPE_VARINT) {
Bo Yang5db21732015-05-21 14:28:59 -07002253 result = PyInt_FromLong(unknown_field_set.field(i).varint());
jieluo@google.combde4a322014-08-12 21:10:30 +00002254 break;
2255 }
2256 }
2257 }
2258
2259 if (result == NULL) {
Jisi Liuada65562015-02-25 16:39:11 -08002260 const EnumValueDescriptor* enum_value =
jieluo@google.combde4a322014-08-12 21:10:30 +00002261 message->GetReflection()->GetEnum(*message, field_descriptor);
2262 result = PyInt_FromLong(enum_value->number());
2263 }
2264 break;
2265 }
2266 default:
2267 PyErr_Format(
2268 PyExc_SystemError, "Getting a value from a field of unknown type %d",
2269 field_descriptor->cpp_type());
2270 }
2271
2272 return result;
2273}
2274
Feng Xiao6ef984a2014-11-10 17:34:54 -08002275PyObject* InternalGetSubMessage(
Jisi Liuada65562015-02-25 16:39:11 -08002276 CMessage* self, const FieldDescriptor* field_descriptor) {
2277 const Reflection* reflection = self->message->GetReflection();
Jisi Liu46e8ff62015-10-05 11:59:43 -07002278 PyDescriptorPool* pool = GetDescriptorPoolForMessage(self);
Jisi Liuada65562015-02-25 16:39:11 -08002279 const Message& sub_message = reflection->GetMessage(
Jisi Liu46e8ff62015-10-05 11:59:43 -07002280 *self->message, field_descriptor, pool->message_factory);
Feng Xiao6ef984a2014-11-10 17:34:54 -08002281
2282 PyObject *message_class = cdescriptor_pool::GetMessageClass(
Jisi Liu46e8ff62015-10-05 11:59:43 -07002283 pool, field_descriptor->message_type());
Feng Xiao6ef984a2014-11-10 17:34:54 -08002284 if (message_class == NULL) {
2285 return NULL;
2286 }
2287
2288 CMessage* cmsg = cmessage::NewEmptyMessage(message_class,
2289 sub_message.GetDescriptor());
2290 if (cmsg == NULL) {
2291 return NULL;
2292 }
2293
jieluo@google.combde4a322014-08-12 21:10:30 +00002294 cmsg->owner = self->owner;
2295 cmsg->parent = self;
Feng Xiao6ef984a2014-11-10 17:34:54 -08002296 cmsg->parent_field_descriptor = field_descriptor;
jieluo@google.combde4a322014-08-12 21:10:30 +00002297 cmsg->read_only = !reflection->HasField(*self->message, field_descriptor);
Jisi Liuada65562015-02-25 16:39:11 -08002298 cmsg->message = const_cast<Message*>(&sub_message);
jieluo@google.combde4a322014-08-12 21:10:30 +00002299
Feng Xiao6ef984a2014-11-10 17:34:54 -08002300 return reinterpret_cast<PyObject*>(cmsg);
jieluo@google.combde4a322014-08-12 21:10:30 +00002301}
2302
Bo Yang5db21732015-05-21 14:28:59 -07002303int InternalSetNonOneofScalar(
2304 Message* message,
Jisi Liuada65562015-02-25 16:39:11 -08002305 const FieldDescriptor* field_descriptor,
jieluo@google.combde4a322014-08-12 21:10:30 +00002306 PyObject* arg) {
Jisi Liuada65562015-02-25 16:39:11 -08002307 const Reflection* reflection = message->GetReflection();
jieluo@google.combde4a322014-08-12 21:10:30 +00002308
Feng Xiao6ef984a2014-11-10 17:34:54 -08002309 if (!CheckFieldBelongsToMessage(field_descriptor, message)) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002310 return -1;
2311 }
2312
jieluo@google.combde4a322014-08-12 21:10:30 +00002313 switch (field_descriptor->cpp_type()) {
Jisi Liuada65562015-02-25 16:39:11 -08002314 case FieldDescriptor::CPPTYPE_INT32: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002315 GOOGLE_CHECK_GET_INT32(arg, value, -1);
2316 reflection->SetInt32(message, field_descriptor, value);
2317 break;
2318 }
Jisi Liuada65562015-02-25 16:39:11 -08002319 case FieldDescriptor::CPPTYPE_INT64: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002320 GOOGLE_CHECK_GET_INT64(arg, value, -1);
2321 reflection->SetInt64(message, field_descriptor, value);
2322 break;
2323 }
Jisi Liuada65562015-02-25 16:39:11 -08002324 case FieldDescriptor::CPPTYPE_UINT32: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002325 GOOGLE_CHECK_GET_UINT32(arg, value, -1);
2326 reflection->SetUInt32(message, field_descriptor, value);
2327 break;
2328 }
Jisi Liuada65562015-02-25 16:39:11 -08002329 case FieldDescriptor::CPPTYPE_UINT64: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002330 GOOGLE_CHECK_GET_UINT64(arg, value, -1);
2331 reflection->SetUInt64(message, field_descriptor, value);
2332 break;
2333 }
Jisi Liuada65562015-02-25 16:39:11 -08002334 case FieldDescriptor::CPPTYPE_FLOAT: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002335 GOOGLE_CHECK_GET_FLOAT(arg, value, -1);
2336 reflection->SetFloat(message, field_descriptor, value);
2337 break;
2338 }
Jisi Liuada65562015-02-25 16:39:11 -08002339 case FieldDescriptor::CPPTYPE_DOUBLE: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002340 GOOGLE_CHECK_GET_DOUBLE(arg, value, -1);
2341 reflection->SetDouble(message, field_descriptor, value);
2342 break;
2343 }
Jisi Liuada65562015-02-25 16:39:11 -08002344 case FieldDescriptor::CPPTYPE_BOOL: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002345 GOOGLE_CHECK_GET_BOOL(arg, value, -1);
2346 reflection->SetBool(message, field_descriptor, value);
2347 break;
2348 }
Jisi Liuada65562015-02-25 16:39:11 -08002349 case FieldDescriptor::CPPTYPE_STRING: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002350 if (!CheckAndSetString(
2351 arg, message, field_descriptor, reflection, false, -1)) {
2352 return -1;
2353 }
2354 break;
2355 }
Jisi Liuada65562015-02-25 16:39:11 -08002356 case FieldDescriptor::CPPTYPE_ENUM: {
jieluo@google.combde4a322014-08-12 21:10:30 +00002357 GOOGLE_CHECK_GET_INT32(arg, value, -1);
Jisi Liuada65562015-02-25 16:39:11 -08002358 if (reflection->SupportsUnknownEnumValues()) {
2359 reflection->SetEnumValue(message, field_descriptor, value);
jieluo@google.combde4a322014-08-12 21:10:30 +00002360 } else {
Jisi Liuada65562015-02-25 16:39:11 -08002361 const EnumDescriptor* enum_descriptor = field_descriptor->enum_type();
2362 const EnumValueDescriptor* enum_value =
2363 enum_descriptor->FindValueByNumber(value);
2364 if (enum_value != NULL) {
2365 reflection->SetEnum(message, field_descriptor, enum_value);
2366 } else {
2367 PyErr_Format(PyExc_ValueError, "Unknown enum value: %d", value);
2368 return -1;
2369 }
jieluo@google.combde4a322014-08-12 21:10:30 +00002370 }
2371 break;
2372 }
2373 default:
2374 PyErr_Format(
2375 PyExc_SystemError, "Setting value to a field of unknown type %d",
2376 field_descriptor->cpp_type());
2377 return -1;
2378 }
2379
2380 return 0;
2381}
2382
Bo Yang5db21732015-05-21 14:28:59 -07002383int InternalSetScalar(
2384 CMessage* self,
2385 const FieldDescriptor* field_descriptor,
2386 PyObject* arg) {
2387 if (!CheckFieldBelongsToMessage(field_descriptor, self->message)) {
2388 return -1;
2389 }
2390
2391 if (MaybeReleaseOverlappingOneofField(self, field_descriptor) < 0) {
2392 return -1;
2393 }
2394
2395 return InternalSetNonOneofScalar(self->message, field_descriptor, arg);
2396}
2397
jieluo@google.combde4a322014-08-12 21:10:30 +00002398PyObject* FromString(PyTypeObject* cls, PyObject* serialized) {
2399 PyObject* py_cmsg = PyObject_CallObject(
2400 reinterpret_cast<PyObject*>(cls), NULL);
2401 if (py_cmsg == NULL) {
2402 return NULL;
2403 }
2404 CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
2405
2406 ScopedPyObjectPtr py_length(MergeFromString(cmsg, serialized));
2407 if (py_length == NULL) {
2408 Py_DECREF(py_cmsg);
2409 return NULL;
2410 }
2411
jieluo@google.combde4a322014-08-12 21:10:30 +00002412 return py_cmsg;
2413}
2414
jieluo@google.combde4a322014-08-12 21:10:30 +00002415PyObject* DeepCopy(CMessage* self, PyObject* arg) {
2416 PyObject* clone = PyObject_CallObject(
2417 reinterpret_cast<PyObject*>(Py_TYPE(self)), NULL);
2418 if (clone == NULL) {
2419 return NULL;
2420 }
2421 if (!PyObject_TypeCheck(clone, &CMessage_Type)) {
2422 Py_DECREF(clone);
2423 return NULL;
2424 }
Feng Xiaoeee38b02015-08-22 18:25:48 -07002425 if (ScopedPyObjectPtr(MergeFrom(
2426 reinterpret_cast<CMessage*>(clone),
2427 reinterpret_cast<PyObject*>(self))) == NULL) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002428 Py_DECREF(clone);
2429 return NULL;
2430 }
2431 return clone;
2432}
2433
2434PyObject* ToUnicode(CMessage* self) {
2435 // Lazy import to prevent circular dependencies
2436 ScopedPyObjectPtr text_format(
2437 PyImport_ImportModule("google.protobuf.text_format"));
2438 if (text_format == NULL) {
2439 return NULL;
2440 }
2441 ScopedPyObjectPtr method_name(PyString_FromString("MessageToString"));
2442 if (method_name == NULL) {
2443 return NULL;
2444 }
2445 Py_INCREF(Py_True);
Josh Haberman00700b72015-10-06 14:13:09 -07002446 ScopedPyObjectPtr encoded(PyObject_CallMethodObjArgs(
2447 text_format.get(), method_name.get(), self, Py_True, NULL));
jieluo@google.combde4a322014-08-12 21:10:30 +00002448 Py_DECREF(Py_True);
2449 if (encoded == NULL) {
2450 return NULL;
2451 }
2452#if PY_MAJOR_VERSION < 3
Josh Haberman00700b72015-10-06 14:13:09 -07002453 PyObject* decoded = PyString_AsDecodedObject(encoded.get(), "utf-8", NULL);
jieluo@google.combde4a322014-08-12 21:10:30 +00002454#else
Josh Haberman00700b72015-10-06 14:13:09 -07002455 PyObject* decoded = PyUnicode_FromEncodedObject(encoded.get(), "utf-8", NULL);
jieluo@google.combde4a322014-08-12 21:10:30 +00002456#endif
2457 if (decoded == NULL) {
2458 return NULL;
2459 }
2460 return decoded;
2461}
2462
2463PyObject* Reduce(CMessage* self) {
2464 ScopedPyObjectPtr constructor(reinterpret_cast<PyObject*>(Py_TYPE(self)));
2465 constructor.inc();
2466 ScopedPyObjectPtr args(PyTuple_New(0));
2467 if (args == NULL) {
2468 return NULL;
2469 }
2470 ScopedPyObjectPtr state(PyDict_New());
2471 if (state == NULL) {
2472 return NULL;
2473 }
2474 ScopedPyObjectPtr serialized(SerializePartialToString(self));
2475 if (serialized == NULL) {
2476 return NULL;
2477 }
Josh Haberman00700b72015-10-06 14:13:09 -07002478 if (PyDict_SetItemString(state.get(), "serialized", serialized.get()) < 0) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002479 return NULL;
2480 }
2481 return Py_BuildValue("OOO", constructor.get(), args.get(), state.get());
2482}
2483
2484PyObject* SetState(CMessage* self, PyObject* state) {
2485 if (!PyDict_Check(state)) {
2486 PyErr_SetString(PyExc_TypeError, "state not a dict");
2487 return NULL;
2488 }
2489 PyObject* serialized = PyDict_GetItemString(state, "serialized");
2490 if (serialized == NULL) {
2491 return NULL;
2492 }
Feng Xiaoeee38b02015-08-22 18:25:48 -07002493 if (ScopedPyObjectPtr(ParseFromString(self, serialized)) == NULL) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002494 return NULL;
2495 }
2496 Py_RETURN_NONE;
2497}
2498
2499// CMessage static methods:
Jisi Liuada65562015-02-25 16:39:11 -08002500PyObject* _CheckCalledFromGeneratedFile(PyObject* unused,
2501 PyObject* unused_arg) {
2502 if (!_CalledFromGeneratedFile(1)) {
2503 PyErr_SetString(PyExc_TypeError,
2504 "Descriptors should not be created directly, "
2505 "but only retrieved from their parent.");
2506 return NULL;
2507 }
2508 Py_RETURN_NONE;
jieluo@google.combde4a322014-08-12 21:10:30 +00002509}
2510
Feng Xiaoe841bac2015-12-11 17:09:20 -08002511static PyObject* GetExtensionDict(CMessage* self, void *closure) {
2512 if (self->extensions) {
2513 Py_INCREF(self->extensions);
2514 return reinterpret_cast<PyObject*>(self->extensions);
2515 }
2516
2517 // If there are extension_ranges, the message is "extendable". Allocate a
2518 // dictionary to store the extension fields.
2519 const Descriptor* descriptor = GetMessageDescriptor(Py_TYPE(self));
2520 if (descriptor->extension_range_count() > 0) {
2521 ExtensionDict* extension_dict = extension_dict::NewExtensionDict(self);
2522 if (extension_dict == NULL) {
2523 return NULL;
2524 }
2525 self->extensions = extension_dict;
2526 Py_INCREF(self->extensions);
2527 return reinterpret_cast<PyObject*>(self->extensions);
2528 }
2529
2530 PyErr_SetNone(PyExc_AttributeError);
2531 return NULL;
2532}
2533
2534static PyGetSetDef Getters[] = {
2535 {"Extensions", (getter)GetExtensionDict, NULL, "Extension dict"},
jieluo@google.combde4a322014-08-12 21:10:30 +00002536 {NULL}
2537};
2538
2539static PyMethodDef Methods[] = {
2540 { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
2541 "Makes a deep copy of the class." },
2542 { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
2543 "Outputs picklable representation of the message." },
2544 { "__setstate__", (PyCFunction)SetState, METH_O,
2545 "Inputs picklable representation of the message." },
2546 { "__unicode__", (PyCFunction)ToUnicode, METH_NOARGS,
2547 "Outputs a unicode representation of the message." },
jieluo@google.combde4a322014-08-12 21:10:30 +00002548 { "ByteSize", (PyCFunction)ByteSize, METH_NOARGS,
2549 "Returns the size of the message in bytes." },
2550 { "Clear", (PyCFunction)Clear, METH_NOARGS,
2551 "Clears the message." },
2552 { "ClearExtension", (PyCFunction)ClearExtension, METH_O,
2553 "Clears a message field." },
2554 { "ClearField", (PyCFunction)ClearField, METH_O,
2555 "Clears a message field." },
2556 { "CopyFrom", (PyCFunction)CopyFrom, METH_O,
2557 "Copies a protocol message into the current message." },
2558 { "FindInitializationErrors", (PyCFunction)FindInitializationErrors,
2559 METH_NOARGS,
2560 "Finds unset required fields." },
2561 { "FromString", (PyCFunction)FromString, METH_O | METH_CLASS,
2562 "Creates new method instance from given serialized data." },
2563 { "HasExtension", (PyCFunction)HasExtension, METH_O,
2564 "Checks if a message field is set." },
2565 { "HasField", (PyCFunction)HasField, METH_O,
2566 "Checks if a message field is set." },
2567 { "IsInitialized", (PyCFunction)IsInitialized, METH_VARARGS,
2568 "Checks if all required fields of a protocol message are set." },
2569 { "ListFields", (PyCFunction)ListFields, METH_NOARGS,
2570 "Lists all set fields of a message." },
2571 { "MergeFrom", (PyCFunction)MergeFrom, METH_O,
2572 "Merges a protocol message into the current message." },
2573 { "MergeFromString", (PyCFunction)MergeFromString, METH_O,
2574 "Merges a serialized message into the current message." },
2575 { "ParseFromString", (PyCFunction)ParseFromString, METH_O,
2576 "Parses a serialized message into the current message." },
2577 { "RegisterExtension", (PyCFunction)RegisterExtension, METH_O | METH_CLASS,
2578 "Registers an extension with the current message." },
2579 { "SerializePartialToString", (PyCFunction)SerializePartialToString,
2580 METH_NOARGS,
2581 "Serializes the message to a string, even if it isn't initialized." },
2582 { "SerializeToString", (PyCFunction)SerializeToString, METH_NOARGS,
2583 "Serializes the message to a string, only for initialized messages." },
2584 { "SetInParent", (PyCFunction)SetInParent, METH_NOARGS,
2585 "Sets the has bit of the given field in its parent message." },
2586 { "WhichOneof", (PyCFunction)WhichOneof, METH_O,
2587 "Returns the name of the field set inside a oneof, "
2588 "or None if no field is set." },
2589
2590 // Static Methods.
Jisi Liuada65562015-02-25 16:39:11 -08002591 { "_CheckCalledFromGeneratedFile", (PyCFunction)_CheckCalledFromGeneratedFile,
2592 METH_NOARGS | METH_STATIC,
2593 "Raises TypeError if the caller is not in a _pb2.py file."},
jieluo@google.combde4a322014-08-12 21:10:30 +00002594 { NULL, NULL}
2595};
2596
Jisi Liuada65562015-02-25 16:39:11 -08002597static bool SetCompositeField(
2598 CMessage* self, PyObject* name, PyObject* value) {
2599 if (self->composite_fields == NULL) {
2600 self->composite_fields = PyDict_New();
2601 if (self->composite_fields == NULL) {
2602 return false;
2603 }
2604 }
2605 return PyDict_SetItem(self->composite_fields, name, value) == 0;
2606}
2607
jieluo@google.combde4a322014-08-12 21:10:30 +00002608PyObject* GetAttr(CMessage* self, PyObject* name) {
Jisi Liuada65562015-02-25 16:39:11 -08002609 PyObject* value = self->composite_fields ?
2610 PyDict_GetItem(self->composite_fields, name) : NULL;
jieluo@google.combde4a322014-08-12 21:10:30 +00002611 if (value != NULL) {
2612 Py_INCREF(value);
2613 return value;
2614 }
2615
Jisi Liuada65562015-02-25 16:39:11 -08002616 const FieldDescriptor* field_descriptor = GetFieldDescriptor(self, name);
2617 if (field_descriptor == NULL) {
2618 return CMessage_Type.tp_base->tp_getattro(
2619 reinterpret_cast<PyObject*>(self), name);
jieluo@google.combde4a322014-08-12 21:10:30 +00002620 }
2621
Bo Yang5db21732015-05-21 14:28:59 -07002622 if (field_descriptor->is_map()) {
2623 PyObject* py_container = NULL;
2624 const Descriptor* entry_type = field_descriptor->message_type();
2625 const FieldDescriptor* value_type = entry_type->FindFieldByName("value");
2626 if (value_type->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2627 PyObject* value_class = cdescriptor_pool::GetMessageClass(
Jisi Liu46e8ff62015-10-05 11:59:43 -07002628 GetDescriptorPoolForMessage(self), value_type->message_type());
Bo Yang5db21732015-05-21 14:28:59 -07002629 if (value_class == NULL) {
2630 return NULL;
2631 }
Feng Xiaoe841bac2015-12-11 17:09:20 -08002632 py_container =
2633 NewMessageMapContainer(self, field_descriptor, value_class);
Bo Yang5db21732015-05-21 14:28:59 -07002634 } else {
Feng Xiaoe841bac2015-12-11 17:09:20 -08002635 py_container = NewScalarMapContainer(self, field_descriptor);
Bo Yang5db21732015-05-21 14:28:59 -07002636 }
2637 if (py_container == NULL) {
2638 return NULL;
2639 }
2640 if (!SetCompositeField(self, name, py_container)) {
2641 Py_DECREF(py_container);
2642 return NULL;
2643 }
2644 return py_container;
2645 }
2646
Jisi Liuada65562015-02-25 16:39:11 -08002647 if (field_descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
2648 PyObject* py_container = NULL;
2649 if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2650 PyObject *message_class = cdescriptor_pool::GetMessageClass(
Jisi Liu46e8ff62015-10-05 11:59:43 -07002651 GetDescriptorPoolForMessage(self), field_descriptor->message_type());
Jisi Liuada65562015-02-25 16:39:11 -08002652 if (message_class == NULL) {
2653 return NULL;
2654 }
2655 py_container = repeated_composite_container::NewContainer(
2656 self, field_descriptor, message_class);
2657 } else {
2658 py_container = repeated_scalar_container::NewContainer(
2659 self, field_descriptor);
2660 }
2661 if (py_container == NULL) {
2662 return NULL;
2663 }
2664 if (!SetCompositeField(self, name, py_container)) {
2665 Py_DECREF(py_container);
2666 return NULL;
2667 }
2668 return py_container;
2669 }
2670
2671 if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2672 PyObject* sub_message = InternalGetSubMessage(self, field_descriptor);
Feng Xiaoeee38b02015-08-22 18:25:48 -07002673 if (sub_message == NULL) {
2674 return NULL;
2675 }
Jisi Liuada65562015-02-25 16:39:11 -08002676 if (!SetCompositeField(self, name, sub_message)) {
2677 Py_DECREF(sub_message);
2678 return NULL;
2679 }
2680 return sub_message;
2681 }
2682
Bo Yang5db21732015-05-21 14:28:59 -07002683 return InternalGetScalar(self->message, field_descriptor);
jieluo@google.combde4a322014-08-12 21:10:30 +00002684}
2685
2686int SetAttr(CMessage* self, PyObject* name, PyObject* value) {
Jisi Liuada65562015-02-25 16:39:11 -08002687 if (self->composite_fields && PyDict_Contains(self->composite_fields, name)) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002688 PyErr_SetString(PyExc_TypeError, "Can't set composite field");
2689 return -1;
2690 }
2691
Jisi Liuada65562015-02-25 16:39:11 -08002692 const FieldDescriptor* field_descriptor = GetFieldDescriptor(self, name);
Feng Xiao6ef984a2014-11-10 17:34:54 -08002693 if (field_descriptor != NULL) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002694 AssureWritable(self);
Jisi Liuada65562015-02-25 16:39:11 -08002695 if (field_descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002696 PyErr_Format(PyExc_AttributeError, "Assignment not allowed to repeated "
2697 "field \"%s\" in protocol message object.",
2698 field_descriptor->name().c_str());
2699 return -1;
2700 } else {
Jisi Liuada65562015-02-25 16:39:11 -08002701 if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002702 PyErr_Format(PyExc_AttributeError, "Assignment not allowed to "
2703 "field \"%s\" in protocol message object.",
2704 field_descriptor->name().c_str());
2705 return -1;
2706 } else {
2707 return InternalSetScalar(self, field_descriptor, value);
2708 }
2709 }
2710 }
2711
Feng Xiaoe841bac2015-12-11 17:09:20 -08002712 PyErr_Format(PyExc_AttributeError,
2713 "Assignment not allowed "
2714 "(no field \"%s\"in protocol message object).",
2715 PyString_AsString(name));
jieluo@google.combde4a322014-08-12 21:10:30 +00002716 return -1;
2717}
2718
2719} // namespace cmessage
2720
2721PyTypeObject CMessage_Type = {
Feng Xiaoeee38b02015-08-22 18:25:48 -07002722 PyVarObject_HEAD_INIT(&PyMessageMeta_Type, 0)
Bo Yang5db21732015-05-21 14:28:59 -07002723 FULL_MODULE_NAME ".CMessage", // tp_name
jieluo@google.combde4a322014-08-12 21:10:30 +00002724 sizeof(CMessage), // tp_basicsize
2725 0, // tp_itemsize
2726 (destructor)cmessage::Dealloc, // tp_dealloc
2727 0, // tp_print
2728 0, // tp_getattr
2729 0, // tp_setattr
2730 0, // tp_compare
2731 0, // tp_repr
2732 0, // tp_as_number
2733 0, // tp_as_sequence
2734 0, // tp_as_mapping
Feng Xiaoeee38b02015-08-22 18:25:48 -07002735 PyObject_HashNotImplemented, // tp_hash
jieluo@google.combde4a322014-08-12 21:10:30 +00002736 0, // tp_call
2737 (reprfunc)cmessage::ToStr, // tp_str
2738 (getattrofunc)cmessage::GetAttr, // tp_getattro
2739 (setattrofunc)cmessage::SetAttr, // tp_setattro
2740 0, // tp_as_buffer
2741 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags
2742 "A ProtocolMessage", // tp_doc
2743 0, // tp_traverse
2744 0, // tp_clear
2745 (richcmpfunc)cmessage::RichCompare, // tp_richcompare
2746 0, // tp_weaklistoffset
2747 0, // tp_iter
2748 0, // tp_iternext
2749 cmessage::Methods, // tp_methods
Feng Xiaoe841bac2015-12-11 17:09:20 -08002750 0, // tp_members
2751 cmessage::Getters, // tp_getset
jieluo@google.combde4a322014-08-12 21:10:30 +00002752 0, // tp_base
2753 0, // tp_dict
2754 0, // tp_descr_get
2755 0, // tp_descr_set
2756 0, // tp_dictoffset
2757 (initproc)cmessage::Init, // tp_init
2758 0, // tp_alloc
2759 cmessage::New, // tp_new
2760};
2761
2762// --- Exposing the C proto living inside Python proto to C code:
2763
2764const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg);
2765Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg);
2766
Jisi Liuada65562015-02-25 16:39:11 -08002767static const Message* GetCProtoInsidePyProtoImpl(PyObject* msg) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002768 if (!PyObject_TypeCheck(msg, &CMessage_Type)) {
2769 return NULL;
2770 }
2771 CMessage* cmsg = reinterpret_cast<CMessage*>(msg);
2772 return cmsg->message;
2773}
2774
Jisi Liuada65562015-02-25 16:39:11 -08002775static Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002776 if (!PyObject_TypeCheck(msg, &CMessage_Type)) {
2777 return NULL;
2778 }
2779 CMessage* cmsg = reinterpret_cast<CMessage*>(msg);
Jisi Liuada65562015-02-25 16:39:11 -08002780 if ((cmsg->composite_fields && PyDict_Size(cmsg->composite_fields) != 0) ||
jieluo@google.combde4a322014-08-12 21:10:30 +00002781 (cmsg->extensions != NULL &&
2782 PyDict_Size(cmsg->extensions->values) != 0)) {
2783 // There is currently no way of accurately syncing arbitrary changes to
2784 // the underlying C++ message back to the CMessage (e.g. removed repeated
2785 // composite containers). We only allow direct mutation of the underlying
2786 // C++ message if there is no child data in the CMessage.
2787 return NULL;
2788 }
2789 cmessage::AssureWritable(cmsg);
2790 return cmsg->message;
2791}
2792
2793static const char module_docstring[] =
2794"python-proto2 is a module that can be used to enhance proto2 Python API\n"
2795"performance.\n"
2796"\n"
2797"It provides access to the protocol buffers C++ reflection API that\n"
2798"implements the basic protocol buffer functions.";
2799
2800void InitGlobals() {
2801 // TODO(gps): Check all return values in this function for NULL and propagate
2802 // the error (MemoryError) on up to result in an import failure. These should
2803 // also be freed and reset to NULL during finalization.
2804 kPythonZero = PyInt_FromLong(0);
2805 kint32min_py = PyInt_FromLong(kint32min);
2806 kint32max_py = PyInt_FromLong(kint32max);
2807 kuint32max_py = PyLong_FromLongLong(kuint32max);
2808 kint64min_py = PyLong_FromLongLong(kint64min);
2809 kint64max_py = PyLong_FromLongLong(kint64max);
2810 kuint64max_py = PyLong_FromUnsignedLongLong(kuint64max);
2811
2812 kDESCRIPTOR = PyString_FromString("DESCRIPTOR");
Feng Xiao6ef984a2014-11-10 17:34:54 -08002813 k_cdescriptor = PyString_FromString("_cdescriptor");
jieluo@google.combde4a322014-08-12 21:10:30 +00002814 kfull_name = PyString_FromString("full_name");
jieluo@google.combde4a322014-08-12 21:10:30 +00002815 k_extensions_by_name = PyString_FromString("_extensions_by_name");
2816 k_extensions_by_number = PyString_FromString("_extensions_by_number");
jieluo@google.combde4a322014-08-12 21:10:30 +00002817
Feng Xiaoeee38b02015-08-22 18:25:48 -07002818 PyObject *dummy_obj = PySet_New(NULL);
2819 kEmptyWeakref = PyWeakref_NewRef(dummy_obj, NULL);
2820 Py_DECREF(dummy_obj);
jieluo@google.combde4a322014-08-12 21:10:30 +00002821}
2822
2823bool InitProto2MessageModule(PyObject *m) {
Jisi Liuada65562015-02-25 16:39:11 -08002824 // Initialize types and globals in descriptor.cc
2825 if (!InitDescriptor()) {
2826 return false;
2827 }
2828
2829 // Initialize types and globals in descriptor_pool.cc
2830 if (!InitDescriptorPool()) {
2831 return false;
2832 }
2833
2834 // Initialize constants defined in this file.
jieluo@google.combde4a322014-08-12 21:10:30 +00002835 InitGlobals();
2836
Feng Xiaoeee38b02015-08-22 18:25:48 -07002837 PyMessageMeta_Type.tp_base = &PyType_Type;
2838 if (PyType_Ready(&PyMessageMeta_Type) < 0) {
2839 return false;
2840 }
2841 PyModule_AddObject(m, "MessageMeta",
2842 reinterpret_cast<PyObject*>(&PyMessageMeta_Type));
2843
Jisi Liuada65562015-02-25 16:39:11 -08002844 if (PyType_Ready(&CMessage_Type) < 0) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002845 return false;
2846 }
2847
Feng Xiao6ef984a2014-11-10 17:34:54 -08002848 // DESCRIPTOR is set on each protocol buffer message class elsewhere, but set
2849 // it here as well to document that subclasses need to set it.
Jisi Liuada65562015-02-25 16:39:11 -08002850 PyDict_SetItem(CMessage_Type.tp_dict, kDESCRIPTOR, Py_None);
Feng Xiao6ef984a2014-11-10 17:34:54 -08002851 // Subclasses with message extensions will override _extensions_by_name and
2852 // _extensions_by_number with fresh mutable dictionaries in AddDescriptors.
2853 // All other classes can share this same immutable mapping.
2854 ScopedPyObjectPtr empty_dict(PyDict_New());
2855 if (empty_dict == NULL) {
2856 return false;
2857 }
Josh Haberman00700b72015-10-06 14:13:09 -07002858 ScopedPyObjectPtr immutable_dict(PyDictProxy_New(empty_dict.get()));
Feng Xiao6ef984a2014-11-10 17:34:54 -08002859 if (immutable_dict == NULL) {
2860 return false;
2861 }
Jisi Liuada65562015-02-25 16:39:11 -08002862 if (PyDict_SetItem(CMessage_Type.tp_dict,
Josh Haberman00700b72015-10-06 14:13:09 -07002863 k_extensions_by_name, immutable_dict.get()) < 0) {
Feng Xiao6ef984a2014-11-10 17:34:54 -08002864 return false;
2865 }
Jisi Liuada65562015-02-25 16:39:11 -08002866 if (PyDict_SetItem(CMessage_Type.tp_dict,
Josh Haberman00700b72015-10-06 14:13:09 -07002867 k_extensions_by_number, immutable_dict.get()) < 0) {
Feng Xiao6ef984a2014-11-10 17:34:54 -08002868 return false;
2869 }
jieluo@google.combde4a322014-08-12 21:10:30 +00002870
Jisi Liuada65562015-02-25 16:39:11 -08002871 PyModule_AddObject(m, "Message", reinterpret_cast<PyObject*>(&CMessage_Type));
jieluo@google.combde4a322014-08-12 21:10:30 +00002872
Feng Xiaoeee38b02015-08-22 18:25:48 -07002873 // Initialize Repeated container types.
2874 {
2875 if (PyType_Ready(&RepeatedScalarContainer_Type) < 0) {
2876 return false;
2877 }
2878
2879 PyModule_AddObject(m, "RepeatedScalarContainer",
2880 reinterpret_cast<PyObject*>(
2881 &RepeatedScalarContainer_Type));
2882
2883 if (PyType_Ready(&RepeatedCompositeContainer_Type) < 0) {
2884 return false;
2885 }
2886
2887 PyModule_AddObject(
2888 m, "RepeatedCompositeContainer",
2889 reinterpret_cast<PyObject*>(
2890 &RepeatedCompositeContainer_Type));
2891
2892 // Register them as collections.Sequence
2893 ScopedPyObjectPtr collections(PyImport_ImportModule("collections"));
2894 if (collections == NULL) {
2895 return false;
2896 }
Josh Haberman00700b72015-10-06 14:13:09 -07002897 ScopedPyObjectPtr mutable_sequence(
2898 PyObject_GetAttrString(collections.get(), "MutableSequence"));
Feng Xiaoeee38b02015-08-22 18:25:48 -07002899 if (mutable_sequence == NULL) {
2900 return false;
2901 }
Josh Haberman00700b72015-10-06 14:13:09 -07002902 if (ScopedPyObjectPtr(
2903 PyObject_CallMethod(mutable_sequence.get(), "register", "O",
2904 &RepeatedScalarContainer_Type)) == NULL) {
Feng Xiaoeee38b02015-08-22 18:25:48 -07002905 return false;
2906 }
Josh Haberman00700b72015-10-06 14:13:09 -07002907 if (ScopedPyObjectPtr(
2908 PyObject_CallMethod(mutable_sequence.get(), "register", "O",
2909 &RepeatedCompositeContainer_Type)) == NULL) {
Feng Xiaoeee38b02015-08-22 18:25:48 -07002910 return false;
2911 }
jieluo@google.combde4a322014-08-12 21:10:30 +00002912 }
2913
Feng Xiaoeee38b02015-08-22 18:25:48 -07002914 // Initialize Map container types.
2915 {
2916 // ScalarMapContainer_Type derives from our MutableMapping type.
2917 ScopedPyObjectPtr containers(PyImport_ImportModule(
2918 "google.protobuf.internal.containers"));
2919 if (containers == NULL) {
2920 return false;
2921 }
jieluo@google.combde4a322014-08-12 21:10:30 +00002922
Feng Xiaoeee38b02015-08-22 18:25:48 -07002923 ScopedPyObjectPtr mutable_mapping(
Josh Haberman00700b72015-10-06 14:13:09 -07002924 PyObject_GetAttrString(containers.get(), "MutableMapping"));
Feng Xiaoeee38b02015-08-22 18:25:48 -07002925 if (mutable_mapping == NULL) {
2926 return false;
2927 }
2928
Josh Haberman00700b72015-10-06 14:13:09 -07002929 if (!PyObject_TypeCheck(mutable_mapping.get(), &PyType_Type)) {
Feng Xiaoeee38b02015-08-22 18:25:48 -07002930 return false;
2931 }
2932
Josh Haberman00700b72015-10-06 14:13:09 -07002933 Py_INCREF(mutable_mapping.get());
Dan O'Reillyd9598ca2015-08-26 20:30:41 -04002934#if PY_MAJOR_VERSION >= 3
2935 PyObject* bases = PyTuple_New(1);
2936 PyTuple_SET_ITEM(bases, 0, mutable_mapping.get());
2937
2938 ScalarMapContainer_Type =
2939 PyType_FromSpecWithBases(&ScalarMapContainer_Type_spec, bases);
2940 PyModule_AddObject(m, "ScalarMapContainer", ScalarMapContainer_Type);
2941#else
Feng Xiaoeee38b02015-08-22 18:25:48 -07002942 ScalarMapContainer_Type.tp_base =
2943 reinterpret_cast<PyTypeObject*>(mutable_mapping.get());
2944
2945 if (PyType_Ready(&ScalarMapContainer_Type) < 0) {
2946 return false;
2947 }
2948
2949 PyModule_AddObject(m, "ScalarMapContainer",
2950 reinterpret_cast<PyObject*>(&ScalarMapContainer_Type));
Dan O'Reillyd9598ca2015-08-26 20:30:41 -04002951#endif
Feng Xiaoeee38b02015-08-22 18:25:48 -07002952
Feng Xiaoe841bac2015-12-11 17:09:20 -08002953 if (PyType_Ready(&MapIterator_Type) < 0) {
Feng Xiaoeee38b02015-08-22 18:25:48 -07002954 return false;
2955 }
2956
Feng Xiaoe841bac2015-12-11 17:09:20 -08002957 PyModule_AddObject(m, "MapIterator",
2958 reinterpret_cast<PyObject*>(&MapIterator_Type));
Feng Xiaoeee38b02015-08-22 18:25:48 -07002959
Dan O'Reillyd9598ca2015-08-26 20:30:41 -04002960
2961#if PY_MAJOR_VERSION >= 3
2962 MessageMapContainer_Type =
2963 PyType_FromSpecWithBases(&MessageMapContainer_Type_spec, bases);
2964 PyModule_AddObject(m, "MessageMapContainer", MessageMapContainer_Type);
2965#else
Josh Haberman00700b72015-10-06 14:13:09 -07002966 Py_INCREF(mutable_mapping.get());
Feng Xiaoeee38b02015-08-22 18:25:48 -07002967 MessageMapContainer_Type.tp_base =
2968 reinterpret_cast<PyTypeObject*>(mutable_mapping.get());
2969
2970 if (PyType_Ready(&MessageMapContainer_Type) < 0) {
2971 return false;
2972 }
2973
2974 PyModule_AddObject(m, "MessageMapContainer",
2975 reinterpret_cast<PyObject*>(&MessageMapContainer_Type));
Dan O'Reillyd9598ca2015-08-26 20:30:41 -04002976#endif
jieluo@google.combde4a322014-08-12 21:10:30 +00002977 }
2978
Jisi Liuada65562015-02-25 16:39:11 -08002979 if (PyType_Ready(&ExtensionDict_Type) < 0) {
jieluo@google.combde4a322014-08-12 21:10:30 +00002980 return false;
2981 }
jieluo@google.combde4a322014-08-12 21:10:30 +00002982 PyModule_AddObject(
2983 m, "ExtensionDict",
Jisi Liuada65562015-02-25 16:39:11 -08002984 reinterpret_cast<PyObject*>(&ExtensionDict_Type));
jieluo@google.combde4a322014-08-12 21:10:30 +00002985
Bo Yang5db21732015-05-21 14:28:59 -07002986 // Expose the DescriptorPool used to hold all descriptors added from generated
2987 // pb2.py files.
Jisi Liu46e8ff62015-10-05 11:59:43 -07002988 // PyModule_AddObject steals a reference.
2989 Py_INCREF(GetDefaultDescriptorPool());
2990 PyModule_AddObject(m, "default_pool",
2991 reinterpret_cast<PyObject*>(GetDefaultDescriptorPool()));
Bo Yang5db21732015-05-21 14:28:59 -07002992
Feng Xiaoe841bac2015-12-11 17:09:20 -08002993 PyModule_AddObject(m, "DescriptorPool", reinterpret_cast<PyObject*>(
2994 &PyDescriptorPool_Type));
2995
Jisi Liuada65562015-02-25 16:39:11 -08002996 // This implementation provides full Descriptor types, we advertise it so that
2997 // descriptor.py can use them in replacement of the Python classes.
2998 PyModule_AddIntConstant(m, "_USE_C_DESCRIPTORS", 1);
2999
3000 PyModule_AddObject(m, "Descriptor", reinterpret_cast<PyObject*>(
3001 &PyMessageDescriptor_Type));
3002 PyModule_AddObject(m, "FieldDescriptor", reinterpret_cast<PyObject*>(
3003 &PyFieldDescriptor_Type));
3004 PyModule_AddObject(m, "EnumDescriptor", reinterpret_cast<PyObject*>(
3005 &PyEnumDescriptor_Type));
3006 PyModule_AddObject(m, "EnumValueDescriptor", reinterpret_cast<PyObject*>(
3007 &PyEnumValueDescriptor_Type));
3008 PyModule_AddObject(m, "FileDescriptor", reinterpret_cast<PyObject*>(
3009 &PyFileDescriptor_Type));
3010 PyModule_AddObject(m, "OneofDescriptor", reinterpret_cast<PyObject*>(
3011 &PyOneofDescriptor_Type));
jieluo@google.combde4a322014-08-12 21:10:30 +00003012
3013 PyObject* enum_type_wrapper = PyImport_ImportModule(
3014 "google.protobuf.internal.enum_type_wrapper");
3015 if (enum_type_wrapper == NULL) {
3016 return false;
3017 }
Jisi Liuada65562015-02-25 16:39:11 -08003018 EnumTypeWrapper_class =
jieluo@google.combde4a322014-08-12 21:10:30 +00003019 PyObject_GetAttrString(enum_type_wrapper, "EnumTypeWrapper");
3020 Py_DECREF(enum_type_wrapper);
3021
3022 PyObject* message_module = PyImport_ImportModule(
3023 "google.protobuf.message");
3024 if (message_module == NULL) {
3025 return false;
3026 }
Jisi Liuada65562015-02-25 16:39:11 -08003027 EncodeError_class = PyObject_GetAttrString(message_module, "EncodeError");
3028 DecodeError_class = PyObject_GetAttrString(message_module, "DecodeError");
Feng Xiaoeee38b02015-08-22 18:25:48 -07003029 PythonMessage_class = PyObject_GetAttrString(message_module, "Message");
jieluo@google.combde4a322014-08-12 21:10:30 +00003030 Py_DECREF(message_module);
3031
3032 PyObject* pickle_module = PyImport_ImportModule("pickle");
3033 if (pickle_module == NULL) {
3034 return false;
3035 }
Jisi Liuada65562015-02-25 16:39:11 -08003036 PickleError_class = PyObject_GetAttrString(pickle_module, "PickleError");
jieluo@google.combde4a322014-08-12 21:10:30 +00003037 Py_DECREF(pickle_module);
3038
3039 // Override {Get,Mutable}CProtoInsidePyProto.
Jisi Liuada65562015-02-25 16:39:11 -08003040 GetCProtoInsidePyProtoPtr = GetCProtoInsidePyProtoImpl;
3041 MutableCProtoInsidePyProtoPtr = MutableCProtoInsidePyProtoImpl;
jieluo@google.combde4a322014-08-12 21:10:30 +00003042
3043 return true;
3044}
3045
3046} // namespace python
3047} // namespace protobuf
3048
3049
3050#if PY_MAJOR_VERSION >= 3
3051static struct PyModuleDef _module = {
3052 PyModuleDef_HEAD_INIT,
3053 "_message",
3054 google::protobuf::python::module_docstring,
3055 -1,
3056 NULL,
3057 NULL,
3058 NULL,
3059 NULL,
3060 NULL
3061};
3062#define INITFUNC PyInit__message
3063#define INITFUNC_ERRORVAL NULL
3064#else // Python 2
3065#define INITFUNC init_message
3066#define INITFUNC_ERRORVAL
3067#endif
3068
3069extern "C" {
3070 PyMODINIT_FUNC INITFUNC(void) {
3071 PyObject* m;
3072#if PY_MAJOR_VERSION >= 3
3073 m = PyModule_Create(&_module);
3074#else
3075 m = Py_InitModule3("_message", NULL, google::protobuf::python::module_docstring);
3076#endif
3077 if (m == NULL) {
3078 return INITFUNC_ERRORVAL;
3079 }
3080
3081 if (!google::protobuf::python::InitProto2MessageModule(m)) {
3082 Py_DECREF(m);
3083 return INITFUNC_ERRORVAL;
3084 }
3085
3086#if PY_MAJOR_VERSION >= 3
3087 return m;
3088#endif
3089 }
3090}
3091} // namespace google