~ubuntu-branches/ubuntu/trusty/protobuf/trusty-proposed

« back to all changes in this revision

Viewing changes to python/google/protobuf/pyext/python-proto2.cc

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2011-05-31 14:41:47 UTC
  • mfrom: (2.2.8 sid)
  • Revision ID: james.westby@ubuntu.com-20110531144147-s41g5fozgvyo462l
Tags: 2.4.0a-2ubuntu1
* Merge with Debian; remaining changes:
  - Fix linking with -lpthread.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 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.
 
103
static PyObject* kPythonZero;
 
104
static PyObject* kint32min_py;
 
105
static PyObject* kint32max_py;
 
106
static PyObject* kuint32max_py;
 
107
static PyObject* kint64min_py;
 
108
static PyObject* kint64max_py;
 
109
static PyObject* kuint64max_py;
 
110
 
 
111
namespace google {
 
112
namespace protobuf {
 
113
namespace python {
 
114
 
 
115
// --- Support Routines:
 
116
 
 
117
static 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
 
 
144
struct CMessage;
 
145
struct CMessage_Type;
 
146
 
 
147
static void CMessageDealloc(CMessage* self);
 
148
static int CMessageInit(CMessage* self, PyObject *args, PyObject *kwds);
 
149
static PyObject* CMessageStr(CMessage* self);
 
150
 
 
151
static PyObject* CMessage_AddMessage(CMessage* self, PyObject* args);
 
152
static PyObject* CMessage_AddRepeatedScalar(CMessage* self, PyObject* args);
 
153
static PyObject* CMessage_AssignRepeatedScalar(CMessage* self, PyObject* args);
 
154
static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args);
 
155
static PyObject* CMessage_Clear(CMessage* self, PyObject* args);
 
156
static PyObject* CMessage_ClearField(CMessage* self, PyObject* args);
 
157
static PyObject* CMessage_ClearFieldByDescriptor(
 
158
    CMessage* self, PyObject* args);
 
159
static PyObject* CMessage_CopyFrom(CMessage* self, PyObject* args);
 
160
static PyObject* CMessage_DebugString(CMessage* self, PyObject* args);
 
161
static PyObject* CMessage_DeleteRepeatedField(CMessage* self, PyObject* args);
 
162
static PyObject* CMessage_Equals(CMessage* self, PyObject* args);
 
163
static PyObject* CMessage_FieldLength(CMessage* self, PyObject* args);
 
164
static PyObject* CMessage_FindInitializationErrors(CMessage* self);
 
165
static PyObject* CMessage_GetRepeatedMessage(CMessage* self, PyObject* args);
 
166
static PyObject* CMessage_GetRepeatedScalar(CMessage* self, PyObject* args);
 
167
static PyObject* CMessage_GetScalar(CMessage* self, PyObject* args);
 
168
static PyObject* CMessage_HasField(CMessage* self, PyObject* args);
 
169
static PyObject* CMessage_HasFieldByDescriptor(CMessage* self, PyObject* args);
 
170
static PyObject* CMessage_IsInitialized(CMessage* self, PyObject* args);
 
171
static PyObject* CMessage_ListFields(CMessage* self, PyObject* args);
 
172
static PyObject* CMessage_MergeFrom(CMessage* self, PyObject* args);
 
173
static PyObject* CMessage_MergeFromString(CMessage* self, PyObject* args);
 
174
static PyObject* CMessage_MutableMessage(CMessage* self, PyObject* args);
 
175
static PyObject* CMessage_NewSubMessage(CMessage* self, PyObject* args);
 
176
static PyObject* CMessage_SetScalar(CMessage* self, PyObject* args);
 
177
static PyObject* CMessage_SerializePartialToString(
 
178
    CMessage* self, PyObject* args);
 
179
static PyObject* CMessage_SerializeToString(CMessage* self, PyObject* args);
 
180
static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args);
 
181
static PyObject* CMessage_SwapRepeatedFieldElements(
 
182
    CMessage* self, PyObject* args);
 
183
 
 
184
// ------ Object Definition:
 
185
 
 
186
typedef 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) }
 
201
static 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
 
 
265
static 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.
 
274
PyTypeObject 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
 
 
321
static 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
 
 
333
template <class T>
 
334
static 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
 
 
362
static 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
 
 
372
static 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
 
 
381
static 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
 
 
390
google::protobuf::DynamicMessageFactory* global_message_factory = NULL;
 
391
static 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
 
 
401
static 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
 
 
471
static 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
 
 
489
static 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
 
 
511
static 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
 
 
613
static 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
 
 
705
static 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
 
 
785
static 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
 
 
883
static 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
 
 
941
static int CMessageInit(CMessage* self, PyObject *args, PyObject *kwds) {
 
942
  self->message = NULL;
 
943
  return 0;
 
944
}
 
945
 
 
946
static 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
 
 
958
static PyObject* CMessage_Clear(CMessage* self, PyObject* args) {
 
959
  AssureWritable(self);
 
960
  self->message->Clear();
 
961
  Py_RETURN_NONE;
 
962
}
 
963
 
 
964
static PyObject* CMessage_IsInitialized(CMessage* self, PyObject* args) {
 
965
  return PyBool_FromLong(self->message->IsInitialized() ? 1 : 0);
 
966
}
 
967
 
 
968
static 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
 
 
988
static 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
 
 
1018
static 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
 
 
1042
static 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
 
 
1061
static 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
 
 
1074
static 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
 
 
1086
static 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
 
 
1111
static 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
 
 
1184
static 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
 
 
1196
static 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
 
 
1209
static 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
 
 
1224
static PyObject* CMessage_DebugString(CMessage* self, PyObject* args) {
 
1225
  return PyString_FromString(self->message->DebugString().c_str());
 
1226
}
 
1227
 
 
1228
static 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
 
 
1243
static 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
 
 
1250
static 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
 
 
1257
static 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
 
 
1280
static 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
 
 
1304
static 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
 
 
1322
static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args) {
 
1323
  return PyLong_FromLong(self->message->ByteSize());
 
1324
}
 
1325
 
 
1326
static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args) {
 
1327
  AssureWritable(self);
 
1328
  Py_RETURN_NONE;
 
1329
}
 
1330
 
 
1331
static 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
 
 
1349
static 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
 
 
1377
static 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
 
 
1389
static 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
 
 
1418
static 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
 
 
1446
static 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
 
 
1466
static 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
 
 
1509
static 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
 
 
1533
PyObject* 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
 
 
1561
PyMethodDef 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
 
 
1577
extern const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg);
 
1578
extern Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg);
 
1579
 
 
1580
static 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
 
 
1594
static 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
 
 
1611
static 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
 
 
1618
extern "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