blob: f2799e62517f277eb5b94f9b0973379a68052cbf [file] [log] [blame]
liujisi@google.com33165fe2010-11-02 13:14:58 +00001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// http://code.google.com/p/protobuf/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// Author: petar@google.com (Petar Petrov)
32
33#include <Python.h>
34#include <map>
35#include <string>
36#include <vector>
37
38#include <google/protobuf/stubs/common.h>
39#include <google/protobuf/pyext/python_descriptor.h>
40#include <google/protobuf/io/coded_stream.h>
41#include <google/protobuf/descriptor.h>
42#include <google/protobuf/dynamic_message.h>
43#include <google/protobuf/message.h>
44#include <google/protobuf/unknown_field_set.h>
45#include <google/protobuf/pyext/python_protobuf.h>
46
47/* Is 64bit */
48#define IS_64BIT (SIZEOF_LONG == 8)
49
50#define FIELD_BELONGS_TO_MESSAGE(field_descriptor, message) \
51 ((message)->GetDescriptor() == (field_descriptor)->containing_type())
52
53#define FIELD_IS_REPEATED(field_descriptor) \
54 ((field_descriptor)->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED)
55
56#define GOOGLE_CHECK_GET_INT32(arg, value) \
57 int32 value; \
58 if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \
59 return NULL; \
60 }
61
62#define GOOGLE_CHECK_GET_INT64(arg, value) \
63 int64 value; \
64 if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \
65 return NULL; \
66 }
67
68#define GOOGLE_CHECK_GET_UINT32(arg, value) \
69 uint32 value; \
70 if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \
71 return NULL; \
72 }
73
74#define GOOGLE_CHECK_GET_UINT64(arg, value) \
75 uint64 value; \
76 if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \
77 return NULL; \
78 }
79
80#define GOOGLE_CHECK_GET_FLOAT(arg, value) \
81 float value; \
82 if (!CheckAndGetFloat(arg, &value)) { \
83 return NULL; \
84 } \
85
86#define GOOGLE_CHECK_GET_DOUBLE(arg, value) \
87 double value; \
88 if (!CheckAndGetDouble(arg, &value)) { \
89 return NULL; \
90 }
91
92#define GOOGLE_CHECK_GET_BOOL(arg, value) \
93 bool value; \
94 if (!CheckAndGetBool(arg, &value)) { \
95 return NULL; \
96 }
97
98#define C(str) const_cast<char*>(str)
99
100// --- Globals:
101
102// Constants used for integer type range checking.
103static PyObject* kPythonZero;
104static PyObject* kint32min_py;
105static PyObject* kint32max_py;
106static PyObject* kuint32max_py;
107static PyObject* kint64min_py;
108static PyObject* kint64max_py;
109static PyObject* kuint64max_py;
110
111namespace google {
112namespace protobuf {
113namespace python {
114
115// --- Support Routines:
116
117static void AddConstants(PyObject* module) {
118 struct NameValue {
119 char* name;
120 int32 value;
121 } constants[] = {
122 // Labels:
123 {"LABEL_OPTIONAL", google::protobuf::FieldDescriptor::LABEL_OPTIONAL},
124 {"LABEL_REQUIRED", google::protobuf::FieldDescriptor::LABEL_REQUIRED},
125 {"LABEL_REPEATED", google::protobuf::FieldDescriptor::LABEL_REPEATED},
126 // CPP types:
127 {"CPPTYPE_MESSAGE", google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE},
128 // Field Types:
129 {"TYPE_MESSAGE", google::protobuf::FieldDescriptor::TYPE_MESSAGE},
130 // End.
131 {NULL, 0}
132 };
133
134 for (NameValue* constant = constants;
135 constant->name != NULL; constant++) {
136 PyModule_AddIntConstant(module, constant->name, constant->value);
137 }
138}
139
140// --- CMessage Custom Type:
141
142// ------ Type Forward Declaration:
143
144struct CMessage;
145struct CMessage_Type;
146
147static void CMessageDealloc(CMessage* self);
148static int CMessageInit(CMessage* self, PyObject *args, PyObject *kwds);
149static PyObject* CMessageStr(CMessage* self);
150
151static PyObject* CMessage_AddMessage(CMessage* self, PyObject* args);
152static PyObject* CMessage_AddRepeatedScalar(CMessage* self, PyObject* args);
153static PyObject* CMessage_AssignRepeatedScalar(CMessage* self, PyObject* args);
154static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args);
155static PyObject* CMessage_Clear(CMessage* self, PyObject* args);
156static PyObject* CMessage_ClearField(CMessage* self, PyObject* args);
157static PyObject* CMessage_ClearFieldByDescriptor(
158 CMessage* self, PyObject* args);
159static PyObject* CMessage_CopyFrom(CMessage* self, PyObject* args);
160static PyObject* CMessage_DebugString(CMessage* self, PyObject* args);
161static PyObject* CMessage_DeleteRepeatedField(CMessage* self, PyObject* args);
162static PyObject* CMessage_Equals(CMessage* self, PyObject* args);
163static PyObject* CMessage_FieldLength(CMessage* self, PyObject* args);
164static PyObject* CMessage_FindInitializationErrors(CMessage* self);
165static PyObject* CMessage_GetRepeatedMessage(CMessage* self, PyObject* args);
166static PyObject* CMessage_GetRepeatedScalar(CMessage* self, PyObject* args);
167static PyObject* CMessage_GetScalar(CMessage* self, PyObject* args);
168static PyObject* CMessage_HasField(CMessage* self, PyObject* args);
169static PyObject* CMessage_HasFieldByDescriptor(CMessage* self, PyObject* args);
170static PyObject* CMessage_IsInitialized(CMessage* self, PyObject* args);
171static PyObject* CMessage_ListFields(CMessage* self, PyObject* args);
172static PyObject* CMessage_MergeFrom(CMessage* self, PyObject* args);
173static PyObject* CMessage_MergeFromString(CMessage* self, PyObject* args);
174static PyObject* CMessage_MutableMessage(CMessage* self, PyObject* args);
175static PyObject* CMessage_NewSubMessage(CMessage* self, PyObject* args);
176static PyObject* CMessage_SetScalar(CMessage* self, PyObject* args);
177static PyObject* CMessage_SerializePartialToString(
178 CMessage* self, PyObject* args);
179static PyObject* CMessage_SerializeToString(CMessage* self, PyObject* args);
180static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args);
181static PyObject* CMessage_SwapRepeatedFieldElements(
182 CMessage* self, PyObject* args);
183
184// ------ Object Definition:
185
186typedef struct CMessage {
187 PyObject_HEAD
188
189 struct CMessage* parent; // NULL if wasn't created from another message.
190 CFieldDescriptor* parent_field;
191 const char* full_name;
192 google::protobuf::Message* message;
193 bool free_message;
194 bool read_only;
195} CMessage;
196
197// ------ Method Table:
198
199#define CMETHOD(name, args, doc) \
200 { C(#name), (PyCFunction)CMessage_##name, args, C(doc) }
201static PyMethodDef CMessageMethods[] = {
202 CMETHOD(AddMessage, METH_O,
203 "Adds a new message to a repeated composite field."),
204 CMETHOD(AddRepeatedScalar, METH_VARARGS,
205 "Adds a scalar to a repeated scalar field."),
206 CMETHOD(AssignRepeatedScalar, METH_VARARGS,
207 "Clears and sets the values of a repeated scalar field."),
208 CMETHOD(ByteSize, METH_NOARGS,
209 "Returns the size of the message in bytes."),
210 CMETHOD(Clear, METH_NOARGS,
211 "Clears a protocol message."),
212 CMETHOD(ClearField, METH_O,
213 "Clears a protocol message field by name."),
214 CMETHOD(ClearFieldByDescriptor, METH_O,
215 "Clears a protocol message field by descriptor."),
216 CMETHOD(CopyFrom, METH_O,
217 "Copies a protocol message into the current message."),
218 CMETHOD(DebugString, METH_NOARGS,
219 "Returns the debug string of a protocol message."),
220 CMETHOD(DeleteRepeatedField, METH_VARARGS,
221 "Deletes a slice of values from a repeated field."),
222 CMETHOD(Equals, METH_O,
223 "Checks if two protocol messages are equal (by identity)."),
224 CMETHOD(FieldLength, METH_O,
225 "Returns the number of elements in a repeated field."),
226 CMETHOD(FindInitializationErrors, METH_NOARGS,
227 "Returns the initialization errors of a message."),
228 CMETHOD(GetRepeatedMessage, METH_VARARGS,
229 "Returns a message from a repeated composite field."),
230 CMETHOD(GetRepeatedScalar, METH_VARARGS,
231 "Returns a scalar value from a repeated scalar field."),
232 CMETHOD(GetScalar, METH_O,
233 "Returns the scalar value of a field."),
234 CMETHOD(HasField, METH_O,
235 "Checks if a message field is set."),
236 CMETHOD(HasFieldByDescriptor, METH_O,
237 "Checks if a message field is set by given its descriptor"),
238 CMETHOD(IsInitialized, METH_NOARGS,
239 "Checks if all required fields of a protocol message are set."),
240 CMETHOD(ListFields, METH_NOARGS,
241 "Lists all set fields of a message."),
242 CMETHOD(MergeFrom, METH_O,
243 "Merges a protocol message into the current message."),
244 CMETHOD(MergeFromString, METH_O,
245 "Merges a serialized message into the current message."),
246 CMETHOD(MutableMessage, METH_O,
247 "Returns a new instance of a nested protocol message."),
248 CMETHOD(NewSubMessage, METH_O,
249 "Creates and returns a python message given the descriptor of a "
250 "composite field of the current message."),
251 CMETHOD(SetScalar, METH_VARARGS,
252 "Sets the value of a singular scalar field."),
253 CMETHOD(SerializePartialToString, METH_VARARGS,
254 "Serializes the message to a string, even if it isn't initialized."),
255 CMETHOD(SerializeToString, METH_NOARGS,
256 "Serializes the message to a string, only for initialized messages."),
257 CMETHOD(SetInParent, METH_NOARGS,
258 "Sets the has bit of the given field in its parent message."),
259 CMETHOD(SwapRepeatedFieldElements, METH_VARARGS,
260 "Swaps the elements in two positions in a repeated field."),
261 { NULL, NULL }
262};
263#undef CMETHOD
264
265static PyMemberDef CMessageMembers[] = {
266 { C("full_name"), T_STRING, offsetof(CMessage, full_name), 0, "Full name" },
267 { NULL }
268};
269
270// ------ Type Definition:
271
272// The definition for the type object that captures the type of CMessage
273// in Python.
274PyTypeObject CMessage_Type = {
275 PyObject_HEAD_INIT(&PyType_Type)
276 0,
277 C("google3.net.google.protobuf.python.internal."
278 "_net_proto2___python."
279 "CMessage"), // tp_name
280 sizeof(CMessage), // tp_basicsize
281 0, // tp_itemsize
282 (destructor)CMessageDealloc, // tp_dealloc
283 0, // tp_print
284 0, // tp_getattr
285 0, // tp_setattr
286 0, // tp_compare
287 0, // tp_repr
288 0, // tp_as_number
289 0, // tp_as_sequence
290 0, // tp_as_mapping
291 0, // tp_hash
292 0, // tp_call
293 (reprfunc)CMessageStr, // tp_str
294 0, // tp_getattro
295 0, // tp_setattro
296 0, // tp_as_buffer
297 Py_TPFLAGS_DEFAULT, // tp_flags
298 C("A ProtocolMessage"), // tp_doc
299 0, // tp_traverse
300 0, // tp_clear
301 0, // tp_richcompare
302 0, // tp_weaklistoffset
303 0, // tp_iter
304 0, // tp_iternext
305 CMessageMethods, // tp_methods
306 CMessageMembers, // tp_members
307 0, // tp_getset
308 0, // tp_base
309 0, // tp_dict
310 0, // tp_descr_get
311 0, // tp_descr_set
312 0, // tp_dictoffset
313 (initproc)CMessageInit, // tp_init
314 PyType_GenericAlloc, // tp_alloc
315 PyType_GenericNew, // tp_new
316 PyObject_Del, // tp_free
317};
318
319// ------ Helper Functions:
320
321static void FormatTypeError(PyObject* arg, char* expected_types) {
322 PyObject* s = PyObject_Str(PyObject_Type(arg));
323 PyObject* repr = PyObject_Repr(PyObject_Type(arg));
324 PyErr_Format(PyExc_TypeError,
325 "%.100s has type %.100s, but expected one of: %s",
326 PyString_AS_STRING(repr),
327 PyString_AS_STRING(s),
328 expected_types);
329 Py_DECREF(s);
330 Py_DECREF(repr);
331}
332
333template <class T>
334static bool CheckAndGetInteger(
335 PyObject* arg, T* value, PyObject* min, PyObject* max) {
336 bool is_long = PyLong_Check(arg);
337 if (!PyInt_Check(arg) && !is_long) {
338 FormatTypeError(arg, "int, long");
339 return false;
340 }
341
342 if (PyObject_Compare(min, arg) > 0 || PyObject_Compare(max, arg) < 0) {
343 PyObject* s = PyObject_Str(arg);
344 PyErr_Format(PyExc_ValueError,
345 "Value out of range: %s",
346 PyString_AS_STRING(s));
347 Py_DECREF(s);
348 return false;
349 }
350 if (is_long) {
351 if (min == kPythonZero) {
352 *value = static_cast<T>(PyLong_AsUnsignedLongLong(arg));
353 } else {
354 *value = static_cast<T>(PyLong_AsLongLong(arg));
355 }
356 } else {
357 *value = static_cast<T>(PyInt_AsLong(arg));
358 }
359 return true;
360}
361
362static bool CheckAndGetDouble(PyObject* arg, double* value) {
363 if (!PyInt_Check(arg) && !PyLong_Check(arg) &&
364 !PyFloat_Check(arg)) {
365 FormatTypeError(arg, "int, long, float");
366 return false;
367 }
368 *value = PyFloat_AsDouble(arg);
369 return true;
370}
371
372static bool CheckAndGetFloat(PyObject* arg, float* value) {
373 double double_value;
374 if (!CheckAndGetDouble(arg, &double_value)) {
375 return false;
376 }
377 *value = static_cast<float>(double_value);
378 return true;
379}
380
381static bool CheckAndGetBool(PyObject* arg, bool* value) {
382 if (!PyInt_Check(arg) && !PyBool_Check(arg) && !PyLong_Check(arg)) {
383 FormatTypeError(arg, "int, long, bool");
384 return false;
385 }
386 *value = static_cast<bool>(PyInt_AsLong(arg));
387 return true;
388}
389
390google::protobuf::DynamicMessageFactory* global_message_factory = NULL;
391static const google::protobuf::Message* CreateMessage(const char* message_type) {
392 string message_name(message_type);
393 const google::protobuf::Descriptor* descriptor =
394 GetDescriptorPool()->FindMessageTypeByName(message_name);
395 if (descriptor == NULL) {
396 return NULL;
397 }
398 return global_message_factory->GetPrototype(descriptor);
399}
400
401static bool CheckAndSetString(
402 PyObject* arg, google::protobuf::Message* message,
403 const google::protobuf::FieldDescriptor* descriptor,
404 const google::protobuf::Reflection* reflection,
405 bool append,
406 int index) {
407 GOOGLE_DCHECK(descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING ||
408 descriptor->type() == google::protobuf::FieldDescriptor::TYPE_BYTES);
409 if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) {
410 if (!PyString_Check(arg) && !PyUnicode_Check(arg)) {
411 FormatTypeError(arg, "str, unicode");
412 return false;
413 }
414
415 if (PyString_Check(arg)) {
416 PyObject* unicode = PyUnicode_FromEncodedObject(arg, "ascii", NULL);
417 if (unicode == NULL) {
418 PyObject* repr = PyObject_Repr(arg);
419 PyErr_Format(PyExc_ValueError,
420 "%s has type str, but isn't in 7-bit ASCII "
421 "encoding. Non-ASCII strings must be converted to "
422 "unicode objects before being added.",
423 PyString_AS_STRING(repr));
424 Py_DECREF(repr);
425 return false;
426 } else {
427 Py_DECREF(unicode);
428 }
429 }
430 } else if (!PyString_Check(arg)) {
431 FormatTypeError(arg, "str");
432 return false;
433 }
434
435 PyObject* encoded_string = NULL;
436 if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) {
437 if (PyString_Check(arg)) {
438 encoded_string = PyString_AsEncodedObject(arg, "utf-8", NULL);
439 } else {
440 encoded_string = PyUnicode_AsEncodedObject(arg, "utf-8", NULL);
441 }
442 } else {
443 // In this case field type is "bytes".
444 encoded_string = arg;
445 Py_INCREF(encoded_string);
446 }
447
448 if (encoded_string == NULL) {
449 return false;
450 }
451
452 char* value;
453 Py_ssize_t value_len;
454 if (PyString_AsStringAndSize(encoded_string, &value, &value_len) < 0) {
455 Py_DECREF(encoded_string);
456 return false;
457 }
458
459 string value_string(value, value_len);
460 if (append) {
461 reflection->AddString(message, descriptor, value_string);
462 } else if (index < 0) {
463 reflection->SetString(message, descriptor, value_string);
464 } else {
465 reflection->SetRepeatedString(message, descriptor, index, value_string);
466 }
467 Py_DECREF(encoded_string);
468 return true;
469}
470
471static PyObject* ToStringObject(
472 const google::protobuf::FieldDescriptor* descriptor, string value) {
473 if (descriptor->type() != google::protobuf::FieldDescriptor::TYPE_STRING) {
474 return PyString_FromStringAndSize(value.c_str(), value.length());
475 }
476
477 PyObject* result = PyUnicode_DecodeUTF8(value.c_str(), value.length(), NULL);
478 // If the string can't be decoded in UTF-8, just return a string object that
479 // contains the raw bytes. This can't happen if the value was assigned using
480 // the members of the Python message object, but can happen if the values were
481 // parsed from the wire (binary).
482 if (result == NULL) {
483 PyErr_Clear();
484 result = PyString_FromStringAndSize(value.c_str(), value.length());
485 }
486 return result;
487}
488
489static void AssureWritable(CMessage* self) {
490 if (self == NULL ||
491 self->parent == NULL ||
492 self->parent_field == NULL) {
493 return;
494 }
495
496 if (!self->read_only) {
497 return;
498 }
499
500 AssureWritable(self->parent);
501
502 google::protobuf::Message* message = self->parent->message;
503 const google::protobuf::Reflection* reflection = message->GetReflection();
504 self->message = reflection->MutableMessage(
505 message, self->parent_field->descriptor, global_message_factory);
506 self->read_only = false;
507 self->parent = NULL;
508 self->parent_field = NULL;
509}
510
511static PyObject* InternalGetScalar(
512 google::protobuf::Message* message,
513 const google::protobuf::FieldDescriptor* field_descriptor) {
514 const google::protobuf::Reflection* reflection = message->GetReflection();
515
516 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
517 PyErr_SetString(
518 PyExc_KeyError, "Field does not belong to message!");
519 return NULL;
520 }
521
522 PyObject* result = NULL;
523 switch (field_descriptor->cpp_type()) {
524 case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
525 int32 value = reflection->GetInt32(*message, field_descriptor);
526 result = PyInt_FromLong(value);
527 break;
528 }
529 case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
530 int64 value = reflection->GetInt64(*message, field_descriptor);
531#if IS_64BIT
532 result = PyInt_FromLong(value);
533#else
534 result = PyLong_FromLongLong(value);
535#endif
536 break;
537 }
538 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
539 uint32 value = reflection->GetUInt32(*message, field_descriptor);
540#if IS_64BIT
541 result = PyInt_FromLong(value);
542#else
543 result = PyLong_FromLongLong(value);
544#endif
545 break;
546 }
547 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
548 uint64 value = reflection->GetUInt64(*message, field_descriptor);
549#if IS_64BIT
550 if (value <= static_cast<uint64>(kint64max)) {
551 result = PyInt_FromLong(static_cast<uint64>(value));
552 }
553#else
554 if (value <= static_cast<uint32>(kint32max)) {
555 result = PyInt_FromLong(static_cast<uint32>(value));
556 }
557#endif
558 else { // NOLINT
559 result = PyLong_FromUnsignedLongLong(value);
560 }
561 break;
562 }
563 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
564 float value = reflection->GetFloat(*message, field_descriptor);
565 result = PyFloat_FromDouble(value);
566 break;
567 }
568 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
569 double value = reflection->GetDouble(*message, field_descriptor);
570 result = PyFloat_FromDouble(value);
571 break;
572 }
573 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
574 bool value = reflection->GetBool(*message, field_descriptor);
575 result = PyBool_FromLong(value);
576 break;
577 }
578 case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
579 string value = reflection->GetString(*message, field_descriptor);
580 result = ToStringObject(field_descriptor, value);
581 break;
582 }
583 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
584 if (!message->GetReflection()->HasField(*message, field_descriptor)) {
585 // Look for the value in the unknown fields.
586 google::protobuf::UnknownFieldSet* unknown_field_set =
587 message->GetReflection()->MutableUnknownFields(message);
588 for (int i = 0; i < unknown_field_set->field_count(); ++i) {
589 if (unknown_field_set->field(i).number() ==
590 field_descriptor->number()) {
591 result = PyInt_FromLong(unknown_field_set->field(i).varint());
592 break;
593 }
594 }
595 }
596
597 if (result == NULL) {
598 const google::protobuf::EnumValueDescriptor* enum_value =
599 message->GetReflection()->GetEnum(*message, field_descriptor);
600 result = PyInt_FromLong(enum_value->number());
601 }
602 break;
603 }
604 default:
605 PyErr_Format(
606 PyExc_SystemError, "Getting a value from a field of unknown type %d",
607 field_descriptor->cpp_type());
608 }
609
610 return result;
611}
612
613static PyObject* InternalSetScalar(
614 google::protobuf::Message* message, const google::protobuf::FieldDescriptor* field_descriptor,
615 PyObject* arg) {
616 const google::protobuf::Reflection* reflection = message->GetReflection();
617
618 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
619 PyErr_SetString(
620 PyExc_KeyError, "Field does not belong to message!");
621 return NULL;
622 }
623
624 switch (field_descriptor->cpp_type()) {
625 case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
626 GOOGLE_CHECK_GET_INT32(arg, value);
627 reflection->SetInt32(message, field_descriptor, value);
628 break;
629 }
630 case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
631 GOOGLE_CHECK_GET_INT64(arg, value);
632 reflection->SetInt64(message, field_descriptor, value);
633 break;
634 }
635 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
636 GOOGLE_CHECK_GET_UINT32(arg, value);
637 reflection->SetUInt32(message, field_descriptor, value);
638 break;
639 }
640 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
641 GOOGLE_CHECK_GET_UINT64(arg, value);
642 reflection->SetUInt64(message, field_descriptor, value);
643 break;
644 }
645 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
646 GOOGLE_CHECK_GET_FLOAT(arg, value);
647 reflection->SetFloat(message, field_descriptor, value);
648 break;
649 }
650 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
651 GOOGLE_CHECK_GET_DOUBLE(arg, value);
652 reflection->SetDouble(message, field_descriptor, value);
653 break;
654 }
655 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
656 GOOGLE_CHECK_GET_BOOL(arg, value);
657 reflection->SetBool(message, field_descriptor, value);
658 break;
659 }
660 case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
661 if (!CheckAndSetString(
662 arg, message, field_descriptor, reflection, false, -1)) {
663 return NULL;
664 }
665 break;
666 }
667 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
668 GOOGLE_CHECK_GET_INT32(arg, value);
669 const google::protobuf::EnumDescriptor* enum_descriptor =
670 field_descriptor->enum_type();
671 const google::protobuf::EnumValueDescriptor* enum_value =
672 enum_descriptor->FindValueByNumber(value);
673 if (enum_value != NULL) {
674 reflection->SetEnum(message, field_descriptor, enum_value);
675 } else {
676 bool added = false;
677 // Add the value to the unknown fields.
678 google::protobuf::UnknownFieldSet* unknown_field_set =
679 message->GetReflection()->MutableUnknownFields(message);
680 for (int i = 0; i < unknown_field_set->field_count(); ++i) {
681 if (unknown_field_set->field(i).number() ==
682 field_descriptor->number()) {
683 unknown_field_set->mutable_field(i)->set_varint(value);
684 added = true;
685 break;
686 }
687 }
688
689 if (!added) {
690 unknown_field_set->AddVarint(field_descriptor->number(), value);
691 }
692 reflection->ClearField(message, field_descriptor);
693 }
694 break;
695 }
696 default:
697 PyErr_Format(
698 PyExc_SystemError, "Setting value to a field of unknown type %d",
699 field_descriptor->cpp_type());
700 }
701
702 Py_RETURN_NONE;
703}
704
705static PyObject* InternalAddRepeatedScalar(
706 google::protobuf::Message* message, const google::protobuf::FieldDescriptor* field_descriptor,
707 PyObject* arg) {
708
709 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
710 PyErr_SetString(
711 PyExc_KeyError, "Field does not belong to message!");
712 return NULL;
713 }
714
715 const google::protobuf::Reflection* reflection = message->GetReflection();
716 switch (field_descriptor->cpp_type()) {
717 case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
718 GOOGLE_CHECK_GET_INT32(arg, value);
719 reflection->AddInt32(message, field_descriptor, value);
720 break;
721 }
722 case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
723 GOOGLE_CHECK_GET_INT64(arg, value);
724 reflection->AddInt64(message, field_descriptor, value);
725 break;
726 }
727 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
728 GOOGLE_CHECK_GET_UINT32(arg, value);
729 reflection->AddUInt32(message, field_descriptor, value);
730 break;
731 }
732 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
733 GOOGLE_CHECK_GET_UINT64(arg, value);
734 reflection->AddUInt64(message, field_descriptor, value);
735 break;
736 }
737 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
738 GOOGLE_CHECK_GET_FLOAT(arg, value);
739 reflection->AddFloat(message, field_descriptor, value);
740 break;
741 }
742 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
743 GOOGLE_CHECK_GET_DOUBLE(arg, value);
744 reflection->AddDouble(message, field_descriptor, value);
745 break;
746 }
747 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
748 GOOGLE_CHECK_GET_BOOL(arg, value);
749 reflection->AddBool(message, field_descriptor, value);
750 break;
751 }
752 case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
753 if (!CheckAndSetString(
754 arg, message, field_descriptor, reflection, true, -1)) {
755 return NULL;
756 }
757 break;
758 }
759 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
760 GOOGLE_CHECK_GET_INT32(arg, value);
761 const google::protobuf::EnumDescriptor* enum_descriptor =
762 field_descriptor->enum_type();
763 const google::protobuf::EnumValueDescriptor* enum_value =
764 enum_descriptor->FindValueByNumber(value);
765 if (enum_value != NULL) {
766 reflection->AddEnum(message, field_descriptor, enum_value);
767 } else {
768 PyObject* s = PyObject_Str(arg);
769 PyErr_Format(PyExc_ValueError, "Unknown enum value: %s",
770 PyString_AS_STRING(s));
771 Py_DECREF(s);
772 return NULL;
773 }
774 break;
775 }
776 default:
777 PyErr_Format(
778 PyExc_SystemError, "Adding value to a field of unknown type %d",
779 field_descriptor->cpp_type());
780 }
781
782 Py_RETURN_NONE;
783}
784
785static PyObject* InternalGetRepeatedScalar(
786 CMessage* cmessage, const google::protobuf::FieldDescriptor* field_descriptor,
787 int index) {
788 google::protobuf::Message* message = cmessage->message;
789 const google::protobuf::Reflection* reflection = message->GetReflection();
790
791 int field_size = reflection->FieldSize(*message, field_descriptor);
792 if (index < 0) {
793 index = field_size + index;
794 }
795 if (index < 0 || index >= field_size) {
796 PyErr_Format(PyExc_IndexError,
797 "list assignment index (%d) out of range", index);
798 return NULL;
799 }
800
801 PyObject* result = NULL;
802 switch (field_descriptor->cpp_type()) {
803 case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
804 int32 value = reflection->GetRepeatedInt32(
805 *message, field_descriptor, index);
806 result = PyInt_FromLong(value);
807 break;
808 }
809 case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
810 int64 value = reflection->GetRepeatedInt64(
811 *message, field_descriptor, index);
812 result = PyLong_FromLongLong(value);
813 break;
814 }
815 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
816 uint32 value = reflection->GetRepeatedUInt32(
817 *message, field_descriptor, index);
818 result = PyLong_FromLongLong(value);
819 break;
820 }
821 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
822 uint64 value = reflection->GetRepeatedUInt64(
823 *message, field_descriptor, index);
824 result = PyLong_FromUnsignedLongLong(value);
825 break;
826 }
827 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
828 float value = reflection->GetRepeatedFloat(
829 *message, field_descriptor, index);
830 result = PyFloat_FromDouble(value);
831 break;
832 }
833 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
834 double value = reflection->GetRepeatedDouble(
835 *message, field_descriptor, index);
836 result = PyFloat_FromDouble(value);
837 break;
838 }
839 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
840 bool value = reflection->GetRepeatedBool(
841 *message, field_descriptor, index);
842 result = PyBool_FromLong(value ? 1 : 0);
843 break;
844 }
845 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
846 const google::protobuf::EnumValueDescriptor* enum_value =
847 message->GetReflection()->GetRepeatedEnum(
848 *message, field_descriptor, index);
849 result = PyInt_FromLong(enum_value->number());
850 break;
851 }
852 case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
853 string value = reflection->GetRepeatedString(
854 *message, field_descriptor, index);
855 result = ToStringObject(field_descriptor, value);
856 break;
857 }
858 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
859 CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type);
860 if (py_cmsg == NULL) {
861 return NULL;
862 }
863 const google::protobuf::Message& msg = reflection->GetRepeatedMessage(
864 *message, field_descriptor, index);
865 py_cmsg->parent = cmessage;
866 py_cmsg->full_name = field_descriptor->full_name().c_str();
867 py_cmsg->message = const_cast<google::protobuf::Message*>(&msg);
868 py_cmsg->free_message = false;
869 py_cmsg->read_only = false;
870 result = reinterpret_cast<PyObject*>(py_cmsg);
871 break;
872 }
873 default:
874 PyErr_Format(
875 PyExc_SystemError,
876 "Getting value from a repeated field of unknown type %d",
877 field_descriptor->cpp_type());
878 }
879
880 return result;
881}
882
883static PyObject* InternalGetRepeatedScalarSlice(
884 CMessage* cmessage, const google::protobuf::FieldDescriptor* field_descriptor,
885 PyObject* slice) {
886 Py_ssize_t from;
887 Py_ssize_t to;
888 Py_ssize_t step;
889 Py_ssize_t length;
890 bool return_list = false;
891 google::protobuf::Message* message = cmessage->message;
892
893 if (PyInt_Check(slice)) {
894 from = to = PyInt_AsLong(slice);
895 } else if (PyLong_Check(slice)) {
896 from = to = PyLong_AsLong(slice);
897 } else if (PySlice_Check(slice)) {
898 const google::protobuf::Reflection* reflection = message->GetReflection();
899 length = reflection->FieldSize(*message, field_descriptor);
900 PySlice_GetIndices(
901 reinterpret_cast<PySliceObject*>(slice), length, &from, &to, &step);
902 return_list = true;
903 } else {
904 PyErr_SetString(PyExc_TypeError, "list indices must be integers");
905 return NULL;
906 }
907
908 if (!return_list) {
909 return InternalGetRepeatedScalar(cmessage, field_descriptor, from);
910 }
911
912 PyObject* list = PyList_New(0);
913 if (list == NULL) {
914 return NULL;
915 }
916
917 if (from <= to) {
918 if (step < 0) return list;
919 for (Py_ssize_t index = from; index < to; index += step) {
920 if (index < 0 || index >= length) break;
921 PyObject* s = InternalGetRepeatedScalar(
922 cmessage, field_descriptor, index);
923 PyList_Append(list, s);
924 Py_DECREF(s);
925 }
926 } else {
927 if (step > 0) return list;
928 for (Py_ssize_t index = from; index > to; index += step) {
929 if (index < 0 || index >= length) break;
930 PyObject* s = InternalGetRepeatedScalar(
931 cmessage, field_descriptor, index);
932 PyList_Append(list, s);
933 Py_DECREF(s);
934 }
935 }
936 return list;
937}
938
939// ------ C Constructor/Destructor:
940
941static int CMessageInit(CMessage* self, PyObject *args, PyObject *kwds) {
942 self->message = NULL;
943 return 0;
944}
945
946static void CMessageDealloc(CMessage* self) {
947 if (self->free_message) {
948 if (self->read_only) {
949 PyErr_WriteUnraisable(reinterpret_cast<PyObject*>(self));
950 }
951 delete self->message;
952 }
953 self->ob_type->tp_free(reinterpret_cast<PyObject*>(self));
954}
955
956// ------ Methods:
957
958static PyObject* CMessage_Clear(CMessage* self, PyObject* args) {
959 AssureWritable(self);
960 self->message->Clear();
961 Py_RETURN_NONE;
962}
963
964static PyObject* CMessage_IsInitialized(CMessage* self, PyObject* args) {
965 return PyBool_FromLong(self->message->IsInitialized() ? 1 : 0);
966}
967
968static PyObject* CMessage_HasField(CMessage* self, PyObject* arg) {
969 char* field_name;
970 if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) {
971 return NULL;
972 }
973
974 google::protobuf::Message* message = self->message;
975 const google::protobuf::Descriptor* descriptor = message->GetDescriptor();
976 const google::protobuf::FieldDescriptor* field_descriptor =
977 descriptor->FindFieldByName(field_name);
978 if (field_descriptor == NULL) {
979 PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name);
980 return NULL;
981 }
982
983 bool has_field =
984 message->GetReflection()->HasField(*message, field_descriptor);
985 return PyBool_FromLong(has_field ? 1 : 0);
986}
987
988static PyObject* CMessage_HasFieldByDescriptor(CMessage* self, PyObject* arg) {
989 CFieldDescriptor* cfield_descriptor = NULL;
990 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
991 &CFieldDescriptor_Type)) {
992 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
993 return NULL;
994 }
995 cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
996
997 google::protobuf::Message* message = self->message;
998 const google::protobuf::FieldDescriptor* field_descriptor =
999 cfield_descriptor->descriptor;
1000
1001 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
1002 PyErr_SetString(PyExc_KeyError,
1003 "Field does not belong to message!");
1004 return NULL;
1005 }
1006
1007 if (FIELD_IS_REPEATED(field_descriptor)) {
1008 PyErr_SetString(PyExc_KeyError,
1009 "Field is repeated. A singular method is required.");
1010 return NULL;
1011 }
1012
1013 bool has_field =
1014 message->GetReflection()->HasField(*message, field_descriptor);
1015 return PyBool_FromLong(has_field ? 1 : 0);
1016}
1017
1018static PyObject* CMessage_ClearFieldByDescriptor(
1019 CMessage* self, PyObject* arg) {
1020 CFieldDescriptor* cfield_descriptor = NULL;
1021 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
1022 &CFieldDescriptor_Type)) {
1023 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
1024 return NULL;
1025 }
1026 cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
1027
1028 google::protobuf::Message* message = self->message;
1029 const google::protobuf::FieldDescriptor* field_descriptor =
1030 cfield_descriptor->descriptor;
1031
1032 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
1033 PyErr_SetString(PyExc_KeyError,
1034 "Field does not belong to message!");
1035 return NULL;
1036 }
1037
1038 message->GetReflection()->ClearField(message, field_descriptor);
1039 Py_RETURN_NONE;
1040}
1041
1042static PyObject* CMessage_ClearField(CMessage* self, PyObject* arg) {
1043 char* field_name;
1044 if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) {
1045 return NULL;
1046 }
1047
1048 google::protobuf::Message* message = self->message;
1049 const google::protobuf::Descriptor* descriptor = message->GetDescriptor();
1050 const google::protobuf::FieldDescriptor* field_descriptor =
1051 descriptor->FindFieldByName(field_name);
1052 if (field_descriptor == NULL) {
1053 PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name);
1054 return NULL;
1055 }
1056
1057 message->GetReflection()->ClearField(message, field_descriptor);
1058 Py_RETURN_NONE;
1059}
1060
1061static PyObject* CMessage_GetScalar(CMessage* self, PyObject* arg) {
1062 CFieldDescriptor* cdescriptor = NULL;
1063 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
1064 &CFieldDescriptor_Type)) {
1065 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
1066 return NULL;
1067 }
1068 cdescriptor = reinterpret_cast<CFieldDescriptor*>(arg);
1069
1070 google::protobuf::Message* message = self->message;
1071 return InternalGetScalar(message, cdescriptor->descriptor);
1072}
1073
1074static PyObject* CMessage_GetRepeatedScalar(CMessage* self, PyObject* args) {
1075 CFieldDescriptor* cfield_descriptor;
1076 PyObject* slice;
1077 if (!PyArg_ParseTuple(args, C("O!O:GetRepeatedScalar"),
1078 &CFieldDescriptor_Type, &cfield_descriptor, &slice)) {
1079 return NULL;
1080 }
1081
1082 return InternalGetRepeatedScalarSlice(
1083 self, cfield_descriptor->descriptor, slice);
1084}
1085
1086static PyObject* CMessage_AssignRepeatedScalar(CMessage* self, PyObject* args) {
1087 CFieldDescriptor* cfield_descriptor;
1088 PyObject* slice;
1089 if (!PyArg_ParseTuple(args, C("O!O:AssignRepeatedScalar"),
1090 &CFieldDescriptor_Type, &cfield_descriptor, &slice)) {
1091 return NULL;
1092 }
1093
1094 AssureWritable(self);
1095 google::protobuf::Message* message = self->message;
1096 message->GetReflection()->ClearField(message, cfield_descriptor->descriptor);
1097
1098 PyObject* iter = PyObject_GetIter(slice);
1099 PyObject* next;
1100 while ((next = PyIter_Next(iter)) != NULL) {
1101 if (InternalAddRepeatedScalar(
1102 message, cfield_descriptor->descriptor, next) == NULL) {
1103 Py_DECREF(iter);
1104 return NULL;
1105 }
1106 }
1107 Py_DECREF(iter);
1108 Py_RETURN_NONE;
1109}
1110
1111static PyObject* CMessage_DeleteRepeatedField(CMessage* self, PyObject* args) {
1112 CFieldDescriptor* cfield_descriptor;
1113 PyObject* slice;
1114 if (!PyArg_ParseTuple(args, C("O!O:DeleteRepeatedField"),
1115 &CFieldDescriptor_Type, &cfield_descriptor, &slice)) {
1116 return NULL;
1117 }
1118 AssureWritable(self);
1119
1120 Py_ssize_t length, from, to, step, slice_length;
1121 google::protobuf::Message* message = self->message;
1122 const google::protobuf::FieldDescriptor* field_descriptor =
1123 cfield_descriptor->descriptor;
1124 const google::protobuf::Reflection* reflection = message->GetReflection();
1125 int min, max;
1126 length = reflection->FieldSize(*message, field_descriptor);
1127
1128 if (PyInt_Check(slice) || PyLong_Check(slice)) {
1129 from = to = PyLong_AsLong(slice);
1130 if (from < 0) {
1131 from = to = length + from;
1132 }
1133 step = 1;
1134 min = max = from;
1135
1136 // Range check.
1137 if (from < 0 || from >= length) {
1138 PyErr_Format(PyExc_IndexError, "list assignment index out of range");
1139 return NULL;
1140 }
1141 } else if (PySlice_Check(slice)) {
1142 from = to = step = slice_length = 0;
1143 PySlice_GetIndicesEx(
1144 reinterpret_cast<PySliceObject*>(slice),
1145 length, &from, &to, &step, &slice_length);
1146 if (from < to) {
1147 min = from;
1148 max = to - 1;
1149 } else {
1150 min = to + 1;
1151 max = from;
1152 }
1153 } else {
1154 PyErr_SetString(PyExc_TypeError, "list indices must be integers");
1155 return NULL;
1156 }
1157
1158 Py_ssize_t i = from;
1159 std::vector<bool> to_delete(length, false);
1160 while (i >= min && i <= max) {
1161 to_delete[i] = true;
1162 i += step;
1163 }
1164
1165 to = 0;
1166 for (i = 0; i < length; ++i) {
1167 if (!to_delete[i]) {
1168 if (i != to) {
1169 reflection->SwapElements(message, field_descriptor, i, to);
1170 }
1171 ++to;
1172 }
1173 }
1174
1175 while (i > to) {
1176 reflection->RemoveLast(message, field_descriptor);
1177 --i;
1178 }
1179
1180 Py_RETURN_NONE;
1181}
1182
1183
1184static PyObject* CMessage_SetScalar(CMessage* self, PyObject* args) {
1185 CFieldDescriptor* cfield_descriptor;
1186 PyObject* arg;
1187 if (!PyArg_ParseTuple(args, C("O!O:SetScalar"),
1188 &CFieldDescriptor_Type, &cfield_descriptor, &arg)) {
1189 return NULL;
1190 }
1191 AssureWritable(self);
1192
1193 return InternalSetScalar(self->message, cfield_descriptor->descriptor, arg);
1194}
1195
1196static PyObject* CMessage_AddRepeatedScalar(CMessage* self, PyObject* args) {
1197 CFieldDescriptor* cfield_descriptor;
1198 PyObject* value;
1199 if (!PyArg_ParseTuple(args, C("O!O:AddRepeatedScalar"),
1200 &CFieldDescriptor_Type, &cfield_descriptor, &value)) {
1201 return NULL;
1202 }
1203 AssureWritable(self);
1204
1205 return InternalAddRepeatedScalar(
1206 self->message, cfield_descriptor->descriptor, value);
1207}
1208
1209static PyObject* CMessage_FieldLength(CMessage* self, PyObject* arg) {
1210 CFieldDescriptor* cfield_descriptor;
1211 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
1212 &CFieldDescriptor_Type)) {
1213 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
1214 return NULL;
1215 }
1216 cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
1217
1218 google::protobuf::Message* message = self->message;
1219 int length = message->GetReflection()->FieldSize(
1220 *message, cfield_descriptor->descriptor);
1221 return PyInt_FromLong(length);
1222}
1223
1224static PyObject* CMessage_DebugString(CMessage* self, PyObject* args) {
1225 return PyString_FromString(self->message->DebugString().c_str());
1226}
1227
1228static PyObject* CMessage_SerializeToString(CMessage* self, PyObject* args) {
1229 int size = self->message->ByteSize();
1230 if (size <= 0) {
1231 return PyString_FromString("");
1232 }
1233 PyObject* result = PyString_FromStringAndSize(NULL, size);
1234 if (result == NULL) {
1235 return NULL;
1236 }
1237 char* buffer = PyString_AS_STRING(result);
1238 self->message->SerializeWithCachedSizesToArray(
1239 reinterpret_cast<uint8*>(buffer));
1240 return result;
1241}
1242
1243static PyObject* CMessage_SerializePartialToString(
1244 CMessage* self, PyObject* args) {
1245 string contents;
1246 self->message->SerializePartialToString(&contents);
1247 return PyString_FromStringAndSize(contents.c_str(), contents.size());
1248}
1249
1250static PyObject* CMessageStr(CMessage* self) {
1251 char str[1024];
1252 str[sizeof(str) - 1] = 0;
1253 snprintf(str, sizeof(str) - 1, "CMessage: <%p>", self->message);
1254 return PyString_FromString(str);
1255}
1256
1257static PyObject* CMessage_MergeFrom(CMessage* self, PyObject* arg) {
1258 CMessage* other_message;
1259 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
1260 PyErr_SetString(PyExc_TypeError, "Must be a message");
1261 return NULL;
1262 }
1263
1264 other_message = reinterpret_cast<CMessage*>(arg);
1265 if (other_message->message->GetDescriptor() !=
1266 self->message->GetDescriptor()) {
1267 PyErr_Format(PyExc_TypeError,
1268 "Tried to merge from a message with a different type. "
1269 "to: %s, from: %s",
1270 self->message->GetDescriptor()->full_name().c_str(),
1271 other_message->message->GetDescriptor()->full_name().c_str());
1272 return NULL;
1273 }
1274 AssureWritable(self);
1275
1276 self->message->MergeFrom(*other_message->message);
1277 Py_RETURN_NONE;
1278}
1279
1280static PyObject* CMessage_CopyFrom(CMessage* self, PyObject* arg) {
1281 CMessage* other_message;
1282 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
1283 PyErr_SetString(PyExc_TypeError, "Must be a message");
1284 return NULL;
1285 }
1286
1287 other_message = reinterpret_cast<CMessage*>(arg);
1288 if (other_message->message->GetDescriptor() !=
1289 self->message->GetDescriptor()) {
1290 PyErr_Format(PyExc_TypeError,
1291 "Tried to copy from a message with a different type. "
1292 "to: %s, from: %s",
1293 self->message->GetDescriptor()->full_name().c_str(),
1294 other_message->message->GetDescriptor()->full_name().c_str());
1295 return NULL;
1296 }
1297
1298 AssureWritable(self);
1299
1300 self->message->CopyFrom(*other_message->message);
1301 Py_RETURN_NONE;
1302}
1303
1304static PyObject* CMessage_MergeFromString(CMessage* self, PyObject* arg) {
1305 const void* data;
1306 Py_ssize_t data_length;
1307 if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) {
1308 return NULL;
1309 }
1310
1311 AssureWritable(self);
1312 google::protobuf::io::CodedInputStream input(
1313 reinterpret_cast<const uint8*>(data), data_length);
1314 bool success = self->message->MergePartialFromCodedStream(&input);
1315 if (success) {
1316 return PyInt_FromLong(self->message->ByteSize());
1317 } else {
1318 return PyInt_FromLong(-1);
1319 }
1320}
1321
1322static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args) {
1323 return PyLong_FromLong(self->message->ByteSize());
1324}
1325
1326static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args) {
1327 AssureWritable(self);
1328 Py_RETURN_NONE;
1329}
1330
1331static PyObject* CMessage_SwapRepeatedFieldElements(
1332 CMessage* self, PyObject* args) {
1333 CFieldDescriptor* cfield_descriptor;
1334 int index1, index2;
1335 if (!PyArg_ParseTuple(args, C("O!ii:SwapRepeatedFieldElements"),
1336 &CFieldDescriptor_Type, &cfield_descriptor,
1337 &index1, &index2)) {
1338 return NULL;
1339 }
1340
1341 google::protobuf::Message* message = self->message;
1342 const google::protobuf::Reflection* reflection = message->GetReflection();
1343
1344 reflection->SwapElements(
1345 message, cfield_descriptor->descriptor, index1, index2);
1346 Py_RETURN_NONE;
1347}
1348
1349static PyObject* CMessage_AddMessage(CMessage* self, PyObject* arg) {
1350 CFieldDescriptor* cfield_descriptor;
1351 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
1352 &CFieldDescriptor_Type)) {
1353 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
1354 return NULL;
1355 }
1356 cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
1357 AssureWritable(self);
1358
1359 CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type);
1360 if (py_cmsg == NULL) {
1361 return NULL;
1362 }
1363
1364 google::protobuf::Message* message = self->message;
1365 const google::protobuf::Reflection* reflection = message->GetReflection();
1366 google::protobuf::Message* sub_message =
1367 reflection->AddMessage(message, cfield_descriptor->descriptor);
1368
1369 py_cmsg->parent = NULL;
1370 py_cmsg->full_name = sub_message->GetDescriptor()->full_name().c_str();
1371 py_cmsg->message = sub_message;
1372 py_cmsg->free_message = false;
1373 py_cmsg->read_only = false;
1374 return reinterpret_cast<PyObject*>(py_cmsg);
1375}
1376
1377static PyObject* CMessage_GetRepeatedMessage(CMessage* self, PyObject* args) {
1378 CFieldDescriptor* cfield_descriptor;
1379 PyObject* slice;
1380 if (!PyArg_ParseTuple(args, C("O!O:GetRepeatedMessage"),
1381 &CFieldDescriptor_Type, &cfield_descriptor, &slice)) {
1382 return NULL;
1383 }
1384
1385 return InternalGetRepeatedScalarSlice(
1386 self, cfield_descriptor->descriptor, slice);
1387}
1388
1389static PyObject* CMessage_NewSubMessage(CMessage* self, PyObject* arg) {
1390 CFieldDescriptor* cfield_descriptor;
1391 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
1392 &CFieldDescriptor_Type)) {
1393 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
1394 return NULL;
1395 }
1396 cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
1397
1398 CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type);
1399 if (py_cmsg == NULL) {
1400 return NULL;
1401 }
1402
1403 google::protobuf::Message* message = self->message;
1404 const google::protobuf::Reflection* reflection = message->GetReflection();
1405 const google::protobuf::Message& sub_message =
1406 reflection->GetMessage(*message, cfield_descriptor->descriptor,
1407 global_message_factory);
1408
1409 py_cmsg->full_name = sub_message.GetDescriptor()->full_name().c_str();
1410 py_cmsg->parent = self;
1411 py_cmsg->parent_field = cfield_descriptor;
1412 py_cmsg->message = const_cast<google::protobuf::Message*>(&sub_message);
1413 py_cmsg->free_message = false;
1414 py_cmsg->read_only = true;
1415 return reinterpret_cast<PyObject*>(py_cmsg);
1416}
1417
1418static PyObject* CMessage_MutableMessage(CMessage* self, PyObject* arg) {
1419 CFieldDescriptor* cfield_descriptor;
1420 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
1421 &CFieldDescriptor_Type)) {
1422 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
1423 return NULL;
1424 }
1425 cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
1426 AssureWritable(self);
1427
1428 CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type);
1429 if (py_cmsg == NULL) {
1430 return NULL;
1431 }
1432
1433 google::protobuf::Message* message = self->message;
1434 const google::protobuf::Reflection* reflection = message->GetReflection();
1435 google::protobuf::Message* mutable_message =
1436 reflection->MutableMessage(message, cfield_descriptor->descriptor,
1437 global_message_factory);
1438
1439 py_cmsg->full_name = mutable_message->GetDescriptor()->full_name().c_str();
1440 py_cmsg->message = mutable_message;
1441 py_cmsg->free_message = false;
1442 py_cmsg->read_only = false;
1443 return reinterpret_cast<PyObject*>(py_cmsg);
1444}
1445
1446static PyObject* CMessage_Equals(CMessage* self, PyObject* arg) {
1447 CMessage* other_message;
1448 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
1449 PyErr_SetString(PyExc_TypeError, "Must be a message");
1450 return NULL;
1451 }
1452 other_message = reinterpret_cast<CMessage*>(arg);
1453
1454 if (other_message->message == self->message) {
1455 return PyBool_FromLong(1);
1456 }
1457
1458 if (other_message->message->GetDescriptor() !=
1459 self->message->GetDescriptor()) {
1460 return PyBool_FromLong(0);
1461 }
1462
1463 return PyBool_FromLong(1);
1464}
1465
1466static PyObject* CMessage_ListFields(CMessage* self, PyObject* args) {
1467 google::protobuf::Message* message = self->message;
1468 const google::protobuf::Reflection* reflection = message->GetReflection();
1469 vector<const google::protobuf::FieldDescriptor*> fields;
1470 reflection->ListFields(*message, &fields);
1471
1472 PyObject* list = PyList_New(fields.size());
1473 if (list == NULL) {
1474 return NULL;
1475 }
1476
1477 for (unsigned int i = 0; i < fields.size(); ++i) {
1478 bool is_extension = fields[i]->is_extension();
1479 PyObject* t = PyTuple_New(2);
1480 if (t == NULL) {
1481 Py_DECREF(list);
1482 return NULL;
1483 }
1484
1485 PyObject* is_extension_object = PyBool_FromLong(is_extension ? 1 : 0);
1486
1487 PyObject* field_name;
1488 const string* s;
1489 if (is_extension) {
1490 s = &fields[i]->full_name();
1491 } else {
1492 s = &fields[i]->name();
1493 }
1494 field_name = PyString_FromStringAndSize(s->c_str(), s->length());
1495 if (field_name == NULL) {
1496 Py_DECREF(list);
1497 Py_DECREF(t);
1498 return NULL;
1499 }
1500
1501 PyTuple_SET_ITEM(t, 0, is_extension_object);
1502 PyTuple_SET_ITEM(t, 1, field_name);
1503 PyList_SET_ITEM(list, i, t);
1504 }
1505
1506 return list;
1507}
1508
1509static PyObject* CMessage_FindInitializationErrors(CMessage* self) {
1510 google::protobuf::Message* message = self->message;
1511 vector<string> errors;
1512 message->FindInitializationErrors(&errors);
1513
1514 PyObject* error_list = PyList_New(errors.size());
1515 if (error_list == NULL) {
1516 return NULL;
1517 }
1518 for (unsigned int i = 0; i < errors.size(); ++i) {
1519 const string& error = errors[i];
1520 PyObject* error_string = PyString_FromStringAndSize(
1521 error.c_str(), error.length());
1522 if (error_string == NULL) {
1523 Py_DECREF(error_list);
1524 return NULL;
1525 }
1526 PyList_SET_ITEM(error_list, i, error_string);
1527 }
1528 return error_list;
1529}
1530
1531// ------ Python Constructor:
1532
1533PyObject* Python_NewCMessage(PyObject* ignored, PyObject* arg) {
1534 const char* message_type = PyString_AsString(arg);
1535 if (message_type == NULL) {
1536 return NULL;
1537 }
1538
1539 const google::protobuf::Message* message = CreateMessage(message_type);
1540 if (message == NULL) {
1541 PyErr_Format(PyExc_TypeError, "Couldn't create message of type %s!",
1542 message_type);
1543 return NULL;
1544 }
1545
1546 CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type);
1547 if (py_cmsg == NULL) {
1548 return NULL;
1549 }
1550 py_cmsg->message = message->New();
1551 py_cmsg->free_message = true;
1552 py_cmsg->full_name = message->GetDescriptor()->full_name().c_str();
1553 py_cmsg->read_only = false;
1554 py_cmsg->parent = NULL;
1555 py_cmsg->parent_field = NULL;
1556 return reinterpret_cast<PyObject*>(py_cmsg);
1557}
1558
1559// --- Module Functions (exposed to Python):
1560
1561PyMethodDef methods[] = {
1562 { C("NewCMessage"), (PyCFunction)Python_NewCMessage,
1563 METH_O,
1564 C("Creates a new C++ protocol message, given its full name.") },
1565 { C("NewCDescriptorPool"), (PyCFunction)Python_NewCDescriptorPool,
1566 METH_NOARGS,
1567 C("Creates a new C++ descriptor pool.") },
1568 { C("BuildFile"), (PyCFunction)Python_BuildFile,
1569 METH_O,
1570 C("Registers a new protocol buffer file in the global C++ descriptor "
1571 "pool.") },
1572 {NULL}
1573};
1574
1575// --- Exposing the C proto living inside Python proto to C code:
1576
1577extern const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg);
1578extern Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg);
1579
1580static const google::protobuf::Message* GetCProtoInsidePyProtoImpl(PyObject* msg) {
1581 PyObject* c_msg_obj = PyObject_GetAttrString(msg, "_cmsg");
1582 if (c_msg_obj == NULL) {
1583 PyErr_Clear();
1584 return NULL;
1585 }
1586 Py_DECREF(c_msg_obj);
1587 if (!PyObject_TypeCheck(c_msg_obj, &CMessage_Type)) {
1588 return NULL;
1589 }
1590 CMessage* c_msg = reinterpret_cast<CMessage*>(c_msg_obj);
1591 return c_msg->message;
1592}
1593
1594static google::protobuf::Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) {
1595 PyObject* c_msg_obj = PyObject_GetAttrString(msg, "_cmsg");
1596 if (c_msg_obj == NULL) {
1597 PyErr_Clear();
1598 return NULL;
1599 }
1600 Py_DECREF(c_msg_obj);
1601 if (!PyObject_TypeCheck(c_msg_obj, &CMessage_Type)) {
1602 return NULL;
1603 }
1604 CMessage* c_msg = reinterpret_cast<CMessage*>(c_msg_obj);
1605 AssureWritable(c_msg);
1606 return c_msg->message;
1607}
1608
1609// --- Module Init Function:
1610
1611static const char module_docstring[] =
1612"python-proto2 is a module that can be used to enhance proto2 Python API\n"
1613"performance.\n"
1614"\n"
1615"It provides access to the protocol buffers C++ reflection API that\n"
1616"implements the basic protocol buffer functions.";
1617
1618extern "C" {
1619 void init_net_proto2___python() {
1620 // Initialize constants.
1621 kPythonZero = PyInt_FromLong(0);
1622 kint32min_py = PyInt_FromLong(kint32min);
1623 kint32max_py = PyInt_FromLong(kint32max);
1624 kuint32max_py = PyLong_FromLongLong(kuint32max);
1625 kint64min_py = PyLong_FromLongLong(kint64min);
1626 kint64max_py = PyLong_FromLongLong(kint64max);
1627 kuint64max_py = PyLong_FromUnsignedLongLong(kuint64max);
1628
1629 global_message_factory = new DynamicMessageFactory(GetDescriptorPool());
1630 global_message_factory->SetDelegateToGeneratedFactory(true);
1631
1632 // Export our functions to Python.
1633 PyObject *m;
1634 m = Py_InitModule3(C("_net_proto2___python"), methods, C(module_docstring));
1635 if (m == NULL) {
1636 return;
1637 }
1638
1639 AddConstants(m);
1640
1641 CMessage_Type.tp_new = PyType_GenericNew;
1642 if (PyType_Ready(&CMessage_Type) < 0) {
1643 return;
1644 }
1645
1646 if (!InitDescriptor()) {
1647 return;
1648 }
1649
1650 // Override {Get,Mutable}CProtoInsidePyProto.
1651 GetCProtoInsidePyProtoPtr = GetCProtoInsidePyProtoImpl;
1652 MutableCProtoInsidePyProtoPtr = MutableCProtoInsidePyProtoImpl;
1653 }
1654}
1655
1656} // namespace python
1657} // namespace protobuf
1658} // namespace google