PageRenderTime 116ms CodeModel.GetById 10ms app.highlight 95ms RepoModel.GetById 1ms app.codeStats 0ms

/thirdparty/breakpad/third_party/protobuf/protobuf/python/google/protobuf/pyext/python-proto2.cc

http://github.com/tomahawk-player/tomahawk
C++ | 1660 lines | 1413 code | 184 blank | 63 comment | 208 complexity | b734479db7d2be23014ee74a35e84d98 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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.
 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(next);
1104      Py_DECREF(iter);
1105      return NULL;
1106    }
1107    Py_DECREF(next);
1108  }
1109  Py_DECREF(iter);
1110  Py_RETURN_NONE;
1111}
1112
1113static PyObject* CMessage_DeleteRepeatedField(CMessage* self, PyObject* args) {
1114  CFieldDescriptor* cfield_descriptor;
1115  PyObject* slice;
1116  if (!PyArg_ParseTuple(args, C("O!O:DeleteRepeatedField"),
1117                        &CFieldDescriptor_Type, &cfield_descriptor, &slice)) {
1118    return NULL;
1119  }
1120  AssureWritable(self);
1121
1122  Py_ssize_t length, from, to, step, slice_length;
1123  google::protobuf::Message* message = self->message;
1124  const google::protobuf::FieldDescriptor* field_descriptor =
1125      cfield_descriptor->descriptor;
1126  const google::protobuf::Reflection* reflection = message->GetReflection();
1127  int min, max;
1128  length = reflection->FieldSize(*message, field_descriptor);
1129
1130  if (PyInt_Check(slice) || PyLong_Check(slice)) {
1131    from = to = PyLong_AsLong(slice);
1132    if (from < 0) {
1133      from = to = length + from;
1134    }
1135    step = 1;
1136    min = max = from;
1137
1138    // Range check.
1139    if (from < 0 || from >= length) {
1140      PyErr_Format(PyExc_IndexError, "list assignment index out of range");
1141      return NULL;
1142    }
1143  } else if (PySlice_Check(slice)) {
1144    from = to = step = slice_length = 0;
1145    PySlice_GetIndicesEx(
1146        reinterpret_cast<PySliceObject*>(slice),
1147        length, &from, &to, &step, &slice_length);
1148    if (from < to) {
1149      min = from;
1150      max = to - 1;
1151    } else {
1152      min = to + 1;
1153      max = from;
1154    }
1155  } else {
1156    PyErr_SetString(PyExc_TypeError, "list indices must be integers");
1157    return NULL;
1158  }
1159
1160  Py_ssize_t i = from;
1161  std::vector<bool> to_delete(length, false);
1162  while (i >= min && i <= max) {
1163    to_delete[i] = true;
1164    i += step;
1165  }
1166
1167  to = 0;
1168  for (i = 0; i < length; ++i) {
1169    if (!to_delete[i]) {
1170      if (i != to) {
1171        reflection->SwapElements(message, field_descriptor, i, to);
1172      }
1173      ++to;
1174    }
1175  }
1176
1177  while (i > to) {
1178    reflection->RemoveLast(message, field_descriptor);
1179    --i;
1180  }
1181
1182  Py_RETURN_NONE;
1183}
1184
1185
1186static PyObject* CMessage_SetScalar(CMessage* self, PyObject* args) {
1187  CFieldDescriptor* cfield_descriptor;
1188  PyObject* arg;
1189  if (!PyArg_ParseTuple(args, C("O!O:SetScalar"),
1190                        &CFieldDescriptor_Type, &cfield_descriptor, &arg)) {
1191    return NULL;
1192  }
1193  AssureWritable(self);
1194
1195  return InternalSetScalar(self->message, cfield_descriptor->descriptor, arg);
1196}
1197
1198static PyObject* CMessage_AddRepeatedScalar(CMessage* self, PyObject* args) {
1199  CFieldDescriptor* cfield_descriptor;
1200  PyObject* value;
1201  if (!PyArg_ParseTuple(args, C("O!O:AddRepeatedScalar"),
1202                        &CFieldDescriptor_Type, &cfield_descriptor, &value)) {
1203    return NULL;
1204  }
1205  AssureWritable(self);
1206
1207  return InternalAddRepeatedScalar(
1208      self->message, cfield_descriptor->descriptor, value);
1209}
1210
1211static PyObject* CMessage_FieldLength(CMessage* self, PyObject* arg) {
1212  CFieldDescriptor* cfield_descriptor;
1213  if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
1214                          &CFieldDescriptor_Type)) {
1215    PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
1216    return NULL;
1217  }
1218  cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
1219
1220  google::protobuf::Message* message = self->message;
1221  int length = message->GetReflection()->FieldSize(
1222      *message, cfield_descriptor->descriptor);
1223  return PyInt_FromLong(length);
1224}
1225
1226static PyObject* CMessage_DebugString(CMessage* self, PyObject* args) {
1227  return PyString_FromString(self->message->DebugString().c_str());
1228}
1229
1230static PyObject* CMessage_SerializeToString(CMessage* self, PyObject* args) {
1231  int size = self->message->ByteSize();
1232  if (size <= 0) {
1233    return PyString_FromString("");
1234  }
1235  PyObject* result = PyString_FromStringAndSize(NULL, size);
1236  if (result == NULL) {
1237    return NULL;
1238  }
1239  char* buffer = PyString_AS_STRING(result);
1240  self->message->SerializeWithCachedSizesToArray(
1241      reinterpret_cast<uint8*>(buffer));
1242  return result;
1243}
1244
1245static PyObject* CMessage_SerializePartialToString(
1246    CMessage* self, PyObject* args) {
1247  string contents;
1248  self->message->SerializePartialToString(&contents);
1249  return PyString_FromStringAndSize(contents.c_str(), contents.size());
1250}
1251
1252static PyObject* CMessageStr(CMessage* self) {
1253  char str[1024];
1254  str[sizeof(str) - 1] = 0;
1255  snprintf(str, sizeof(str) - 1, "CMessage: <%p>", self->message);
1256  return PyString_FromString(str);
1257}
1258
1259static PyObject* CMessage_MergeFrom(CMessage* self, PyObject* arg) {
1260  CMessage* other_message;
1261  if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
1262    PyErr_SetString(PyExc_TypeError, "Must be a message");
1263    return NULL;
1264  }
1265
1266  other_message = reinterpret_cast<CMessage*>(arg);
1267  if (other_message->message->GetDescriptor() !=
1268      self->message->GetDescriptor()) {
1269    PyErr_Format(PyExc_TypeError,
1270                 "Tried to merge from a message with a different type. "
1271                 "to: %s, from: %s",
1272                 self->message->GetDescriptor()->full_name().c_str(),
1273                 other_message->message->GetDescriptor()->full_name().c_str());
1274    return NULL;
1275  }
1276  AssureWritable(self);
1277
1278  self->message->MergeFrom(*other_message->message);
1279  Py_RETURN_NONE;
1280}
1281
1282static PyObject* CMessage_CopyFrom(CMessage* self, PyObject* arg) {
1283  CMessage* other_message;
1284  if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
1285    PyErr_SetString(PyExc_TypeError, "Must be a message");
1286    return NULL;
1287  }
1288
1289  other_message = reinterpret_cast<CMessage*>(arg);
1290  if (other_message->message->GetDescriptor() !=
1291      self->message->GetDescriptor()) {
1292    PyErr_Format(PyExc_TypeError,
1293                 "Tried to copy from a message with a different type. "
1294                 "to: %s, from: %s",
1295                 self->message->GetDescriptor()->full_name().c_str(),
1296                 other_message->message->GetDescriptor()->full_name().c_str());
1297    return NULL;
1298  }
1299
1300  AssureWritable(self);
1301
1302  self->message->CopyFrom(*other_message->message);
1303  Py_RETURN_NONE;
1304}
1305
1306static PyObject* CMessage_MergeFromString(CMessage* self, PyObject* arg) {
1307  const void* data;
1308  Py_ssize_t data_length;
1309  if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) {
1310    return NULL;
1311  }
1312
1313  AssureWritable(self);
1314  google::protobuf::io::CodedInputStream input(
1315      reinterpret_cast<const uint8*>(data), data_length);
1316  bool success = self->message->MergePartialFromCodedStream(&input);
1317  if (success) {
1318    return PyInt_FromLong(self->message->ByteSize());
1319  } else {
1320    return PyInt_FromLong(-1);
1321  }
1322}
1323
1324static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args) {
1325  return PyLong_FromLong(self->message->ByteSize());
1326}
1327
1328static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args) {
1329  AssureWritable(self);
1330  Py_RETURN_NONE;
1331}
1332
1333static PyObject* CMessage_SwapRepeatedFieldElements(
1334    CMessage* self, PyObject* args) {
1335  CFieldDescriptor* cfield_descriptor;
1336  int index1, index2;
1337  if (!PyArg_ParseTuple(args, C("O!ii:SwapRepeatedFieldElements"),
1338                        &CFieldDescriptor_Type, &cfield_descriptor,
1339                        &index1, &index2)) {
1340    return NULL;
1341  }
1342
1343  google::protobuf::Message* message = self->message;
1344  const google::protobuf::Reflection* reflection = message->GetReflection();
1345
1346  reflection->SwapElements(
1347      message, cfield_descriptor->descriptor, index1, index2);
1348  Py_RETURN_NONE;
1349}
1350
1351static PyObject* CMessage_AddMessage(CMessage* self, PyObject* arg) {
1352  CFieldDescriptor* cfield_descriptor;
1353  if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
1354                          &CFieldDescriptor_Type)) {
1355    PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
1356    return NULL;
1357  }
1358  cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
1359  AssureWritable(self);
1360
1361  CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type);
1362  if (py_cmsg == NULL) {
1363    return NULL;
1364  }
1365
1366  google::protobuf::Message* message = self->message;
1367  const google::protobuf::Reflection* reflection = message->GetReflection();
1368  google::protobuf::Message* sub_message =
1369      reflection->AddMessage(message, cfield_descriptor->descriptor);
1370
1371  py_cmsg->parent = NULL;
1372  py_cmsg->full_name = sub_message->GetDescriptor()->full_name().c_str();
1373  py_cmsg->message = sub_message;
1374  py_cmsg->free_message = false;
1375  py_cmsg->read_only = false;
1376  return reinterpret_cast<PyObject*>(py_cmsg);
1377}
1378
1379static PyObject* CMessage_GetRepeatedMessage(CMessage* self, PyObject* args) {
1380  CFieldDescriptor* cfield_descriptor;
1381  PyObject* slice;
1382  if (!PyArg_ParseTuple(args, C("O!O:GetRepeatedMessage"),
1383                        &CFieldDescriptor_Type, &cfield_descriptor, &slice)) {
1384    return NULL;
1385  }
1386
1387  return InternalGetRepeatedScalarSlice(
1388      self, cfield_descriptor->descriptor, slice);
1389}
1390
1391static PyObject* CMessage_NewSubMessage(CMessage* self, PyObject* arg) {
1392  CFieldDescriptor* cfield_descriptor;
1393  if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
1394                          &CFieldDescriptor_Type)) {
1395    PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
1396    return NULL;
1397  }
1398  cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
1399
1400  CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type);
1401  if (py_cmsg == NULL) {
1402    return NULL;
1403  }
1404
1405  google::protobuf::Message* message = self->message;
1406  const google::protobuf::Reflection* reflection = message->GetReflection();
1407  const google::protobuf::Message& sub_message =
1408      reflection->GetMessage(*message, cfield_descriptor->descriptor,
1409                             global_message_factory);
1410
1411  py_cmsg->full_name = sub_message.GetDescriptor()->full_name().c_str();
1412  py_cmsg->parent = self;
1413  py_cmsg->parent_field = cfield_descriptor;
1414  py_cmsg->message = const_cast<google::protobuf::Message*>(&sub_message);
1415  py_cmsg->free_message = false;
1416  py_cmsg->read_only = true;
1417  return reinterpret_cast<PyObject*>(py_cmsg);
1418}
1419
1420static PyObject* CMessage_MutableMessage(CMes

Large files files are truncated, but you can click here to view the full file