summaryrefslogtreecommitdiff
path: root/python/google/protobuf/pyext
diff options
context:
space:
mode:
Diffstat (limited to 'python/google/protobuf/pyext')
-rw-r--r--python/google/protobuf/pyext/README6
-rw-r--r--python/google/protobuf/pyext/__init__.py4
-rw-r--r--python/google/protobuf/pyext/cpp_message.py65
-rw-r--r--python/google/protobuf/pyext/descriptor.cc1845
-rw-r--r--python/google/protobuf/pyext/descriptor.h103
-rw-r--r--python/google/protobuf/pyext/descriptor_containers.cc1786
-rw-r--r--python/google/protobuf/pyext/descriptor_containers.h109
-rw-r--r--python/google/protobuf/pyext/descriptor_database.cc148
-rw-r--r--python/google/protobuf/pyext/descriptor_database.h75
-rw-r--r--python/google/protobuf/pyext/descriptor_pool.cc631
-rw-r--r--python/google/protobuf/pyext/descriptor_pool.h167
-rw-r--r--python/google/protobuf/pyext/extension_dict.cc337
-rw-r--r--python/google/protobuf/pyext/extension_dict.h137
-rw-r--r--python/google/protobuf/pyext/map_container.cc969
-rw-r--r--python/google/protobuf/pyext/map_container.h142
-rw-r--r--python/google/protobuf/pyext/message.cc3085
-rw-r--r--python/google/protobuf/pyext/message.h365
-rw-r--r--python/google/protobuf/pyext/message_module.cc88
-rw-r--r--python/google/protobuf/pyext/proto2_api_test.proto40
-rw-r--r--python/google/protobuf/pyext/python.proto68
-rw-r--r--python/google/protobuf/pyext/python_protobuf.h57
-rw-r--r--python/google/protobuf/pyext/repeated_composite_container.cc612
-rw-r--r--python/google/protobuf/pyext/repeated_composite_container.h179
-rw-r--r--python/google/protobuf/pyext/repeated_scalar_container.cc812
-rw-r--r--python/google/protobuf/pyext/repeated_scalar_container.h122
-rw-r--r--python/google/protobuf/pyext/scoped_pyobject_ptr.h96
26 files changed, 0 insertions, 12048 deletions
diff --git a/python/google/protobuf/pyext/README b/python/google/protobuf/pyext/README
deleted file mode 100644
index 6d61cb45..00000000
--- a/python/google/protobuf/pyext/README
+++ /dev/null
@@ -1,6 +0,0 @@
-This is the 'v2' C++ implementation for python proto2.
-
-It is active when:
-
-PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp
-PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION=2
diff --git a/python/google/protobuf/pyext/__init__.py b/python/google/protobuf/pyext/__init__.py
deleted file mode 100644
index 55856141..00000000
--- a/python/google/protobuf/pyext/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-try:
- __import__('pkg_resources').declare_namespace(__name__)
-except ImportError:
- __path__ = __import__('pkgutil').extend_path(__path__, __name__)
diff --git a/python/google/protobuf/pyext/cpp_message.py b/python/google/protobuf/pyext/cpp_message.py
deleted file mode 100644
index b215211e..00000000
--- a/python/google/protobuf/pyext/cpp_message.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Protocol Buffers - Google's data interchange format
-# Copyright 2008 Google Inc. All rights reserved.
-# https://developers.google.com/protocol-buffers/
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Protocol message implementation hooks for C++ implementation.
-
-Contains helper functions used to create protocol message classes from
-Descriptor objects at runtime backed by the protocol buffer C++ API.
-"""
-
-__author__ = 'tibell@google.com (Johan Tibell)'
-
-from google.protobuf.pyext import _message
-
-
-class GeneratedProtocolMessageType(_message.MessageMeta):
-
- """Metaclass for protocol message classes created at runtime from Descriptors.
-
- The protocol compiler currently uses this metaclass to create protocol
- message classes at runtime. Clients can also manually create their own
- classes at runtime, as in this example:
-
- mydescriptor = Descriptor(.....)
- class MyProtoClass(Message):
- __metaclass__ = GeneratedProtocolMessageType
- DESCRIPTOR = mydescriptor
- myproto_instance = MyProtoClass()
- myproto.foo_field = 23
- ...
-
- The above example will not work for nested types. If you wish to include them,
- use reflection.MakeClass() instead of manually instantiating the class in
- order to create the appropriate class structure.
- """
-
- # Must be consistent with the protocol-compiler code in
- # proto2/compiler/internal/generator.*.
- _DESCRIPTOR_KEY = 'DESCRIPTOR'
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc
deleted file mode 100644
index e6ef5ef5..00000000
--- a/python/google/protobuf/pyext/descriptor.cc
+++ /dev/null
@@ -1,1845 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: petar@google.com (Petar Petrov)
-
-#include <Python.h>
-#include <frameobject.h>
-#include <string>
-
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/dynamic_message.h>
-#include <google/protobuf/pyext/descriptor.h>
-#include <google/protobuf/pyext/descriptor_containers.h>
-#include <google/protobuf/pyext/descriptor_pool.h>
-#include <google/protobuf/pyext/message.h>
-#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
-
-#if PY_MAJOR_VERSION >= 3
- #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
- #define PyString_Check PyUnicode_Check
- #define PyString_InternFromString PyUnicode_InternFromString
- #define PyInt_FromLong PyLong_FromLong
- #define PyInt_FromSize_t PyLong_FromSize_t
- #if PY_VERSION_HEX < 0x03030000
- #error "Python 3.0 - 3.2 are not supported."
- #endif
- #define PyString_AsStringAndSize(ob, charpp, sizep) \
- (PyUnicode_Check(ob)? \
- ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
- PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
-#endif
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-// Store interned descriptors, so that the same C++ descriptor yields the same
-// Python object. Objects are not immortal: this map does not own the
-// references, and items are deleted when the last reference to the object is
-// released.
-// This is enough to support the "is" operator on live objects.
-// All descriptors are stored here.
-hash_map<const void*, PyObject*> interned_descriptors;
-
-PyObject* PyString_FromCppString(const string& str) {
- return PyString_FromStringAndSize(str.c_str(), str.size());
-}
-
-// Check that the calling Python code is the global scope of a _pb2.py module.
-// This function is used to support the current code generated by the proto
-// compiler, which creates descriptors, then update some properties.
-// For example:
-// message_descriptor = Descriptor(
-// name='Message',
-// fields = [FieldDescriptor(name='field')]
-// message_descriptor.fields[0].containing_type = message_descriptor
-//
-// This code is still executed, but the descriptors now have no other storage
-// than the (const) C++ pointer, and are immutable.
-// So we let this code pass, by simply ignoring the new value.
-//
-// From user code, descriptors still look immutable.
-//
-// TODO(amauryfa): Change the proto2 compiler to remove the assignments, and
-// remove this hack.
-bool _CalledFromGeneratedFile(int stacklevel) {
-#ifndef PYPY_VERSION
- // This check is not critical and is somewhat difficult to implement correctly
- // in PyPy.
- PyFrameObject* frame = PyEval_GetFrame();
- if (frame == NULL) {
- return false;
- }
- while (stacklevel-- > 0) {
- frame = frame->f_back;
- if (frame == NULL) {
- return false;
- }
- }
- if (frame->f_globals != frame->f_locals) {
- // Not at global module scope
- return false;
- }
-
- if (frame->f_code->co_filename == NULL) {
- return false;
- }
- char* filename;
- Py_ssize_t filename_size;
- if (PyString_AsStringAndSize(frame->f_code->co_filename,
- &filename, &filename_size) < 0) {
- // filename is not a string.
- PyErr_Clear();
- return false;
- }
- if (filename_size < 7) {
- // filename is too short.
- return false;
- }
- if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) {
- // Filename is not ending with _pb2.
- return false;
- }
-#endif
- return true;
-}
-
-// If the calling code is not a _pb2.py file, raise AttributeError.
-// To be used in attribute setters.
-static int CheckCalledFromGeneratedFile(const char* attr_name) {
- if (_CalledFromGeneratedFile(0)) {
- return 0;
- }
- PyErr_Format(PyExc_AttributeError,
- "attribute is not writable: %s", attr_name);
- return -1;
-}
-
-
-#ifndef PyVarObject_HEAD_INIT
-#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
-#endif
-#ifndef Py_TYPE
-#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
-#endif
-
-
-// Helper functions for descriptor objects.
-
-// A set of templates to retrieve the C++ FileDescriptor of any descriptor.
-template<class DescriptorClass>
-const FileDescriptor* GetFileDescriptor(const DescriptorClass* descriptor) {
- return descriptor->file();
-}
-template<>
-const FileDescriptor* GetFileDescriptor(const FileDescriptor* descriptor) {
- return descriptor;
-}
-template<>
-const FileDescriptor* GetFileDescriptor(const EnumValueDescriptor* descriptor) {
- return descriptor->type()->file();
-}
-template<>
-const FileDescriptor* GetFileDescriptor(const OneofDescriptor* descriptor) {
- return descriptor->containing_type()->file();
-}
-template<>
-const FileDescriptor* GetFileDescriptor(const MethodDescriptor* descriptor) {
- return descriptor->service()->file();
-}
-
-// Converts options into a Python protobuf, and cache the result.
-//
-// This is a bit tricky because options can contain extension fields defined in
-// the same proto file. In this case the options parsed from the serialized_pb
-// have unknown fields, and we need to parse them again.
-//
-// Always returns a new reference.
-template<class DescriptorClass>
-static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) {
- // Options (and their extensions) are completely resolved in the proto file
- // containing the descriptor.
- PyDescriptorPool* pool = GetDescriptorPool_FromPool(
- GetFileDescriptor(descriptor)->pool());
-
- hash_map<const void*, PyObject*>* descriptor_options =
- pool->descriptor_options;
- // First search in the cache.
- if (descriptor_options->find(descriptor) != descriptor_options->end()) {
- PyObject *value = (*descriptor_options)[descriptor];
- Py_INCREF(value);
- return value;
- }
-
- // Build the Options object: get its Python class, and make a copy of the C++
- // read-only instance.
- const Message& options(descriptor->options());
- const Descriptor *message_type = options.GetDescriptor();
- CMessageClass* message_class(
- cdescriptor_pool::GetMessageClass(pool, message_type));
- if (message_class == NULL) {
- // The Options message was not found in the current DescriptorPool.
- // This means that the pool cannot contain any extensions to the Options
- // message either, so falling back to the basic pool we can only increase
- // the chances of successfully parsing the options.
- PyErr_Clear();
- pool = GetDefaultDescriptorPool();
- message_class = cdescriptor_pool::GetMessageClass(pool, message_type);
- }
- if (message_class == NULL) {
- PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s",
- message_type->full_name().c_str());
- return NULL;
- }
- ScopedPyObjectPtr value(
- PyEval_CallObject(message_class->AsPyObject(), NULL));
- if (value == NULL) {
- return NULL;
- }
- if (!PyObject_TypeCheck(value.get(), &CMessage_Type)) {
- PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s",
- message_type->full_name().c_str(),
- Py_TYPE(value.get())->tp_name);
- return NULL;
- }
- CMessage* cmsg = reinterpret_cast<CMessage*>(value.get());
-
- const Reflection* reflection = options.GetReflection();
- const UnknownFieldSet& unknown_fields(reflection->GetUnknownFields(options));
- if (unknown_fields.empty()) {
- cmsg->message->CopyFrom(options);
- } else {
- // Reparse options string! XXX call cmessage::MergeFromString
- string serialized;
- options.SerializeToString(&serialized);
- io::CodedInputStream input(
- reinterpret_cast<const uint8*>(serialized.c_str()), serialized.size());
- input.SetExtensionRegistry(pool->pool, pool->message_factory);
- bool success = cmsg->message->MergePartialFromCodedStream(&input);
- if (!success) {
- PyErr_Format(PyExc_ValueError, "Error parsing Options message");
- return NULL;
- }
- }
-
- // Cache the result.
- Py_INCREF(value.get());
- (*descriptor_options)[descriptor] = value.get();
-
- return value.release();
-}
-
-// Copy the C++ descriptor to a Python message.
-// The Python message is an instance of descriptor_pb2.DescriptorProto
-// or similar.
-template<class DescriptorProtoClass, class DescriptorClass>
-static PyObject* CopyToPythonProto(const DescriptorClass *descriptor,
- PyObject *target) {
- const Descriptor* self_descriptor =
- DescriptorProtoClass::default_instance().GetDescriptor();
- CMessage* message = reinterpret_cast<CMessage*>(target);
- if (!PyObject_TypeCheck(target, &CMessage_Type) ||
- message->message->GetDescriptor() != self_descriptor) {
- PyErr_Format(PyExc_TypeError, "Not a %s message",
- self_descriptor->full_name().c_str());
- return NULL;
- }
- cmessage::AssureWritable(message);
- DescriptorProtoClass* descriptor_message =
- static_cast<DescriptorProtoClass*>(message->message);
- descriptor->CopyTo(descriptor_message);
- Py_RETURN_NONE;
-}
-
-// All Descriptors classes share the same memory layout.
-typedef struct PyBaseDescriptor {
- PyObject_HEAD
-
- // Pointer to the C++ proto2 descriptor.
- // Like all descriptors, it is owned by the global DescriptorPool.
- const void* descriptor;
-
- // Owned reference to the DescriptorPool, to ensure it is kept alive.
- PyDescriptorPool* pool;
-} PyBaseDescriptor;
-
-
-// FileDescriptor structure "inherits" from the base descriptor.
-typedef struct PyFileDescriptor {
- PyBaseDescriptor base;
-
- // The cached version of serialized pb. Either NULL, or a Bytes string.
- // We own the reference.
- PyObject *serialized_pb;
-} PyFileDescriptor;
-
-
-namespace descriptor {
-
-// Creates or retrieve a Python descriptor of the specified type.
-// Objects are interned: the same descriptor will return the same object if it
-// was kept alive.
-// 'was_created' is an optional pointer to a bool, and is set to true if a new
-// object was allocated.
-// Always return a new reference.
-template<class DescriptorClass>
-PyObject* NewInternedDescriptor(PyTypeObject* type,
- const DescriptorClass* descriptor,
- bool* was_created) {
- if (was_created) {
- *was_created = false;
- }
- if (descriptor == NULL) {
- PyErr_BadInternalCall();
- return NULL;
- }
-
- // See if the object is in the map of interned descriptors
- hash_map<const void*, PyObject*>::iterator it =
- interned_descriptors.find(descriptor);
- if (it != interned_descriptors.end()) {
- GOOGLE_DCHECK(Py_TYPE(it->second) == type);
- Py_INCREF(it->second);
- return it->second;
- }
- // Create a new descriptor object
- PyBaseDescriptor* py_descriptor = PyObject_New(
- PyBaseDescriptor, type);
- if (py_descriptor == NULL) {
- return NULL;
- }
- py_descriptor->descriptor = descriptor;
-
- // and cache it.
- interned_descriptors.insert(
- std::make_pair(descriptor, reinterpret_cast<PyObject*>(py_descriptor)));
-
- // Ensures that the DescriptorPool stays alive.
- PyDescriptorPool* pool = GetDescriptorPool_FromPool(
- GetFileDescriptor(descriptor)->pool());
- if (pool == NULL) {
- // Don't DECREF, the object is not fully initialized.
- PyObject_Del(py_descriptor);
- return NULL;
- }
- Py_INCREF(pool);
- py_descriptor->pool = pool;
-
- if (was_created) {
- *was_created = true;
- }
- return reinterpret_cast<PyObject*>(py_descriptor);
-}
-
-static void Dealloc(PyBaseDescriptor* self) {
- // Remove from interned dictionary
- interned_descriptors.erase(self->descriptor);
- Py_CLEAR(self->pool);
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
-}
-
-static PyGetSetDef Getters[] = {
- {NULL}
-};
-
-PyTypeObject PyBaseDescriptor_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".DescriptorBase", // tp_name
- sizeof(PyBaseDescriptor), // tp_basicsize
- 0, // tp_itemsize
- (destructor)Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "Descriptors base class", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- 0, // tp_methods
- 0, // tp_members
- Getters, // tp_getset
-};
-
-} // namespace descriptor
-
-const void* PyDescriptor_AsVoidPtr(PyObject* obj) {
- if (!PyObject_TypeCheck(obj, &descriptor::PyBaseDescriptor_Type)) {
- PyErr_SetString(PyExc_TypeError, "Not a BaseDescriptor");
- return NULL;
- }
- return reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor;
-}
-
-namespace message_descriptor {
-
-// Unchecked accessor to the C++ pointer.
-static const Descriptor* _GetDescriptor(PyBaseDescriptor* self) {
- return reinterpret_cast<const Descriptor*>(self->descriptor);
-}
-
-static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->name());
-}
-
-static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->full_name());
-}
-
-static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
- return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
-}
-
-static PyObject* GetConcreteClass(PyBaseDescriptor* self, void *closure) {
- // Retuns the canonical class for the given descriptor.
- // This is the class that was registered with the primary descriptor pool
- // which contains this descriptor.
- // This might not be the one you expect! For example the returned object does
- // not know about extensions defined in a custom pool.
- CMessageClass* concrete_class(cdescriptor_pool::GetMessageClass(
- GetDescriptorPool_FromPool(_GetDescriptor(self)->file()->pool()),
- _GetDescriptor(self)));
- Py_XINCREF(concrete_class);
- return concrete_class->AsPyObject();
-}
-
-static PyObject* GetFieldsByName(PyBaseDescriptor* self, void *closure) {
- return NewMessageFieldsByName(_GetDescriptor(self));
-}
-
-static PyObject* GetFieldsByCamelcaseName(PyBaseDescriptor* self,
- void *closure) {
- return NewMessageFieldsByCamelcaseName(_GetDescriptor(self));
-}
-
-static PyObject* GetFieldsByNumber(PyBaseDescriptor* self, void *closure) {
- return NewMessageFieldsByNumber(_GetDescriptor(self));
-}
-
-static PyObject* GetFieldsSeq(PyBaseDescriptor* self, void *closure) {
- return NewMessageFieldsSeq(_GetDescriptor(self));
-}
-
-static PyObject* GetNestedTypesByName(PyBaseDescriptor* self, void *closure) {
- return NewMessageNestedTypesByName(_GetDescriptor(self));
-}
-
-static PyObject* GetNestedTypesSeq(PyBaseDescriptor* self, void *closure) {
- return NewMessageNestedTypesSeq(_GetDescriptor(self));
-}
-
-static PyObject* GetExtensionsByName(PyBaseDescriptor* self, void *closure) {
- return NewMessageExtensionsByName(_GetDescriptor(self));
-}
-
-static PyObject* GetExtensions(PyBaseDescriptor* self, void *closure) {
- return NewMessageExtensionsSeq(_GetDescriptor(self));
-}
-
-static PyObject* GetEnumsSeq(PyBaseDescriptor* self, void *closure) {
- return NewMessageEnumsSeq(_GetDescriptor(self));
-}
-
-static PyObject* GetEnumTypesByName(PyBaseDescriptor* self, void *closure) {
- return NewMessageEnumsByName(_GetDescriptor(self));
-}
-
-static PyObject* GetEnumValuesByName(PyBaseDescriptor* self, void *closure) {
- return NewMessageEnumValuesByName(_GetDescriptor(self));
-}
-
-static PyObject* GetOneofsByName(PyBaseDescriptor* self, void *closure) {
- return NewMessageOneofsByName(_GetDescriptor(self));
-}
-
-static PyObject* GetOneofsSeq(PyBaseDescriptor* self, void *closure) {
- return NewMessageOneofsSeq(_GetDescriptor(self));
-}
-
-static PyObject* IsExtendable(PyBaseDescriptor *self, void *closure) {
- if (_GetDescriptor(self)->extension_range_count() > 0) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-static PyObject* GetExtensionRanges(PyBaseDescriptor *self, void *closure) {
- const Descriptor* descriptor = _GetDescriptor(self);
- PyObject* range_list = PyList_New(descriptor->extension_range_count());
-
- for (int i = 0; i < descriptor->extension_range_count(); i++) {
- const Descriptor::ExtensionRange* range = descriptor->extension_range(i);
- PyObject* start = PyInt_FromLong(range->start);
- PyObject* end = PyInt_FromLong(range->end);
- PyList_SetItem(range_list, i, PyTuple_Pack(2, start, end));
- }
-
- return range_list;
-}
-
-static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
- const Descriptor* containing_type =
- _GetDescriptor(self)->containing_type();
- if (containing_type) {
- return PyMessageDescriptor_FromDescriptor(containing_type);
- } else {
- Py_RETURN_NONE;
- }
-}
-
-static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("containing_type");
-}
-
-static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
- const MessageOptions& options(_GetDescriptor(self)->options());
- if (&options != &MessageOptions::default_instance()) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("has_options");
-}
-
-static PyObject* GetOptions(PyBaseDescriptor *self) {
- return GetOrBuildOptions(_GetDescriptor(self));
-}
-
-static int SetOptions(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("_options");
-}
-
-static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
- return CopyToPythonProto<DescriptorProto>(_GetDescriptor(self), target);
-}
-
-static PyObject* EnumValueName(PyBaseDescriptor *self, PyObject *args) {
- const char *enum_name;
- int number;
- if (!PyArg_ParseTuple(args, "si", &enum_name, &number))
- return NULL;
- const EnumDescriptor *enum_type =
- _GetDescriptor(self)->FindEnumTypeByName(enum_name);
- if (enum_type == NULL) {
- PyErr_SetString(PyExc_KeyError, enum_name);
- return NULL;
- }
- const EnumValueDescriptor *enum_value =
- enum_type->FindValueByNumber(number);
- if (enum_value == NULL) {
- PyErr_Format(PyExc_KeyError, "%d", number);
- return NULL;
- }
- return PyString_FromCppString(enum_value->name());
-}
-
-static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) {
- return PyString_InternFromString(
- FileDescriptor::SyntaxName(_GetDescriptor(self)->file()->syntax()));
-}
-
-static PyGetSetDef Getters[] = {
- { "name", (getter)GetName, NULL, "Last name"},
- { "full_name", (getter)GetFullName, NULL, "Full name"},
- { "_concrete_class", (getter)GetConcreteClass, NULL, "concrete class"},
- { "file", (getter)GetFile, NULL, "File descriptor"},
-
- { "fields", (getter)GetFieldsSeq, NULL, "Fields sequence"},
- { "fields_by_name", (getter)GetFieldsByName, NULL, "Fields by name"},
- { "fields_by_camelcase_name", (getter)GetFieldsByCamelcaseName, NULL,
- "Fields by camelCase name"},
- { "fields_by_number", (getter)GetFieldsByNumber, NULL, "Fields by number"},
- { "nested_types", (getter)GetNestedTypesSeq, NULL, "Nested types sequence"},
- { "nested_types_by_name", (getter)GetNestedTypesByName, NULL,
- "Nested types by name"},
- { "extensions", (getter)GetExtensions, NULL, "Extensions Sequence"},
- { "extensions_by_name", (getter)GetExtensionsByName, NULL,
- "Extensions by name"},
- { "extension_ranges", (getter)GetExtensionRanges, NULL, "Extension ranges"},
- { "enum_types", (getter)GetEnumsSeq, NULL, "Enum sequence"},
- { "enum_types_by_name", (getter)GetEnumTypesByName, NULL,
- "Enum types by name"},
- { "enum_values_by_name", (getter)GetEnumValuesByName, NULL,
- "Enum values by name"},
- { "oneofs_by_name", (getter)GetOneofsByName, NULL, "Oneofs by name"},
- { "oneofs", (getter)GetOneofsSeq, NULL, "Oneofs by name"},
- { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
- "Containing type"},
- { "is_extendable", (getter)IsExtendable, (setter)NULL},
- { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
- { "_options", (getter)NULL, (setter)SetOptions, "Options"},
- { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"},
- {NULL}
-};
-
-static PyMethodDef Methods[] = {
- { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
- { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
- { "EnumValueName", (PyCFunction)EnumValueName, METH_VARARGS, },
- {NULL}
-};
-
-} // namespace message_descriptor
-
-PyTypeObject PyMessageDescriptor_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".MessageDescriptor", // tp_name
- sizeof(PyBaseDescriptor), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A Message Descriptor", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- message_descriptor::Methods, // tp_methods
- 0, // tp_members
- message_descriptor::Getters, // tp_getset
- &descriptor::PyBaseDescriptor_Type, // tp_base
-};
-
-PyObject* PyMessageDescriptor_FromDescriptor(
- const Descriptor* message_descriptor) {
- return descriptor::NewInternedDescriptor(
- &PyMessageDescriptor_Type, message_descriptor, NULL);
-}
-
-const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj) {
- if (!PyObject_TypeCheck(obj, &PyMessageDescriptor_Type)) {
- PyErr_SetString(PyExc_TypeError, "Not a MessageDescriptor");
- return NULL;
- }
- return reinterpret_cast<const Descriptor*>(
- reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
-}
-
-namespace field_descriptor {
-
-// Unchecked accessor to the C++ pointer.
-static const FieldDescriptor* _GetDescriptor(
- PyBaseDescriptor *self) {
- return reinterpret_cast<const FieldDescriptor*>(self->descriptor);
-}
-
-static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->full_name());
-}
-
-static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->name());
-}
-
-static PyObject* GetCamelcaseName(PyBaseDescriptor* self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->camelcase_name());
-}
-
-static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
- return PyInt_FromLong(_GetDescriptor(self)->type());
-}
-
-static PyObject* GetCppType(PyBaseDescriptor *self, void *closure) {
- return PyInt_FromLong(_GetDescriptor(self)->cpp_type());
-}
-
-static PyObject* GetLabel(PyBaseDescriptor *self, void *closure) {
- return PyInt_FromLong(_GetDescriptor(self)->label());
-}
-
-static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
- return PyInt_FromLong(_GetDescriptor(self)->number());
-}
-
-static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
- return PyInt_FromLong(_GetDescriptor(self)->index());
-}
-
-static PyObject* GetID(PyBaseDescriptor *self, void *closure) {
- return PyLong_FromVoidPtr(self);
-}
-
-static PyObject* IsExtension(PyBaseDescriptor *self, void *closure) {
- return PyBool_FromLong(_GetDescriptor(self)->is_extension());
-}
-
-static PyObject* HasDefaultValue(PyBaseDescriptor *self, void *closure) {
- return PyBool_FromLong(_GetDescriptor(self)->has_default_value());
-}
-
-static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) {
- PyObject *result;
-
- switch (_GetDescriptor(self)->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32: {
- int32 value = _GetDescriptor(self)->default_value_int32();
- result = PyInt_FromLong(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_INT64: {
- int64 value = _GetDescriptor(self)->default_value_int64();
- result = PyLong_FromLongLong(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT32: {
- uint32 value = _GetDescriptor(self)->default_value_uint32();
- result = PyInt_FromSize_t(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT64: {
- uint64 value = _GetDescriptor(self)->default_value_uint64();
- result = PyLong_FromUnsignedLongLong(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_FLOAT: {
- float value = _GetDescriptor(self)->default_value_float();
- result = PyFloat_FromDouble(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_DOUBLE: {
- double value = _GetDescriptor(self)->default_value_double();
- result = PyFloat_FromDouble(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_BOOL: {
- bool value = _GetDescriptor(self)->default_value_bool();
- result = PyBool_FromLong(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- string value = _GetDescriptor(self)->default_value_string();
- result = ToStringObject(_GetDescriptor(self), value);
- break;
- }
- case FieldDescriptor::CPPTYPE_ENUM: {
- const EnumValueDescriptor* value =
- _GetDescriptor(self)->default_value_enum();
- result = PyInt_FromLong(value->number());
- break;
- }
- default:
- PyErr_Format(PyExc_NotImplementedError, "default value for %s",
- _GetDescriptor(self)->full_name().c_str());
- return NULL;
- }
- return result;
-}
-
-static PyObject* GetCDescriptor(PyObject *self, void *closure) {
- Py_INCREF(self);
- return self;
-}
-
-static PyObject *GetEnumType(PyBaseDescriptor *self, void *closure) {
- const EnumDescriptor* enum_type = _GetDescriptor(self)->enum_type();
- if (enum_type) {
- return PyEnumDescriptor_FromDescriptor(enum_type);
- } else {
- Py_RETURN_NONE;
- }
-}
-
-static int SetEnumType(PyBaseDescriptor *self, PyObject *value, void *closure) {
- return CheckCalledFromGeneratedFile("enum_type");
-}
-
-static PyObject *GetMessageType(PyBaseDescriptor *self, void *closure) {
- const Descriptor* message_type = _GetDescriptor(self)->message_type();
- if (message_type) {
- return PyMessageDescriptor_FromDescriptor(message_type);
- } else {
- Py_RETURN_NONE;
- }
-}
-
-static int SetMessageType(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("message_type");
-}
-
-static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
- const Descriptor* containing_type =
- _GetDescriptor(self)->containing_type();
- if (containing_type) {
- return PyMessageDescriptor_FromDescriptor(containing_type);
- } else {
- Py_RETURN_NONE;
- }
-}
-
-static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("containing_type");
-}
-
-static PyObject* GetExtensionScope(PyBaseDescriptor *self, void *closure) {
- const Descriptor* extension_scope =
- _GetDescriptor(self)->extension_scope();
- if (extension_scope) {
- return PyMessageDescriptor_FromDescriptor(extension_scope);
- } else {
- Py_RETURN_NONE;
- }
-}
-
-static PyObject* GetContainingOneof(PyBaseDescriptor *self, void *closure) {
- const OneofDescriptor* containing_oneof =
- _GetDescriptor(self)->containing_oneof();
- if (containing_oneof) {
- return PyOneofDescriptor_FromDescriptor(containing_oneof);
- } else {
- Py_RETURN_NONE;
- }
-}
-
-static int SetContainingOneof(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("containing_oneof");
-}
-
-static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
- const FieldOptions& options(_GetDescriptor(self)->options());
- if (&options != &FieldOptions::default_instance()) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("has_options");
-}
-
-static PyObject* GetOptions(PyBaseDescriptor *self) {
- return GetOrBuildOptions(_GetDescriptor(self));
-}
-
-static int SetOptions(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("_options");
-}
-
-
-static PyGetSetDef Getters[] = {
- { "full_name", (getter)GetFullName, NULL, "Full name"},
- { "name", (getter)GetName, NULL, "Unqualified name"},
- { "camelcase_name", (getter)GetCamelcaseName, NULL, "Camelcase name"},
- { "type", (getter)GetType, NULL, "C++ Type"},
- { "cpp_type", (getter)GetCppType, NULL, "C++ Type"},
- { "label", (getter)GetLabel, NULL, "Label"},
- { "number", (getter)GetNumber, NULL, "Number"},
- { "index", (getter)GetIndex, NULL, "Index"},
- { "default_value", (getter)GetDefaultValue, NULL, "Default Value"},
- { "has_default_value", (getter)HasDefaultValue},
- { "is_extension", (getter)IsExtension, NULL, "ID"},
- { "id", (getter)GetID, NULL, "ID"},
- { "_cdescriptor", (getter)GetCDescriptor, NULL, "HAACK REMOVE ME"},
-
- { "message_type", (getter)GetMessageType, (setter)SetMessageType,
- "Message type"},
- { "enum_type", (getter)GetEnumType, (setter)SetEnumType, "Enum type"},
- { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
- "Containing type"},
- { "extension_scope", (getter)GetExtensionScope, (setter)NULL,
- "Extension scope"},
- { "containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof,
- "Containing oneof"},
- { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
- { "_options", (getter)NULL, (setter)SetOptions, "Options"},
- {NULL}
-};
-
-static PyMethodDef Methods[] = {
- { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
- {NULL}
-};
-
-} // namespace field_descriptor
-
-PyTypeObject PyFieldDescriptor_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".FieldDescriptor", // tp_name
- sizeof(PyBaseDescriptor), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A Field Descriptor", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- field_descriptor::Methods, // tp_methods
- 0, // tp_members
- field_descriptor::Getters, // tp_getset
- &descriptor::PyBaseDescriptor_Type, // tp_base
-};
-
-PyObject* PyFieldDescriptor_FromDescriptor(
- const FieldDescriptor* field_descriptor) {
- return descriptor::NewInternedDescriptor(
- &PyFieldDescriptor_Type, field_descriptor, NULL);
-}
-
-const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj) {
- if (!PyObject_TypeCheck(obj, &PyFieldDescriptor_Type)) {
- PyErr_SetString(PyExc_TypeError, "Not a FieldDescriptor");
- return NULL;
- }
- return reinterpret_cast<const FieldDescriptor*>(
- reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
-}
-
-namespace enum_descriptor {
-
-// Unchecked accessor to the C++ pointer.
-static const EnumDescriptor* _GetDescriptor(
- PyBaseDescriptor *self) {
- return reinterpret_cast<const EnumDescriptor*>(self->descriptor);
-}
-
-static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->full_name());
-}
-
-static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->name());
-}
-
-static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
- return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
-}
-
-static PyObject* GetEnumvaluesByName(PyBaseDescriptor* self, void *closure) {
- return NewEnumValuesByName(_GetDescriptor(self));
-}
-
-static PyObject* GetEnumvaluesByNumber(PyBaseDescriptor* self, void *closure) {
- return NewEnumValuesByNumber(_GetDescriptor(self));
-}
-
-static PyObject* GetEnumvaluesSeq(PyBaseDescriptor* self, void *closure) {
- return NewEnumValuesSeq(_GetDescriptor(self));
-}
-
-static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
- const Descriptor* containing_type =
- _GetDescriptor(self)->containing_type();
- if (containing_type) {
- return PyMessageDescriptor_FromDescriptor(containing_type);
- } else {
- Py_RETURN_NONE;
- }
-}
-
-static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("containing_type");
-}
-
-
-static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
- const EnumOptions& options(_GetDescriptor(self)->options());
- if (&options != &EnumOptions::default_instance()) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("has_options");
-}
-
-static PyObject* GetOptions(PyBaseDescriptor *self) {
- return GetOrBuildOptions(_GetDescriptor(self));
-}
-
-static int SetOptions(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("_options");
-}
-
-static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
- return CopyToPythonProto<EnumDescriptorProto>(_GetDescriptor(self), target);
-}
-
-static PyMethodDef Methods[] = {
- { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
- { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
- {NULL}
-};
-
-static PyGetSetDef Getters[] = {
- { "full_name", (getter)GetFullName, NULL, "Full name"},
- { "name", (getter)GetName, NULL, "last name"},
- { "file", (getter)GetFile, NULL, "File descriptor"},
- { "values", (getter)GetEnumvaluesSeq, NULL, "values"},
- { "values_by_name", (getter)GetEnumvaluesByName, NULL,
- "Enum values by name"},
- { "values_by_number", (getter)GetEnumvaluesByNumber, NULL,
- "Enum values by number"},
-
- { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
- "Containing type"},
- { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
- { "_options", (getter)NULL, (setter)SetOptions, "Options"},
- {NULL}
-};
-
-} // namespace enum_descriptor
-
-PyTypeObject PyEnumDescriptor_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".EnumDescriptor", // tp_name
- sizeof(PyBaseDescriptor), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A Enum Descriptor", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- enum_descriptor::Methods, // tp_methods
- 0, // tp_members
- enum_descriptor::Getters, // tp_getset
- &descriptor::PyBaseDescriptor_Type, // tp_base
-};
-
-PyObject* PyEnumDescriptor_FromDescriptor(
- const EnumDescriptor* enum_descriptor) {
- return descriptor::NewInternedDescriptor(
- &PyEnumDescriptor_Type, enum_descriptor, NULL);
-}
-
-const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj) {
- if (!PyObject_TypeCheck(obj, &PyEnumDescriptor_Type)) {
- PyErr_SetString(PyExc_TypeError, "Not an EnumDescriptor");
- return NULL;
- }
- return reinterpret_cast<const EnumDescriptor*>(
- reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
-}
-
-namespace enumvalue_descriptor {
-
-// Unchecked accessor to the C++ pointer.
-static const EnumValueDescriptor* _GetDescriptor(
- PyBaseDescriptor *self) {
- return reinterpret_cast<const EnumValueDescriptor*>(self->descriptor);
-}
-
-static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->name());
-}
-
-static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
- return PyInt_FromLong(_GetDescriptor(self)->number());
-}
-
-static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
- return PyInt_FromLong(_GetDescriptor(self)->index());
-}
-
-static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
- return PyEnumDescriptor_FromDescriptor(_GetDescriptor(self)->type());
-}
-
-static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
- const EnumValueOptions& options(_GetDescriptor(self)->options());
- if (&options != &EnumValueOptions::default_instance()) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("has_options");
-}
-
-static PyObject* GetOptions(PyBaseDescriptor *self) {
- return GetOrBuildOptions(_GetDescriptor(self));
-}
-
-static int SetOptions(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("_options");
-}
-
-
-static PyGetSetDef Getters[] = {
- { "name", (getter)GetName, NULL, "name"},
- { "number", (getter)GetNumber, NULL, "number"},
- { "index", (getter)GetIndex, NULL, "index"},
- { "type", (getter)GetType, NULL, "index"},
-
- { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
- { "_options", (getter)NULL, (setter)SetOptions, "Options"},
- {NULL}
-};
-
-static PyMethodDef Methods[] = {
- { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
- {NULL}
-};
-
-} // namespace enumvalue_descriptor
-
-PyTypeObject PyEnumValueDescriptor_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".EnumValueDescriptor", // tp_name
- sizeof(PyBaseDescriptor), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A EnumValue Descriptor", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- enumvalue_descriptor::Methods, // tp_methods
- 0, // tp_members
- enumvalue_descriptor::Getters, // tp_getset
- &descriptor::PyBaseDescriptor_Type, // tp_base
-};
-
-PyObject* PyEnumValueDescriptor_FromDescriptor(
- const EnumValueDescriptor* enumvalue_descriptor) {
- return descriptor::NewInternedDescriptor(
- &PyEnumValueDescriptor_Type, enumvalue_descriptor, NULL);
-}
-
-namespace file_descriptor {
-
-// Unchecked accessor to the C++ pointer.
-static const FileDescriptor* _GetDescriptor(PyFileDescriptor *self) {
- return reinterpret_cast<const FileDescriptor*>(self->base.descriptor);
-}
-
-static void Dealloc(PyFileDescriptor* self) {
- Py_XDECREF(self->serialized_pb);
- descriptor::Dealloc(&self->base);
-}
-
-static PyObject* GetPool(PyFileDescriptor *self, void *closure) {
- PyObject* pool = reinterpret_cast<PyObject*>(
- GetDescriptorPool_FromPool(_GetDescriptor(self)->pool()));
- Py_XINCREF(pool);
- return pool;
-}
-
-static PyObject* GetName(PyFileDescriptor *self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->name());
-}
-
-static PyObject* GetPackage(PyFileDescriptor *self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->package());
-}
-
-static PyObject* GetSerializedPb(PyFileDescriptor *self, void *closure) {
- PyObject *serialized_pb = self->serialized_pb;
- if (serialized_pb != NULL) {
- Py_INCREF(serialized_pb);
- return serialized_pb;
- }
- FileDescriptorProto file_proto;
- _GetDescriptor(self)->CopyTo(&file_proto);
- string contents;
- file_proto.SerializePartialToString(&contents);
- self->serialized_pb = PyBytes_FromStringAndSize(
- contents.c_str(), contents.size());
- if (self->serialized_pb == NULL) {
- return NULL;
- }
- Py_INCREF(self->serialized_pb);
- return self->serialized_pb;
-}
-
-static PyObject* GetMessageTypesByName(PyFileDescriptor* self, void *closure) {
- return NewFileMessageTypesByName(_GetDescriptor(self));
-}
-
-static PyObject* GetEnumTypesByName(PyFileDescriptor* self, void *closure) {
- return NewFileEnumTypesByName(_GetDescriptor(self));
-}
-
-static PyObject* GetExtensionsByName(PyFileDescriptor* self, void *closure) {
- return NewFileExtensionsByName(_GetDescriptor(self));
-}
-
-static PyObject* GetServicesByName(PyFileDescriptor* self, void *closure) {
- return NewFileServicesByName(_GetDescriptor(self));
-}
-
-static PyObject* GetDependencies(PyFileDescriptor* self, void *closure) {
- return NewFileDependencies(_GetDescriptor(self));
-}
-
-static PyObject* GetPublicDependencies(PyFileDescriptor* self, void *closure) {
- return NewFilePublicDependencies(_GetDescriptor(self));
-}
-
-static PyObject* GetHasOptions(PyFileDescriptor *self, void *closure) {
- const FileOptions& options(_GetDescriptor(self)->options());
- if (&options != &FileOptions::default_instance()) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-static int SetHasOptions(PyFileDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("has_options");
-}
-
-static PyObject* GetOptions(PyFileDescriptor *self) {
- return GetOrBuildOptions(_GetDescriptor(self));
-}
-
-static int SetOptions(PyFileDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("_options");
-}
-
-static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) {
- return PyString_InternFromString(
- FileDescriptor::SyntaxName(_GetDescriptor(self)->syntax()));
-}
-
-static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) {
- return CopyToPythonProto<FileDescriptorProto>(_GetDescriptor(self), target);
-}
-
-static PyGetSetDef Getters[] = {
- { "pool", (getter)GetPool, NULL, "pool"},
- { "name", (getter)GetName, NULL, "name"},
- { "package", (getter)GetPackage, NULL, "package"},
- { "serialized_pb", (getter)GetSerializedPb},
- { "message_types_by_name", (getter)GetMessageTypesByName, NULL,
- "Messages by name"},
- { "enum_types_by_name", (getter)GetEnumTypesByName, NULL, "Enums by name"},
- { "extensions_by_name", (getter)GetExtensionsByName, NULL,
- "Extensions by name"},
- { "services_by_name", (getter)GetServicesByName, NULL, "Services by name"},
- { "dependencies", (getter)GetDependencies, NULL, "Dependencies"},
- { "public_dependencies", (getter)GetPublicDependencies, NULL, "Dependencies"},
-
- { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
- { "_options", (getter)NULL, (setter)SetOptions, "Options"},
- { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"},
- {NULL}
-};
-
-static PyMethodDef Methods[] = {
- { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
- { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
- {NULL}
-};
-
-} // namespace file_descriptor
-
-PyTypeObject PyFileDescriptor_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".FileDescriptor", // tp_name
- sizeof(PyFileDescriptor), // tp_basicsize
- 0, // tp_itemsize
- (destructor)file_descriptor::Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A File Descriptor", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- file_descriptor::Methods, // tp_methods
- 0, // tp_members
- file_descriptor::Getters, // tp_getset
- &descriptor::PyBaseDescriptor_Type, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- 0, // tp_alloc
- 0, // tp_new
- PyObject_Del, // tp_free
-};
-
-PyObject* PyFileDescriptor_FromDescriptor(
- const FileDescriptor* file_descriptor) {
- return PyFileDescriptor_FromDescriptorWithSerializedPb(file_descriptor,
- NULL);
-}
-
-PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb(
- const FileDescriptor* file_descriptor, PyObject *serialized_pb) {
- bool was_created;
- PyObject* py_descriptor = descriptor::NewInternedDescriptor(
- &PyFileDescriptor_Type, file_descriptor, &was_created);
- if (py_descriptor == NULL) {
- return NULL;
- }
- if (was_created) {
- PyFileDescriptor* cfile_descriptor =
- reinterpret_cast<PyFileDescriptor*>(py_descriptor);
- Py_XINCREF(serialized_pb);
- cfile_descriptor->serialized_pb = serialized_pb;
- }
- // TODO(amauryfa): In the case of a cached object, check that serialized_pb
- // is the same as before.
-
- return py_descriptor;
-}
-
-const FileDescriptor* PyFileDescriptor_AsDescriptor(PyObject* obj) {
- if (!PyObject_TypeCheck(obj, &PyFileDescriptor_Type)) {
- PyErr_SetString(PyExc_TypeError, "Not a FileDescriptor");
- return NULL;
- }
- return reinterpret_cast<const FileDescriptor*>(
- reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
-}
-
-namespace oneof_descriptor {
-
-// Unchecked accessor to the C++ pointer.
-static const OneofDescriptor* _GetDescriptor(
- PyBaseDescriptor *self) {
- return reinterpret_cast<const OneofDescriptor*>(self->descriptor);
-}
-
-static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->name());
-}
-
-static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->full_name());
-}
-
-static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
- return PyInt_FromLong(_GetDescriptor(self)->index());
-}
-
-static PyObject* GetFields(PyBaseDescriptor* self, void *closure) {
- return NewOneofFieldsSeq(_GetDescriptor(self));
-}
-
-static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
- const Descriptor* containing_type =
- _GetDescriptor(self)->containing_type();
- if (containing_type) {
- return PyMessageDescriptor_FromDescriptor(containing_type);
- } else {
- Py_RETURN_NONE;
- }
-}
-
-static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
- const OneofOptions& options(_GetDescriptor(self)->options());
- if (&options != &OneofOptions::default_instance()) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("has_options");
-}
-
-static PyObject* GetOptions(PyBaseDescriptor *self) {
- return GetOrBuildOptions(_GetDescriptor(self));
-}
-
-static int SetOptions(PyBaseDescriptor *self, PyObject *value,
- void *closure) {
- return CheckCalledFromGeneratedFile("_options");
-}
-
-static PyGetSetDef Getters[] = {
- { "name", (getter)GetName, NULL, "Name"},
- { "full_name", (getter)GetFullName, NULL, "Full name"},
- { "index", (getter)GetIndex, NULL, "Index"},
-
- { "containing_type", (getter)GetContainingType, NULL, "Containing type"},
- { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
- { "_options", (getter)NULL, (setter)SetOptions, "Options"},
- { "fields", (getter)GetFields, NULL, "Fields"},
- {NULL}
-};
-
-static PyMethodDef Methods[] = {
- { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS },
- {NULL}
-};
-
-} // namespace oneof_descriptor
-
-PyTypeObject PyOneofDescriptor_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".OneofDescriptor", // tp_name
- sizeof(PyBaseDescriptor), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A Oneof Descriptor", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- oneof_descriptor::Methods, // tp_methods
- 0, // tp_members
- oneof_descriptor::Getters, // tp_getset
- &descriptor::PyBaseDescriptor_Type, // tp_base
-};
-
-PyObject* PyOneofDescriptor_FromDescriptor(
- const OneofDescriptor* oneof_descriptor) {
- return descriptor::NewInternedDescriptor(
- &PyOneofDescriptor_Type, oneof_descriptor, NULL);
-}
-
-namespace service_descriptor {
-
-// Unchecked accessor to the C++ pointer.
-static const ServiceDescriptor* _GetDescriptor(
- PyBaseDescriptor *self) {
- return reinterpret_cast<const ServiceDescriptor*>(self->descriptor);
-}
-
-static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->name());
-}
-
-static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->full_name());
-}
-
-static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
- return PyInt_FromLong(_GetDescriptor(self)->index());
-}
-
-static PyObject* GetMethods(PyBaseDescriptor* self, void *closure) {
- return NewServiceMethodsSeq(_GetDescriptor(self));
-}
-
-static PyObject* GetMethodsByName(PyBaseDescriptor* self, void *closure) {
- return NewServiceMethodsByName(_GetDescriptor(self));
-}
-
-static PyObject* FindMethodByName(PyBaseDescriptor *self, PyObject* arg) {
- Py_ssize_t name_size;
- char* name;
- if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
- return NULL;
- }
-
- const MethodDescriptor* method_descriptor =
- _GetDescriptor(self)->FindMethodByName(string(name, name_size));
- if (method_descriptor == NULL) {
- PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
- return NULL;
- }
-
- return PyMethodDescriptor_FromDescriptor(method_descriptor);
-}
-
-static PyObject* GetOptions(PyBaseDescriptor *self) {
- return GetOrBuildOptions(_GetDescriptor(self));
-}
-
-static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
- return CopyToPythonProto<ServiceDescriptorProto>(_GetDescriptor(self),
- target);
-}
-
-static PyGetSetDef Getters[] = {
- { "name", (getter)GetName, NULL, "Name", NULL},
- { "full_name", (getter)GetFullName, NULL, "Full name", NULL},
- { "index", (getter)GetIndex, NULL, "Index", NULL},
-
- { "methods", (getter)GetMethods, NULL, "Methods", NULL},
- { "methods_by_name", (getter)GetMethodsByName, NULL, "Methods by name", NULL},
- {NULL}
-};
-
-static PyMethodDef Methods[] = {
- { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS },
- { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
- { "FindMethodByName", (PyCFunction)FindMethodByName, METH_O },
- {NULL}
-};
-
-} // namespace service_descriptor
-
-PyTypeObject PyServiceDescriptor_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".ServiceDescriptor", // tp_name
- sizeof(PyBaseDescriptor), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A Service Descriptor", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- service_descriptor::Methods, // tp_methods
- 0, // tp_members
- service_descriptor::Getters, // tp_getset
- &descriptor::PyBaseDescriptor_Type, // tp_base
-};
-
-PyObject* PyServiceDescriptor_FromDescriptor(
- const ServiceDescriptor* service_descriptor) {
- return descriptor::NewInternedDescriptor(
- &PyServiceDescriptor_Type, service_descriptor, NULL);
-}
-
-namespace method_descriptor {
-
-// Unchecked accessor to the C++ pointer.
-static const MethodDescriptor* _GetDescriptor(
- PyBaseDescriptor *self) {
- return reinterpret_cast<const MethodDescriptor*>(self->descriptor);
-}
-
-static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->name());
-}
-
-static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
- return PyString_FromCppString(_GetDescriptor(self)->full_name());
-}
-
-static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
- return PyInt_FromLong(_GetDescriptor(self)->index());
-}
-
-static PyObject* GetContainingService(PyBaseDescriptor *self, void *closure) {
- const ServiceDescriptor* containing_service =
- _GetDescriptor(self)->service();
- return PyServiceDescriptor_FromDescriptor(containing_service);
-}
-
-static PyObject* GetInputType(PyBaseDescriptor *self, void *closure) {
- const Descriptor* input_type = _GetDescriptor(self)->input_type();
- return PyMessageDescriptor_FromDescriptor(input_type);
-}
-
-static PyObject* GetOutputType(PyBaseDescriptor *self, void *closure) {
- const Descriptor* output_type = _GetDescriptor(self)->output_type();
- return PyMessageDescriptor_FromDescriptor(output_type);
-}
-
-static PyObject* GetOptions(PyBaseDescriptor *self) {
- return GetOrBuildOptions(_GetDescriptor(self));
-}
-
-static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
- return CopyToPythonProto<MethodDescriptorProto>(_GetDescriptor(self), target);
-}
-
-static PyGetSetDef Getters[] = {
- { "name", (getter)GetName, NULL, "Name", NULL},
- { "full_name", (getter)GetFullName, NULL, "Full name", NULL},
- { "index", (getter)GetIndex, NULL, "Index", NULL},
- { "containing_service", (getter)GetContainingService, NULL,
- "Containing service", NULL},
- { "input_type", (getter)GetInputType, NULL, "Input type", NULL},
- { "output_type", (getter)GetOutputType, NULL, "Output type", NULL},
- {NULL}
-};
-
-static PyMethodDef Methods[] = {
- { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
- { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
- {NULL}
-};
-
-} // namespace method_descriptor
-
-PyTypeObject PyMethodDescriptor_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".MethodDescriptor", // tp_name
- sizeof(PyBaseDescriptor), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A Method Descriptor", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- method_descriptor::Methods, // tp_methods
- 0, // tp_members
- method_descriptor::Getters, // tp_getset
- &descriptor::PyBaseDescriptor_Type, // tp_base
-};
-
-PyObject* PyMethodDescriptor_FromDescriptor(
- const MethodDescriptor* method_descriptor) {
- return descriptor::NewInternedDescriptor(
- &PyMethodDescriptor_Type, method_descriptor, NULL);
-}
-
-// Add a enum values to a type dictionary.
-static bool AddEnumValues(PyTypeObject *type,
- const EnumDescriptor* enum_descriptor) {
- for (int i = 0; i < enum_descriptor->value_count(); ++i) {
- const EnumValueDescriptor* value = enum_descriptor->value(i);
- ScopedPyObjectPtr obj(PyInt_FromLong(value->number()));
- if (obj == NULL) {
- return false;
- }
- if (PyDict_SetItemString(type->tp_dict, value->name().c_str(), obj.get()) <
- 0) {
- return false;
- }
- }
- return true;
-}
-
-static bool AddIntConstant(PyTypeObject *type, const char* name, int value) {
- ScopedPyObjectPtr obj(PyInt_FromLong(value));
- if (PyDict_SetItemString(type->tp_dict, name, obj.get()) < 0) {
- return false;
- }
- return true;
-}
-
-
-bool InitDescriptor() {
- if (PyType_Ready(&PyMessageDescriptor_Type) < 0)
- return false;
-
- if (PyType_Ready(&PyFieldDescriptor_Type) < 0)
- return false;
-
- if (!AddEnumValues(&PyFieldDescriptor_Type,
- FieldDescriptorProto::Label_descriptor())) {
- return false;
- }
- if (!AddEnumValues(&PyFieldDescriptor_Type,
- FieldDescriptorProto::Type_descriptor())) {
- return false;
- }
-#define ADD_FIELDDESC_CONSTANT(NAME) AddIntConstant( \
- &PyFieldDescriptor_Type, #NAME, FieldDescriptor::NAME)
- if (!ADD_FIELDDESC_CONSTANT(CPPTYPE_INT32) ||
- !ADD_FIELDDESC_CONSTANT(CPPTYPE_INT64) ||
- !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT32) ||
- !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT64) ||
- !ADD_FIELDDESC_CONSTANT(CPPTYPE_DOUBLE) ||
- !ADD_FIELDDESC_CONSTANT(CPPTYPE_FLOAT) ||
- !ADD_FIELDDESC_CONSTANT(CPPTYPE_BOOL) ||
- !ADD_FIELDDESC_CONSTANT(CPPTYPE_ENUM) ||
- !ADD_FIELDDESC_CONSTANT(CPPTYPE_STRING) ||
- !ADD_FIELDDESC_CONSTANT(CPPTYPE_MESSAGE)) {
- return false;
- }
-#undef ADD_FIELDDESC_CONSTANT
-
- if (PyType_Ready(&PyEnumDescriptor_Type) < 0)
- return false;
-
- if (PyType_Ready(&PyEnumValueDescriptor_Type) < 0)
- return false;
-
- if (PyType_Ready(&PyFileDescriptor_Type) < 0)
- return false;
-
- if (PyType_Ready(&PyOneofDescriptor_Type) < 0)
- return false;
-
- if (PyType_Ready(&PyServiceDescriptor_Type) < 0)
- return false;
-
- if (PyType_Ready(&PyMethodDescriptor_Type) < 0)
- return false;
-
- if (!InitDescriptorMappingTypes())
- return false;
-
- return true;
-}
-
-} // namespace python
-} // namespace protobuf
-} // namespace google
diff --git a/python/google/protobuf/pyext/descriptor.h b/python/google/protobuf/pyext/descriptor.h
deleted file mode 100644
index 1ae0e672..00000000
--- a/python/google/protobuf/pyext/descriptor.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: petar@google.com (Petar Petrov)
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_H__
-#define GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_H__
-
-#include <Python.h>
-
-#include <google/protobuf/descriptor.h>
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-extern PyTypeObject PyMessageDescriptor_Type;
-extern PyTypeObject PyFieldDescriptor_Type;
-extern PyTypeObject PyEnumDescriptor_Type;
-extern PyTypeObject PyEnumValueDescriptor_Type;
-extern PyTypeObject PyFileDescriptor_Type;
-extern PyTypeObject PyOneofDescriptor_Type;
-extern PyTypeObject PyServiceDescriptor_Type;
-extern PyTypeObject PyMethodDescriptor_Type;
-
-// Wraps a Descriptor in a Python object.
-// The C++ pointer is usually borrowed from the global DescriptorPool.
-// In any case, it must stay alive as long as the Python object.
-// Returns a new reference.
-PyObject* PyMessageDescriptor_FromDescriptor(const Descriptor* descriptor);
-PyObject* PyFieldDescriptor_FromDescriptor(const FieldDescriptor* descriptor);
-PyObject* PyEnumDescriptor_FromDescriptor(const EnumDescriptor* descriptor);
-PyObject* PyEnumValueDescriptor_FromDescriptor(
- const EnumValueDescriptor* descriptor);
-PyObject* PyOneofDescriptor_FromDescriptor(const OneofDescriptor* descriptor);
-PyObject* PyFileDescriptor_FromDescriptor(
- const FileDescriptor* file_descriptor);
-PyObject* PyServiceDescriptor_FromDescriptor(
- const ServiceDescriptor* descriptor);
-PyObject* PyMethodDescriptor_FromDescriptor(
- const MethodDescriptor* descriptor);
-
-// Alternate constructor of PyFileDescriptor, used when we already have a
-// serialized FileDescriptorProto that can be cached.
-// Returns a new reference.
-PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb(
- const FileDescriptor* file_descriptor, PyObject* serialized_pb);
-
-// Return the C++ descriptor pointer.
-// This function checks the parameter type; on error, return NULL with a Python
-// exception set.
-const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj);
-const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj);
-const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj);
-const FileDescriptor* PyFileDescriptor_AsDescriptor(PyObject* obj);
-
-// Returns the raw C++ pointer.
-const void* PyDescriptor_AsVoidPtr(PyObject* obj);
-
-// Check that the calling Python code is the global scope of a _pb2.py module.
-// This function is used to support the current code generated by the proto
-// compiler, which insists on modifying descriptors after they have been
-// created.
-//
-// stacklevel indicates which Python frame should be the _pb2.py module.
-//
-// Don't use this function outside descriptor classes.
-bool _CalledFromGeneratedFile(int stacklevel);
-
-bool InitDescriptor();
-
-} // namespace python
-} // namespace protobuf
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_H__
diff --git a/python/google/protobuf/pyext/descriptor_containers.cc b/python/google/protobuf/pyext/descriptor_containers.cc
deleted file mode 100644
index d0aae9c9..00000000
--- a/python/google/protobuf/pyext/descriptor_containers.cc
+++ /dev/null
@@ -1,1786 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Mappings and Sequences of descriptors.
-// Used by Descriptor.fields_by_name, EnumDescriptor.values...
-//
-// They avoid the allocation of a full dictionary or a full list: they simply
-// store a pointer to the parent descriptor, use the C++ Descriptor methods (see
-// google/protobuf/descriptor.h) to retrieve other descriptors, and create
-// Python objects on the fly.
-//
-// The containers fully conform to abc.Mapping and abc.Sequence, and behave just
-// like read-only dictionaries and lists.
-//
-// Because the interface of C++ Descriptors is quite regular, this file actually
-// defines only three types, the exact behavior of a container is controlled by
-// a DescriptorContainerDef structure, which contains functions that uses the
-// public Descriptor API.
-//
-// Note: This DescriptorContainerDef is similar to the "virtual methods table"
-// that a C++ compiler generates for a class. We have to make it explicit
-// because the Python API is based on C, and does not play well with C++
-// inheritance.
-
-#include <Python.h>
-
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/pyext/descriptor_containers.h>
-#include <google/protobuf/pyext/descriptor_pool.h>
-#include <google/protobuf/pyext/descriptor.h>
-#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
-
-#if PY_MAJOR_VERSION >= 3
- #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
- #define PyString_FromFormat PyUnicode_FromFormat
- #define PyInt_FromLong PyLong_FromLong
- #if PY_VERSION_HEX < 0x03030000
- #error "Python 3.0 - 3.2 are not supported."
- #endif
- #define PyString_AsStringAndSize(ob, charpp, sizep) \
- (PyUnicode_Check(ob)? \
- ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
- PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
-#endif
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-struct PyContainer;
-
-typedef int (*CountMethod)(PyContainer* self);
-typedef const void* (*GetByIndexMethod)(PyContainer* self, int index);
-typedef const void* (*GetByNameMethod)(PyContainer* self, const string& name);
-typedef const void* (*GetByCamelcaseNameMethod)(PyContainer* self,
- const string& name);
-typedef const void* (*GetByNumberMethod)(PyContainer* self, int index);
-typedef PyObject* (*NewObjectFromItemMethod)(const void* descriptor);
-typedef const string& (*GetItemNameMethod)(const void* descriptor);
-typedef const string& (*GetItemCamelcaseNameMethod)(const void* descriptor);
-typedef int (*GetItemNumberMethod)(const void* descriptor);
-typedef int (*GetItemIndexMethod)(const void* descriptor);
-
-struct DescriptorContainerDef {
- const char* mapping_name;
- // Returns the number of items in the container.
- CountMethod count_fn;
- // Retrieve item by index (usually the order of declaration in the proto file)
- // Used by sequences, but also iterators. 0 <= index < Count().
- GetByIndexMethod get_by_index_fn;
- // Retrieve item by name (usually a call to some 'FindByName' method).
- // Used by "by_name" mappings.
- GetByNameMethod get_by_name_fn;
- // Retrieve item by camelcase name (usually a call to some
- // 'FindByCamelcaseName' method). Used by "by_camelcase_name" mappings.
- GetByCamelcaseNameMethod get_by_camelcase_name_fn;
- // Retrieve item by declared number (field tag, or enum value).
- // Used by "by_number" mappings.
- GetByNumberMethod get_by_number_fn;
- // Converts a item C++ descriptor to a Python object. Returns a new reference.
- NewObjectFromItemMethod new_object_from_item_fn;
- // Retrieve the name of an item. Used by iterators on "by_name" mappings.
- GetItemNameMethod get_item_name_fn;
- // Retrieve the camelcase name of an item. Used by iterators on
- // "by_camelcase_name" mappings.
- GetItemCamelcaseNameMethod get_item_camelcase_name_fn;
- // Retrieve the number of an item. Used by iterators on "by_number" mappings.
- GetItemNumberMethod get_item_number_fn;
- // Retrieve the index of an item for the container type.
- // Used by "__contains__".
- // If not set, "x in sequence" will do a linear search.
- GetItemIndexMethod get_item_index_fn;
-};
-
-struct PyContainer {
- PyObject_HEAD
-
- // The proto2 descriptor this container belongs to the global DescriptorPool.
- const void* descriptor;
-
- // A pointer to a static structure with function pointers that control the
- // behavior of the container. Very similar to the table of virtual functions
- // of a C++ class.
- const DescriptorContainerDef* container_def;
-
- // The kind of container: list, or dict by name or value.
- enum ContainerKind {
- KIND_SEQUENCE,
- KIND_BYNAME,
- KIND_BYCAMELCASENAME,
- KIND_BYNUMBER,
- } kind;
-};
-
-struct PyContainerIterator {
- PyObject_HEAD
-
- // The container we are iterating over. Own a reference.
- PyContainer* container;
-
- // The current index in the iterator.
- int index;
-
- // The kind of container: list, or dict by name or value.
- enum IterKind {
- KIND_ITERKEY,
- KIND_ITERVALUE,
- KIND_ITERITEM,
- KIND_ITERVALUE_REVERSED, // For sequences
- } kind;
-};
-
-namespace descriptor {
-
-// Returns the C++ item descriptor for a given Python key.
-// When the descriptor is found, return true and set *item.
-// When the descriptor is not found, return true, but set *item to NULL.
-// On error, returns false with an exception set.
-static bool _GetItemByKey(PyContainer* self, PyObject* key, const void** item) {
- switch (self->kind) {
- case PyContainer::KIND_BYNAME:
- {
- char* name;
- Py_ssize_t name_size;
- if (PyString_AsStringAndSize(key, &name, &name_size) < 0) {
- if (PyErr_ExceptionMatches(PyExc_TypeError)) {
- // Not a string, cannot be in the container.
- PyErr_Clear();
- *item = NULL;
- return true;
- }
- return false;
- }
- *item = self->container_def->get_by_name_fn(
- self, string(name, name_size));
- return true;
- }
- case PyContainer::KIND_BYCAMELCASENAME:
- {
- char* camelcase_name;
- Py_ssize_t name_size;
- if (PyString_AsStringAndSize(key, &camelcase_name, &name_size) < 0) {
- if (PyErr_ExceptionMatches(PyExc_TypeError)) {
- // Not a string, cannot be in the container.
- PyErr_Clear();
- *item = NULL;
- return true;
- }
- return false;
- }
- *item = self->container_def->get_by_camelcase_name_fn(
- self, string(camelcase_name, name_size));
- return true;
- }
- case PyContainer::KIND_BYNUMBER:
- {
- Py_ssize_t number = PyNumber_AsSsize_t(key, NULL);
- if (number == -1 && PyErr_Occurred()) {
- if (PyErr_ExceptionMatches(PyExc_TypeError)) {
- // Not a number, cannot be in the container.
- PyErr_Clear();
- *item = NULL;
- return true;
- }
- return false;
- }
- *item = self->container_def->get_by_number_fn(self, number);
- return true;
- }
- default:
- PyErr_SetNone(PyExc_NotImplementedError);
- return false;
- }
-}
-
-// Returns the key of the object at the given index.
-// Used when iterating over mappings.
-static PyObject* _NewKey_ByIndex(PyContainer* self, Py_ssize_t index) {
- const void* item = self->container_def->get_by_index_fn(self, index);
- switch (self->kind) {
- case PyContainer::KIND_BYNAME:
- {
- const string& name(self->container_def->get_item_name_fn(item));
- return PyString_FromStringAndSize(name.c_str(), name.size());
- }
- case PyContainer::KIND_BYCAMELCASENAME:
- {
- const string& name(
- self->container_def->get_item_camelcase_name_fn(item));
- return PyString_FromStringAndSize(name.c_str(), name.size());
- }
- case PyContainer::KIND_BYNUMBER:
- {
- int value = self->container_def->get_item_number_fn(item);
- return PyInt_FromLong(value);
- }
- default:
- PyErr_SetNone(PyExc_NotImplementedError);
- return NULL;
- }
-}
-
-// Returns the object at the given index.
-// Also used when iterating over mappings.
-static PyObject* _NewObj_ByIndex(PyContainer* self, Py_ssize_t index) {
- return self->container_def->new_object_from_item_fn(
- self->container_def->get_by_index_fn(self, index));
-}
-
-static Py_ssize_t Length(PyContainer* self) {
- return self->container_def->count_fn(self);
-}
-
-// The DescriptorMapping type.
-
-static PyObject* Subscript(PyContainer* self, PyObject* key) {
- const void* item = NULL;
- if (!_GetItemByKey(self, key, &item)) {
- return NULL;
- }
- if (!item) {
- PyErr_SetObject(PyExc_KeyError, key);
- return NULL;
- }
- return self->container_def->new_object_from_item_fn(item);
-}
-
-static int AssSubscript(PyContainer* self, PyObject* key, PyObject* value) {
- if (_CalledFromGeneratedFile(0)) {
- return 0;
- }
- PyErr_Format(PyExc_TypeError,
- "'%.200s' object does not support item assignment",
- Py_TYPE(self)->tp_name);
- return -1;
-}
-
-static PyMappingMethods MappingMappingMethods = {
- (lenfunc)Length, // mp_length
- (binaryfunc)Subscript, // mp_subscript
- (objobjargproc)AssSubscript, // mp_ass_subscript
-};
-
-static int Contains(PyContainer* self, PyObject* key) {
- const void* item = NULL;
- if (!_GetItemByKey(self, key, &item)) {
- return -1;
- }
- if (item) {
- return 1;
- } else {
- return 0;
- }
-}
-
-static PyObject* ContainerRepr(PyContainer* self) {
- const char* kind = "";
- switch (self->kind) {
- case PyContainer::KIND_SEQUENCE:
- kind = "sequence";
- break;
- case PyContainer::KIND_BYNAME:
- kind = "mapping by name";
- break;
- case PyContainer::KIND_BYCAMELCASENAME:
- kind = "mapping by camelCase name";
- break;
- case PyContainer::KIND_BYNUMBER:
- kind = "mapping by number";
- break;
- }
- return PyString_FromFormat(
- "<%s %s>", self->container_def->mapping_name, kind);
-}
-
-extern PyTypeObject DescriptorMapping_Type;
-extern PyTypeObject DescriptorSequence_Type;
-
-// A sequence container can only be equal to another sequence container, or (for
-// backward compatibility) to a list containing the same items.
-// Returns 1 if equal, 0 if unequal, -1 on error.
-static int DescriptorSequence_Equal(PyContainer* self, PyObject* other) {
- // Check the identity of C++ pointers.
- if (PyObject_TypeCheck(other, &DescriptorSequence_Type)) {
- PyContainer* other_container = reinterpret_cast<PyContainer*>(other);
- if (self->descriptor == other_container->descriptor &&
- self->container_def == other_container->container_def &&
- self->kind == other_container->kind) {
- return 1;
- } else {
- return 0;
- }
- }
-
- // If other is a list
- if (PyList_Check(other)) {
- // return list(self) == other
- int size = Length(self);
- if (size != PyList_Size(other)) {
- return false;
- }
- for (int index = 0; index < size; index++) {
- ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index));
- if (value1 == NULL) {
- return -1;
- }
- PyObject* value2 = PyList_GetItem(other, index);
- if (value2 == NULL) {
- return -1;
- }
- int cmp = PyObject_RichCompareBool(value1.get(), value2, Py_EQ);
- if (cmp != 1) // error or not equal
- return cmp;
- }
- // All items were found and equal
- return 1;
- }
-
- // Any other object is different.
- return 0;
-}
-
-// A mapping container can only be equal to another mapping container, or (for
-// backward compatibility) to a dict containing the same items.
-// Returns 1 if equal, 0 if unequal, -1 on error.
-static int DescriptorMapping_Equal(PyContainer* self, PyObject* other) {
- // Check the identity of C++ pointers.
- if (PyObject_TypeCheck(other, &DescriptorMapping_Type)) {
- PyContainer* other_container = reinterpret_cast<PyContainer*>(other);
- if (self->descriptor == other_container->descriptor &&
- self->container_def == other_container->container_def &&
- self->kind == other_container->kind) {
- return 1;
- } else {
- return 0;
- }
- }
-
- // If other is a dict
- if (PyDict_Check(other)) {
- // equivalent to dict(self.items()) == other
- int size = Length(self);
- if (size != PyDict_Size(other)) {
- return false;
- }
- for (int index = 0; index < size; index++) {
- ScopedPyObjectPtr key(_NewKey_ByIndex(self, index));
- if (key == NULL) {
- return -1;
- }
- ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index));
- if (value1 == NULL) {
- return -1;
- }
- PyObject* value2 = PyDict_GetItem(other, key.get());
- if (value2 == NULL) {
- // Not found in the other dictionary
- return 0;
- }
- int cmp = PyObject_RichCompareBool(value1.get(), value2, Py_EQ);
- if (cmp != 1) // error or not equal
- return cmp;
- }
- // All items were found and equal
- return 1;
- }
-
- // Any other object is different.
- return 0;
-}
-
-static PyObject* RichCompare(PyContainer* self, PyObject* other, int opid) {
- if (opid != Py_EQ && opid != Py_NE) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- int result;
-
- if (self->kind == PyContainer::KIND_SEQUENCE) {
- result = DescriptorSequence_Equal(self, other);
- } else {
- result = DescriptorMapping_Equal(self, other);
- }
- if (result < 0) {
- return NULL;
- }
- if (result ^ (opid == Py_NE)) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-static PySequenceMethods MappingSequenceMethods = {
- 0, // sq_length
- 0, // sq_concat
- 0, // sq_repeat
- 0, // sq_item
- 0, // sq_slice
- 0, // sq_ass_item
- 0, // sq_ass_slice
- (objobjproc)Contains, // sq_contains
-};
-
-static PyObject* Get(PyContainer* self, PyObject* args) {
- PyObject* key;
- PyObject* default_value = Py_None;
- if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) {
- return NULL;
- }
-
- const void* item;
- if (!_GetItemByKey(self, key, &item)) {
- return NULL;
- }
- if (item == NULL) {
- Py_INCREF(default_value);
- return default_value;
- }
- return self->container_def->new_object_from_item_fn(item);
-}
-
-static PyObject* Keys(PyContainer* self, PyObject* args) {
- Py_ssize_t count = Length(self);
- ScopedPyObjectPtr list(PyList_New(count));
- if (list == NULL) {
- return NULL;
- }
- for (Py_ssize_t index = 0; index < count; ++index) {
- PyObject* key = _NewKey_ByIndex(self, index);
- if (key == NULL) {
- return NULL;
- }
- PyList_SET_ITEM(list.get(), index, key);
- }
- return list.release();
-}
-
-static PyObject* Values(PyContainer* self, PyObject* args) {
- Py_ssize_t count = Length(self);
- ScopedPyObjectPtr list(PyList_New(count));
- if (list == NULL) {
- return NULL;
- }
- for (Py_ssize_t index = 0; index < count; ++index) {
- PyObject* value = _NewObj_ByIndex(self, index);
- if (value == NULL) {
- return NULL;
- }
- PyList_SET_ITEM(list.get(), index, value);
- }
- return list.release();
-}
-
-static PyObject* Items(PyContainer* self, PyObject* args) {
- Py_ssize_t count = Length(self);
- ScopedPyObjectPtr list(PyList_New(count));
- if (list == NULL) {
- return NULL;
- }
- for (Py_ssize_t index = 0; index < count; ++index) {
- ScopedPyObjectPtr obj(PyTuple_New(2));
- if (obj == NULL) {
- return NULL;
- }
- PyObject* key = _NewKey_ByIndex(self, index);
- if (key == NULL) {
- return NULL;
- }
- PyTuple_SET_ITEM(obj.get(), 0, key);
- PyObject* value = _NewObj_ByIndex(self, index);
- if (value == NULL) {
- return NULL;
- }
- PyTuple_SET_ITEM(obj.get(), 1, value);
- PyList_SET_ITEM(list.get(), index, obj.release());
- }
- return list.release();
-}
-
-static PyObject* NewContainerIterator(PyContainer* mapping,
- PyContainerIterator::IterKind kind);
-
-static PyObject* Iter(PyContainer* self) {
- return NewContainerIterator(self, PyContainerIterator::KIND_ITERKEY);
-}
-static PyObject* IterKeys(PyContainer* self, PyObject* args) {
- return NewContainerIterator(self, PyContainerIterator::KIND_ITERKEY);
-}
-static PyObject* IterValues(PyContainer* self, PyObject* args) {
- return NewContainerIterator(self, PyContainerIterator::KIND_ITERVALUE);
-}
-static PyObject* IterItems(PyContainer* self, PyObject* args) {
- return NewContainerIterator(self, PyContainerIterator::KIND_ITERITEM);
-}
-
-static PyMethodDef MappingMethods[] = {
- { "get", (PyCFunction)Get, METH_VARARGS, },
- { "keys", (PyCFunction)Keys, METH_NOARGS, },
- { "values", (PyCFunction)Values, METH_NOARGS, },
- { "items", (PyCFunction)Items, METH_NOARGS, },
- { "iterkeys", (PyCFunction)IterKeys, METH_NOARGS, },
- { "itervalues", (PyCFunction)IterValues, METH_NOARGS, },
- { "iteritems", (PyCFunction)IterItems, METH_NOARGS, },
- {NULL}
-};
-
-PyTypeObject DescriptorMapping_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "DescriptorMapping", // tp_name
- sizeof(PyContainer), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- (reprfunc)ContainerRepr, // tp_repr
- 0, // tp_as_number
- &MappingSequenceMethods, // tp_as_sequence
- &MappingMappingMethods, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- 0, // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- (richcmpfunc)RichCompare, // tp_richcompare
- 0, // tp_weaklistoffset
- (getiterfunc)Iter, // tp_iter
- 0, // tp_iternext
- MappingMethods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- 0, // tp_alloc
- 0, // tp_new
- 0, // tp_free
-};
-
-// The DescriptorSequence type.
-
-static PyObject* GetItem(PyContainer* self, Py_ssize_t index) {
- if (index < 0) {
- index += Length(self);
- }
- if (index < 0 || index >= Length(self)) {
- PyErr_SetString(PyExc_IndexError, "index out of range");
- return NULL;
- }
- return _NewObj_ByIndex(self, index);
-}
-
-static PyObject *
-SeqSubscript(PyContainer* self, PyObject* item) {
- if (PyIndex_Check(item)) {
- Py_ssize_t index;
- index = PyNumber_AsSsize_t(item, PyExc_IndexError);
- if (index == -1 && PyErr_Occurred())
- return NULL;
- return GetItem(self, index);
- }
- // Materialize the list and delegate the operation to it.
- ScopedPyObjectPtr list(PyObject_CallFunctionObjArgs(
- reinterpret_cast<PyObject*>(&PyList_Type), self, NULL));
- if (list == NULL) {
- return NULL;
- }
- return Py_TYPE(list.get())->tp_as_mapping->mp_subscript(list.get(), item);
-}
-
-// Returns the position of the item in the sequence, of -1 if not found.
-// This function never fails.
-int Find(PyContainer* self, PyObject* item) {
- // The item can only be in one position: item.index.
- // Check that self[item.index] == item, it's faster than a linear search.
- //
- // This assumes that sequences are only defined by syntax of the .proto file:
- // a specific item belongs to only one sequence, depending on its position in
- // the .proto file definition.
- const void* descriptor_ptr = PyDescriptor_AsVoidPtr(item);
- if (descriptor_ptr == NULL) {
- // Not a descriptor, it cannot be in the list.
- return -1;
- }
- if (self->container_def->get_item_index_fn) {
- int index = self->container_def->get_item_index_fn(descriptor_ptr);
- if (index < 0 || index >= Length(self)) {
- // This index is not from this collection.
- return -1;
- }
- if (self->container_def->get_by_index_fn(self, index) != descriptor_ptr) {
- // The descriptor at this index is not the same.
- return -1;
- }
- // self[item.index] == item, so return the index.
- return index;
- } else {
- // Fall back to linear search.
- int length = Length(self);
- for (int index=0; index < length; index++) {
- if (self->container_def->get_by_index_fn(self, index) == descriptor_ptr) {
- return index;
- }
- }
- // Not found
- return -1;
- }
-}
-
-// Implements list.index(): the position of the item is in the sequence.
-static PyObject* Index(PyContainer* self, PyObject* item) {
- int position = Find(self, item);
- if (position < 0) {
- // Not found
- PyErr_SetNone(PyExc_ValueError);
- return NULL;
- } else {
- return PyInt_FromLong(position);
- }
-}
-// Implements "list.__contains__()": is the object in the sequence.
-static int SeqContains(PyContainer* self, PyObject* item) {
- int position = Find(self, item);
- if (position < 0) {
- return 0;
- } else {
- return 1;
- }
-}
-
-// Implements list.count(): number of occurrences of the item in the sequence.
-// An item can only appear once in a sequence. If it exists, return 1.
-static PyObject* Count(PyContainer* self, PyObject* item) {
- int position = Find(self, item);
- if (position < 0) {
- return PyInt_FromLong(0);
- } else {
- return PyInt_FromLong(1);
- }
-}
-
-static PyObject* Append(PyContainer* self, PyObject* args) {
- if (_CalledFromGeneratedFile(0)) {
- Py_RETURN_NONE;
- }
- PyErr_Format(PyExc_TypeError,
- "'%.200s' object is not a mutable sequence",
- Py_TYPE(self)->tp_name);
- return NULL;
-}
-
-static PyObject* Reversed(PyContainer* self, PyObject* args) {
- return NewContainerIterator(self,
- PyContainerIterator::KIND_ITERVALUE_REVERSED);
-}
-
-static PyMethodDef SeqMethods[] = {
- { "index", (PyCFunction)Index, METH_O, },
- { "count", (PyCFunction)Count, METH_O, },
- { "append", (PyCFunction)Append, METH_O, },
- { "__reversed__", (PyCFunction)Reversed, METH_NOARGS, },
- {NULL}
-};
-
-static PySequenceMethods SeqSequenceMethods = {
- (lenfunc)Length, // sq_length
- 0, // sq_concat
- 0, // sq_repeat
- (ssizeargfunc)GetItem, // sq_item
- 0, // sq_slice
- 0, // sq_ass_item
- 0, // sq_ass_slice
- (objobjproc)SeqContains, // sq_contains
-};
-
-static PyMappingMethods SeqMappingMethods = {
- (lenfunc)Length, // mp_length
- (binaryfunc)SeqSubscript, // mp_subscript
- 0, // mp_ass_subscript
-};
-
-PyTypeObject DescriptorSequence_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "DescriptorSequence", // tp_name
- sizeof(PyContainer), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- (reprfunc)ContainerRepr, // tp_repr
- 0, // tp_as_number
- &SeqSequenceMethods, // tp_as_sequence
- &SeqMappingMethods, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- 0, // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- (richcmpfunc)RichCompare, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- SeqMethods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- 0, // tp_alloc
- 0, // tp_new
- 0, // tp_free
-};
-
-static PyObject* NewMappingByName(
- DescriptorContainerDef* container_def, const void* descriptor) {
- PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
- if (self == NULL) {
- return NULL;
- }
- self->descriptor = descriptor;
- self->container_def = container_def;
- self->kind = PyContainer::KIND_BYNAME;
- return reinterpret_cast<PyObject*>(self);
-}
-
-static PyObject* NewMappingByCamelcaseName(
- DescriptorContainerDef* container_def, const void* descriptor) {
- PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
- if (self == NULL) {
- return NULL;
- }
- self->descriptor = descriptor;
- self->container_def = container_def;
- self->kind = PyContainer::KIND_BYCAMELCASENAME;
- return reinterpret_cast<PyObject*>(self);
-}
-
-static PyObject* NewMappingByNumber(
- DescriptorContainerDef* container_def, const void* descriptor) {
- if (container_def->get_by_number_fn == NULL ||
- container_def->get_item_number_fn == NULL) {
- PyErr_SetNone(PyExc_NotImplementedError);
- return NULL;
- }
- PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
- if (self == NULL) {
- return NULL;
- }
- self->descriptor = descriptor;
- self->container_def = container_def;
- self->kind = PyContainer::KIND_BYNUMBER;
- return reinterpret_cast<PyObject*>(self);
-}
-
-static PyObject* NewSequence(
- DescriptorContainerDef* container_def, const void* descriptor) {
- PyContainer* self = PyObject_New(PyContainer, &DescriptorSequence_Type);
- if (self == NULL) {
- return NULL;
- }
- self->descriptor = descriptor;
- self->container_def = container_def;
- self->kind = PyContainer::KIND_SEQUENCE;
- return reinterpret_cast<PyObject*>(self);
-}
-
-// Implement iterators over PyContainers.
-
-static void Iterator_Dealloc(PyContainerIterator* self) {
- Py_CLEAR(self->container);
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
-}
-
-static PyObject* Iterator_Next(PyContainerIterator* self) {
- int count = self->container->container_def->count_fn(self->container);
- if (self->index >= count) {
- // Return NULL with no exception to indicate the end.
- return NULL;
- }
- int index = self->index;
- self->index += 1;
- switch (self->kind) {
- case PyContainerIterator::KIND_ITERKEY:
- return _NewKey_ByIndex(self->container, index);
- case PyContainerIterator::KIND_ITERVALUE:
- return _NewObj_ByIndex(self->container, index);
- case PyContainerIterator::KIND_ITERVALUE_REVERSED:
- return _NewObj_ByIndex(self->container, count - index - 1);
- case PyContainerIterator::KIND_ITERITEM:
- {
- PyObject* obj = PyTuple_New(2);
- if (obj == NULL) {
- return NULL;
- }
- PyObject* key = _NewKey_ByIndex(self->container, index);
- if (key == NULL) {
- Py_DECREF(obj);
- return NULL;
- }
- PyTuple_SET_ITEM(obj, 0, key);
- PyObject* value = _NewObj_ByIndex(self->container, index);
- if (value == NULL) {
- Py_DECREF(obj);
- return NULL;
- }
- PyTuple_SET_ITEM(obj, 1, value);
- return obj;
- }
- default:
- PyErr_SetNone(PyExc_NotImplementedError);
- return NULL;
- }
-}
-
-static PyTypeObject ContainerIterator_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "DescriptorContainerIterator", // tp_name
- sizeof(PyContainerIterator), // tp_basicsize
- 0, // tp_itemsize
- (destructor)Iterator_Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- 0, // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- PyObject_SelfIter, // tp_iter
- (iternextfunc)Iterator_Next, // tp_iternext
- 0, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- 0, // tp_alloc
- 0, // tp_new
- 0, // tp_free
-};
-
-static PyObject* NewContainerIterator(PyContainer* container,
- PyContainerIterator::IterKind kind) {
- PyContainerIterator* self = PyObject_New(PyContainerIterator,
- &ContainerIterator_Type);
- if (self == NULL) {
- return NULL;
- }
- Py_INCREF(container);
- self->container = container;
- self->kind = kind;
- self->index = 0;
-
- return reinterpret_cast<PyObject*>(self);
-}
-
-} // namespace descriptor
-
-// Now define the real collections!
-
-namespace message_descriptor {
-
-typedef const Descriptor* ParentDescriptor;
-
-static ParentDescriptor GetDescriptor(PyContainer* self) {
- return reinterpret_cast<ParentDescriptor>(self->descriptor);
-}
-
-namespace fields {
-
-typedef const FieldDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->field_count();
-}
-
-static ItemDescriptor GetByName(PyContainer* self, const string& name) {
- return GetDescriptor(self)->FindFieldByName(name);
-}
-
-static ItemDescriptor GetByCamelcaseName(PyContainer* self,
- const string& name) {
- return GetDescriptor(self)->FindFieldByCamelcaseName(name);
-}
-
-static ItemDescriptor GetByNumber(PyContainer* self, int number) {
- return GetDescriptor(self)->FindFieldByNumber(number);
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->field(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyFieldDescriptor_FromDescriptor(item);
-}
-
-static const string& GetItemName(ItemDescriptor item) {
- return item->name();
-}
-
-static const string& GetItemCamelcaseName(ItemDescriptor item) {
- return item->camelcase_name();
-}
-
-static int GetItemNumber(ItemDescriptor item) {
- return item->number();
-}
-
-static int GetItemIndex(ItemDescriptor item) {
- return item->index();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "MessageFields",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)GetByName,
- (GetByCamelcaseNameMethod)GetByCamelcaseName,
- (GetByNumberMethod)GetByNumber,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)GetItemName,
- (GetItemCamelcaseNameMethod)GetItemCamelcaseName,
- (GetItemNumberMethod)GetItemNumber,
- (GetItemIndexMethod)GetItemIndex,
-};
-
-} // namespace fields
-
-PyObject* NewMessageFieldsByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&fields::ContainerDef, descriptor);
-}
-
-PyObject* NewMessageFieldsByCamelcaseName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByCamelcaseName(&fields::ContainerDef,
- descriptor);
-}
-
-PyObject* NewMessageFieldsByNumber(ParentDescriptor descriptor) {
- return descriptor::NewMappingByNumber(&fields::ContainerDef, descriptor);
-}
-
-PyObject* NewMessageFieldsSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&fields::ContainerDef, descriptor);
-}
-
-namespace nested_types {
-
-typedef const Descriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->nested_type_count();
-}
-
-static ItemDescriptor GetByName(PyContainer* self, const string& name) {
- return GetDescriptor(self)->FindNestedTypeByName(name);
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->nested_type(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyMessageDescriptor_FromDescriptor(item);
-}
-
-static const string& GetItemName(ItemDescriptor item) {
- return item->name();
-}
-
-static int GetItemIndex(ItemDescriptor item) {
- return item->index();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "MessageNestedTypes",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)GetByName,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)GetItemName,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)GetItemIndex,
-};
-
-} // namespace nested_types
-
-PyObject* NewMessageNestedTypesSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&nested_types::ContainerDef, descriptor);
-}
-
-PyObject* NewMessageNestedTypesByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&nested_types::ContainerDef, descriptor);
-}
-
-namespace enums {
-
-typedef const EnumDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->enum_type_count();
-}
-
-static ItemDescriptor GetByName(PyContainer* self, const string& name) {
- return GetDescriptor(self)->FindEnumTypeByName(name);
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->enum_type(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyEnumDescriptor_FromDescriptor(item);
-}
-
-static const string& GetItemName(ItemDescriptor item) {
- return item->name();
-}
-
-static int GetItemIndex(ItemDescriptor item) {
- return item->index();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "MessageNestedEnums",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)GetByName,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)GetItemName,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)GetItemIndex,
-};
-
-} // namespace enums
-
-PyObject* NewMessageEnumsByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&enums::ContainerDef, descriptor);
-}
-
-PyObject* NewMessageEnumsSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&enums::ContainerDef, descriptor);
-}
-
-namespace enumvalues {
-
-// This is the "enum_values_by_name" mapping, which collects values from all
-// enum types in a message.
-//
-// Note that the behavior of the C++ descriptor is different: it will search and
-// return the first value that matches the name, whereas the Python
-// implementation retrieves the last one.
-
-typedef const EnumValueDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- int count = 0;
- for (int i = 0; i < GetDescriptor(self)->enum_type_count(); ++i) {
- count += GetDescriptor(self)->enum_type(i)->value_count();
- }
- return count;
-}
-
-static ItemDescriptor GetByName(PyContainer* self, const string& name) {
- return GetDescriptor(self)->FindEnumValueByName(name);
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- // This is not optimal, but the number of enums *types* in a given message
- // is small. This function is only used when iterating over the mapping.
- const EnumDescriptor* enum_type = NULL;
- int enum_type_count = GetDescriptor(self)->enum_type_count();
- for (int i = 0; i < enum_type_count; ++i) {
- enum_type = GetDescriptor(self)->enum_type(i);
- int enum_value_count = enum_type->value_count();
- if (index < enum_value_count) {
- // Found it!
- break;
- }
- index -= enum_value_count;
- }
- // The next statement cannot overflow, because this function is only called by
- // internal iterators which ensure that 0 <= index < Count().
- return enum_type->value(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyEnumValueDescriptor_FromDescriptor(item);
-}
-
-static const string& GetItemName(ItemDescriptor item) {
- return item->name();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "MessageEnumValues",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)GetByName,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)GetItemName,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)NULL,
-};
-
-} // namespace enumvalues
-
-PyObject* NewMessageEnumValuesByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&enumvalues::ContainerDef, descriptor);
-}
-
-namespace extensions {
-
-typedef const FieldDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->extension_count();
-}
-
-static ItemDescriptor GetByName(PyContainer* self, const string& name) {
- return GetDescriptor(self)->FindExtensionByName(name);
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->extension(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyFieldDescriptor_FromDescriptor(item);
-}
-
-static const string& GetItemName(ItemDescriptor item) {
- return item->name();
-}
-
-static int GetItemIndex(ItemDescriptor item) {
- return item->index();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "MessageExtensions",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)GetByName,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)GetItemName,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)GetItemIndex,
-};
-
-} // namespace extensions
-
-PyObject* NewMessageExtensionsByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&extensions::ContainerDef, descriptor);
-}
-
-PyObject* NewMessageExtensionsSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&extensions::ContainerDef, descriptor);
-}
-
-namespace oneofs {
-
-typedef const OneofDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->oneof_decl_count();
-}
-
-static ItemDescriptor GetByName(PyContainer* self, const string& name) {
- return GetDescriptor(self)->FindOneofByName(name);
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->oneof_decl(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyOneofDescriptor_FromDescriptor(item);
-}
-
-static const string& GetItemName(ItemDescriptor item) {
- return item->name();
-}
-
-static int GetItemIndex(ItemDescriptor item) {
- return item->index();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "MessageOneofs",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)GetByName,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)GetItemName,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)GetItemIndex,
-};
-
-} // namespace oneofs
-
-PyObject* NewMessageOneofsByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&oneofs::ContainerDef, descriptor);
-}
-
-PyObject* NewMessageOneofsSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&oneofs::ContainerDef, descriptor);
-}
-
-} // namespace message_descriptor
-
-namespace enum_descriptor {
-
-typedef const EnumDescriptor* ParentDescriptor;
-
-static ParentDescriptor GetDescriptor(PyContainer* self) {
- return reinterpret_cast<ParentDescriptor>(self->descriptor);
-}
-
-namespace enumvalues {
-
-typedef const EnumValueDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->value_count();
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->value(index);
-}
-
-static ItemDescriptor GetByName(PyContainer* self, const string& name) {
- return GetDescriptor(self)->FindValueByName(name);
-}
-
-static ItemDescriptor GetByNumber(PyContainer* self, int number) {
- return GetDescriptor(self)->FindValueByNumber(number);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyEnumValueDescriptor_FromDescriptor(item);
-}
-
-static const string& GetItemName(ItemDescriptor item) {
- return item->name();
-}
-
-static int GetItemNumber(ItemDescriptor item) {
- return item->number();
-}
-
-static int GetItemIndex(ItemDescriptor item) {
- return item->index();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "EnumValues",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)GetByName,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)GetByNumber,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)GetItemName,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)GetItemNumber,
- (GetItemIndexMethod)GetItemIndex,
-};
-
-} // namespace enumvalues
-
-PyObject* NewEnumValuesByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&enumvalues::ContainerDef, descriptor);
-}
-
-PyObject* NewEnumValuesByNumber(ParentDescriptor descriptor) {
- return descriptor::NewMappingByNumber(&enumvalues::ContainerDef, descriptor);
-}
-
-PyObject* NewEnumValuesSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&enumvalues::ContainerDef, descriptor);
-}
-
-} // namespace enum_descriptor
-
-namespace oneof_descriptor {
-
-typedef const OneofDescriptor* ParentDescriptor;
-
-static ParentDescriptor GetDescriptor(PyContainer* self) {
- return reinterpret_cast<ParentDescriptor>(self->descriptor);
-}
-
-namespace fields {
-
-typedef const FieldDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->field_count();
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->field(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyFieldDescriptor_FromDescriptor(item);
-}
-
-static int GetItemIndex(ItemDescriptor item) {
- return item->index_in_oneof();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "OneofFields",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)NULL,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)NULL,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)GetItemIndex,
-};
-
-} // namespace fields
-
-PyObject* NewOneofFieldsSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&fields::ContainerDef, descriptor);
-}
-
-} // namespace oneof_descriptor
-
-namespace service_descriptor {
-
-typedef const ServiceDescriptor* ParentDescriptor;
-
-static ParentDescriptor GetDescriptor(PyContainer* self) {
- return reinterpret_cast<ParentDescriptor>(self->descriptor);
-}
-
-namespace methods {
-
-typedef const MethodDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->method_count();
-}
-
-static ItemDescriptor GetByName(PyContainer* self, const string& name) {
- return GetDescriptor(self)->FindMethodByName(name);
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->method(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyMethodDescriptor_FromDescriptor(item);
-}
-
-static const string& GetItemName(ItemDescriptor item) {
- return item->name();
-}
-
-static int GetItemIndex(ItemDescriptor item) {
- return item->index();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "ServiceMethods",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)GetByName,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)GetItemName,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)GetItemIndex,
-};
-
-} // namespace methods
-
-PyObject* NewServiceMethodsSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&methods::ContainerDef, descriptor);
-}
-
-PyObject* NewServiceMethodsByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&methods::ContainerDef, descriptor);
-}
-
-} // namespace service_descriptor
-
-namespace file_descriptor {
-
-typedef const FileDescriptor* ParentDescriptor;
-
-static ParentDescriptor GetDescriptor(PyContainer* self) {
- return reinterpret_cast<ParentDescriptor>(self->descriptor);
-}
-
-namespace messages {
-
-typedef const Descriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->message_type_count();
-}
-
-static ItemDescriptor GetByName(PyContainer* self, const string& name) {
- return GetDescriptor(self)->FindMessageTypeByName(name);
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->message_type(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyMessageDescriptor_FromDescriptor(item);
-}
-
-static const string& GetItemName(ItemDescriptor item) {
- return item->name();
-}
-
-static int GetItemIndex(ItemDescriptor item) {
- return item->index();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "FileMessages",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)GetByName,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)GetItemName,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)GetItemIndex,
-};
-
-} // namespace messages
-
-PyObject* NewFileMessageTypesByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&messages::ContainerDef, descriptor);
-}
-
-namespace enums {
-
-typedef const EnumDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->enum_type_count();
-}
-
-static ItemDescriptor GetByName(PyContainer* self, const string& name) {
- return GetDescriptor(self)->FindEnumTypeByName(name);
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->enum_type(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyEnumDescriptor_FromDescriptor(item);
-}
-
-static const string& GetItemName(ItemDescriptor item) {
- return item->name();
-}
-
-static int GetItemIndex(ItemDescriptor item) {
- return item->index();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "FileEnums",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)GetByName,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)GetItemName,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)GetItemIndex,
-};
-
-} // namespace enums
-
-PyObject* NewFileEnumTypesByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&enums::ContainerDef, descriptor);
-}
-
-namespace extensions {
-
-typedef const FieldDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->extension_count();
-}
-
-static ItemDescriptor GetByName(PyContainer* self, const string& name) {
- return GetDescriptor(self)->FindExtensionByName(name);
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->extension(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyFieldDescriptor_FromDescriptor(item);
-}
-
-static const string& GetItemName(ItemDescriptor item) {
- return item->name();
-}
-
-static int GetItemIndex(ItemDescriptor item) {
- return item->index();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "FileExtensions",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)GetByName,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)GetItemName,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)GetItemIndex,
-};
-
-} // namespace extensions
-
-PyObject* NewFileExtensionsByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&extensions::ContainerDef, descriptor);
-}
-
-namespace services {
-
-typedef const ServiceDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->service_count();
-}
-
-static ItemDescriptor GetByName(PyContainer* self, const string& name) {
- return GetDescriptor(self)->FindServiceByName(name);
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->service(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyServiceDescriptor_FromDescriptor(item);
-}
-
-static const string& GetItemName(ItemDescriptor item) {
- return item->name();
-}
-
-static int GetItemIndex(ItemDescriptor item) {
- return item->index();
-}
-
-static DescriptorContainerDef ContainerDef = {
- "FileServices",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)GetByName,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)GetItemName,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)GetItemIndex,
-};
-
-} // namespace services
-
-PyObject* NewFileServicesByName(const FileDescriptor* descriptor) {
- return descriptor::NewMappingByName(&services::ContainerDef, descriptor);
-}
-
-namespace dependencies {
-
-typedef const FileDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->dependency_count();
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->dependency(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyFileDescriptor_FromDescriptor(item);
-}
-
-static DescriptorContainerDef ContainerDef = {
- "FileDependencies",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)NULL,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)NULL,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)NULL,
-};
-
-} // namespace dependencies
-
-PyObject* NewFileDependencies(const FileDescriptor* descriptor) {
- return descriptor::NewSequence(&dependencies::ContainerDef, descriptor);
-}
-
-namespace public_dependencies {
-
-typedef const FileDescriptor* ItemDescriptor;
-
-static int Count(PyContainer* self) {
- return GetDescriptor(self)->public_dependency_count();
-}
-
-static ItemDescriptor GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->public_dependency(index);
-}
-
-static PyObject* NewObjectFromItem(ItemDescriptor item) {
- return PyFileDescriptor_FromDescriptor(item);
-}
-
-static DescriptorContainerDef ContainerDef = {
- "FilePublicDependencies",
- (CountMethod)Count,
- (GetByIndexMethod)GetByIndex,
- (GetByNameMethod)NULL,
- (GetByCamelcaseNameMethod)NULL,
- (GetByNumberMethod)NULL,
- (NewObjectFromItemMethod)NewObjectFromItem,
- (GetItemNameMethod)NULL,
- (GetItemCamelcaseNameMethod)NULL,
- (GetItemNumberMethod)NULL,
- (GetItemIndexMethod)NULL,
-};
-
-} // namespace public_dependencies
-
-PyObject* NewFilePublicDependencies(const FileDescriptor* descriptor) {
- return descriptor::NewSequence(&public_dependencies::ContainerDef,
- descriptor);
-}
-
-} // namespace file_descriptor
-
-
-// Register all implementations
-
-bool InitDescriptorMappingTypes() {
- if (PyType_Ready(&descriptor::DescriptorMapping_Type) < 0)
- return false;
- if (PyType_Ready(&descriptor::DescriptorSequence_Type) < 0)
- return false;
- if (PyType_Ready(&descriptor::ContainerIterator_Type) < 0)
- return false;
- return true;
-}
-
-} // namespace python
-} // namespace protobuf
-} // namespace google
diff --git a/python/google/protobuf/pyext/descriptor_containers.h b/python/google/protobuf/pyext/descriptor_containers.h
deleted file mode 100644
index 83de07b6..00000000
--- a/python/google/protobuf/pyext/descriptor_containers.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_CONTAINERS_H__
-#define GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_CONTAINERS_H__
-
-// Mappings and Sequences of descriptors.
-// They implement containers like fields_by_name, EnumDescriptor.values...
-// See descriptor_containers.cc for more description.
-#include <Python.h>
-
-namespace google {
-namespace protobuf {
-
-class Descriptor;
-class FileDescriptor;
-class EnumDescriptor;
-class OneofDescriptor;
-class ServiceDescriptor;
-
-namespace python {
-
-// Initialize the various types and objects.
-bool InitDescriptorMappingTypes();
-
-// Each function below returns a Mapping, or a Sequence of descriptors.
-// They all return a new reference.
-
-namespace message_descriptor {
-PyObject* NewMessageFieldsByName(const Descriptor* descriptor);
-PyObject* NewMessageFieldsByCamelcaseName(const Descriptor* descriptor);
-PyObject* NewMessageFieldsByNumber(const Descriptor* descriptor);
-PyObject* NewMessageFieldsSeq(const Descriptor* descriptor);
-
-PyObject* NewMessageNestedTypesSeq(const Descriptor* descriptor);
-PyObject* NewMessageNestedTypesByName(const Descriptor* descriptor);
-
-PyObject* NewMessageEnumsByName(const Descriptor* descriptor);
-PyObject* NewMessageEnumsSeq(const Descriptor* descriptor);
-PyObject* NewMessageEnumValuesByName(const Descriptor* descriptor);
-
-PyObject* NewMessageExtensionsByName(const Descriptor* descriptor);
-PyObject* NewMessageExtensionsSeq(const Descriptor* descriptor);
-
-PyObject* NewMessageOneofsByName(const Descriptor* descriptor);
-PyObject* NewMessageOneofsSeq(const Descriptor* descriptor);
-} // namespace message_descriptor
-
-namespace enum_descriptor {
-PyObject* NewEnumValuesByName(const EnumDescriptor* descriptor);
-PyObject* NewEnumValuesByNumber(const EnumDescriptor* descriptor);
-PyObject* NewEnumValuesSeq(const EnumDescriptor* descriptor);
-} // namespace enum_descriptor
-
-namespace oneof_descriptor {
-PyObject* NewOneofFieldsSeq(const OneofDescriptor* descriptor);
-} // namespace oneof_descriptor
-
-namespace file_descriptor {
-PyObject* NewFileMessageTypesByName(const FileDescriptor* descriptor);
-
-PyObject* NewFileEnumTypesByName(const FileDescriptor* descriptor);
-
-PyObject* NewFileExtensionsByName(const FileDescriptor* descriptor);
-
-PyObject* NewFileServicesByName(const FileDescriptor* descriptor);
-
-PyObject* NewFileDependencies(const FileDescriptor* descriptor);
-PyObject* NewFilePublicDependencies(const FileDescriptor* descriptor);
-} // namespace file_descriptor
-
-namespace service_descriptor {
-PyObject* NewServiceMethodsSeq(const ServiceDescriptor* descriptor);
-PyObject* NewServiceMethodsByName(const ServiceDescriptor* descriptor);
-} // namespace service_descriptor
-
-
-} // namespace python
-} // namespace protobuf
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_CONTAINERS_H__
diff --git a/python/google/protobuf/pyext/descriptor_database.cc b/python/google/protobuf/pyext/descriptor_database.cc
deleted file mode 100644
index daa40cc7..00000000
--- a/python/google/protobuf/pyext/descriptor_database.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file defines a C++ DescriptorDatabase, which wraps a Python Database
-// and delegate all its operations to Python methods.
-
-#include <google/protobuf/pyext/descriptor_database.h>
-
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/pyext/message.h>
-#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-PyDescriptorDatabase::PyDescriptorDatabase(PyObject* py_database)
- : py_database_(py_database) {
- Py_INCREF(py_database_);
-}
-
-PyDescriptorDatabase::~PyDescriptorDatabase() { Py_DECREF(py_database_); }
-
-// Convert a Python object to a FileDescriptorProto pointer.
-// Handles all kinds of Python errors, which are simply logged.
-static bool GetFileDescriptorProto(PyObject* py_descriptor,
- FileDescriptorProto* output) {
- if (py_descriptor == NULL) {
- if (PyErr_ExceptionMatches(PyExc_KeyError)) {
- // Expected error: item was simply not found.
- PyErr_Clear();
- } else {
- GOOGLE_LOG(ERROR) << "DescriptorDatabase method raised an error";
- PyErr_Print();
- }
- return false;
- }
- if (py_descriptor == Py_None) {
- return false;
- }
- const Descriptor* filedescriptor_descriptor =
- FileDescriptorProto::default_instance().GetDescriptor();
- CMessage* message = reinterpret_cast<CMessage*>(py_descriptor);
- if (PyObject_TypeCheck(py_descriptor, &CMessage_Type) &&
- message->message->GetDescriptor() == filedescriptor_descriptor) {
- // Fast path: Just use the pointer.
- FileDescriptorProto* file_proto =
- static_cast<FileDescriptorProto*>(message->message);
- *output = *file_proto;
- return true;
- } else {
- // Slow path: serialize the message. This allows to use databases which
- // use a different implementation of FileDescriptorProto.
- ScopedPyObjectPtr serialized_pb(
- PyObject_CallMethod(py_descriptor, "SerializeToString", NULL));
- if (serialized_pb == NULL) {
- GOOGLE_LOG(ERROR)
- << "DescriptorDatabase method did not return a FileDescriptorProto";
- PyErr_Print();
- return false;
- }
- char* str;
- Py_ssize_t len;
- if (PyBytes_AsStringAndSize(serialized_pb.get(), &str, &len) < 0) {
- GOOGLE_LOG(ERROR)
- << "DescriptorDatabase method did not return a FileDescriptorProto";
- PyErr_Print();
- return false;
- }
- FileDescriptorProto file_proto;
- if (!file_proto.ParseFromArray(str, len)) {
- GOOGLE_LOG(ERROR)
- << "DescriptorDatabase method did not return a FileDescriptorProto";
- return false;
- }
- *output = file_proto;
- return true;
- }
-}
-
-// Find a file by file name.
-bool PyDescriptorDatabase::FindFileByName(const string& filename,
- FileDescriptorProto* output) {
- ScopedPyObjectPtr py_descriptor(PyObject_CallMethod(
- py_database_, "FindFileByName", "s#", filename.c_str(), filename.size()));
- return GetFileDescriptorProto(py_descriptor.get(), output);
-}
-
-// Find the file that declares the given fully-qualified symbol name.
-bool PyDescriptorDatabase::FindFileContainingSymbol(
- const string& symbol_name, FileDescriptorProto* output) {
- ScopedPyObjectPtr py_descriptor(
- PyObject_CallMethod(py_database_, "FindFileContainingSymbol", "s#",
- symbol_name.c_str(), symbol_name.size()));
- return GetFileDescriptorProto(py_descriptor.get(), output);
-}
-
-// Find the file which defines an extension extending the given message type
-// with the given field number.
-// Python DescriptorDatabases are not required to implement this method.
-bool PyDescriptorDatabase::FindFileContainingExtension(
- const string& containing_type, int field_number,
- FileDescriptorProto* output) {
- ScopedPyObjectPtr py_method(
- PyObject_GetAttrString(py_database_, "FindFileContainingExtension"));
- if (py_method == NULL) {
- // This method is not implemented, returns without error.
- PyErr_Clear();
- return false;
- }
- ScopedPyObjectPtr py_descriptor(
- PyObject_CallFunction(py_method.get(), "s#i", containing_type.c_str(),
- containing_type.size(), field_number));
- return GetFileDescriptorProto(py_descriptor.get(), output);
-}
-
-} // namespace python
-} // namespace protobuf
-} // namespace google
diff --git a/python/google/protobuf/pyext/descriptor_database.h b/python/google/protobuf/pyext/descriptor_database.h
deleted file mode 100644
index fc71c4bc..00000000
--- a/python/google/protobuf/pyext/descriptor_database.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_DATABASE_H__
-#define GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_DATABASE_H__
-
-#include <Python.h>
-
-#include <google/protobuf/descriptor_database.h>
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-class PyDescriptorDatabase : public DescriptorDatabase {
- public:
- explicit PyDescriptorDatabase(PyObject* py_database);
- ~PyDescriptorDatabase();
-
- // Implement the abstract interface. All these functions fill the output
- // with a copy of FileDescriptorProto.
-
- // Find a file by file name.
- bool FindFileByName(const string& filename,
- FileDescriptorProto* output);
-
- // Find the file that declares the given fully-qualified symbol name.
- bool FindFileContainingSymbol(const string& symbol_name,
- FileDescriptorProto* output);
-
- // Find the file which defines an extension extending the given message type
- // with the given field number.
- // Containing_type must be a fully-qualified type name.
- // Python objects are not required to implement this method.
- bool FindFileContainingExtension(const string& containing_type,
- int field_number,
- FileDescriptorProto* output);
-
- private:
- // The python object that implements the database. The reference is owned.
- PyObject* py_database_;
-};
-
-} // namespace python
-} // namespace protobuf
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_DATABASE_H__
diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc
deleted file mode 100644
index cfd98690..00000000
--- a/python/google/protobuf/pyext/descriptor_pool.cc
+++ /dev/null
@@ -1,631 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Implements the DescriptorPool, which collects all descriptors.
-
-#include <Python.h>
-
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/dynamic_message.h>
-#include <google/protobuf/pyext/descriptor.h>
-#include <google/protobuf/pyext/descriptor_database.h>
-#include <google/protobuf/pyext/descriptor_pool.h>
-#include <google/protobuf/pyext/message.h>
-#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
-
-#if PY_MAJOR_VERSION >= 3
- #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
- #if PY_VERSION_HEX < 0x03030000
- #error "Python 3.0 - 3.2 are not supported."
- #endif
- #define PyString_AsStringAndSize(ob, charpp, sizep) \
- (PyUnicode_Check(ob)? \
- ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
- PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
-#endif
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-// A map to cache Python Pools per C++ pointer.
-// Pointers are not owned here, and belong to the PyDescriptorPool.
-static hash_map<const DescriptorPool*, PyDescriptorPool*> descriptor_pool_map;
-
-namespace cdescriptor_pool {
-
-// Create a Python DescriptorPool object, but does not fill the "pool"
-// attribute.
-static PyDescriptorPool* _CreateDescriptorPool() {
- PyDescriptorPool* cpool = PyObject_New(
- PyDescriptorPool, &PyDescriptorPool_Type);
- if (cpool == NULL) {
- return NULL;
- }
-
- cpool->underlay = NULL;
- cpool->database = NULL;
-
- DynamicMessageFactory* message_factory = new DynamicMessageFactory();
- // This option might be the default some day.
- message_factory->SetDelegateToGeneratedFactory(true);
- cpool->message_factory = message_factory;
-
- // TODO(amauryfa): Rewrite the SymbolDatabase in C so that it uses the same
- // storage.
- cpool->classes_by_descriptor =
- new PyDescriptorPool::ClassesByMessageMap();
- cpool->descriptor_options =
- new hash_map<const void*, PyObject *>();
-
- return cpool;
-}
-
-// Create a Python DescriptorPool, using the given pool as an underlay:
-// new messages will be added to a custom pool, not to the underlay.
-//
-// Ownership of the underlay is not transferred, its pointer should
-// stay alive.
-static PyDescriptorPool* PyDescriptorPool_NewWithUnderlay(
- const DescriptorPool* underlay) {
- PyDescriptorPool* cpool = _CreateDescriptorPool();
- if (cpool == NULL) {
- return NULL;
- }
- cpool->pool = new DescriptorPool(underlay);
- cpool->underlay = underlay;
-
- if (!descriptor_pool_map.insert(
- std::make_pair(cpool->pool, cpool)).second) {
- // Should never happen -- would indicate an internal error / bug.
- PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered");
- return NULL;
- }
-
- return cpool;
-}
-
-static PyDescriptorPool* PyDescriptorPool_NewWithDatabase(
- DescriptorDatabase* database) {
- PyDescriptorPool* cpool = _CreateDescriptorPool();
- if (cpool == NULL) {
- return NULL;
- }
- if (database != NULL) {
- cpool->pool = new DescriptorPool(database);
- cpool->database = database;
- } else {
- cpool->pool = new DescriptorPool();
- }
-
- if (!descriptor_pool_map.insert(std::make_pair(cpool->pool, cpool)).second) {
- // Should never happen -- would indicate an internal error / bug.
- PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered");
- return NULL;
- }
-
- return cpool;
-}
-
-// The public DescriptorPool constructor.
-static PyObject* New(PyTypeObject* type,
- PyObject* args, PyObject* kwargs) {
- static char* kwlist[] = {"descriptor_db", 0};
- PyObject* py_database = NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &py_database)) {
- return NULL;
- }
- DescriptorDatabase* database = NULL;
- if (py_database && py_database != Py_None) {
- database = new PyDescriptorDatabase(py_database);
- }
- return reinterpret_cast<PyObject*>(
- PyDescriptorPool_NewWithDatabase(database));
-}
-
-static void Dealloc(PyDescriptorPool* self) {
- typedef PyDescriptorPool::ClassesByMessageMap::iterator iterator;
- descriptor_pool_map.erase(self->pool);
- for (iterator it = self->classes_by_descriptor->begin();
- it != self->classes_by_descriptor->end(); ++it) {
- Py_DECREF(it->second);
- }
- delete self->classes_by_descriptor;
- for (hash_map<const void*, PyObject*>::iterator it =
- self->descriptor_options->begin();
- it != self->descriptor_options->end(); ++it) {
- Py_DECREF(it->second);
- }
- delete self->descriptor_options;
- delete self->message_factory;
- delete self->database;
- delete self->pool;
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
-}
-
-PyObject* FindMessageByName(PyDescriptorPool* self, PyObject* arg) {
- Py_ssize_t name_size;
- char* name;
- if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
- return NULL;
- }
-
- const Descriptor* message_descriptor =
- self->pool->FindMessageTypeByName(string(name, name_size));
-
- if (message_descriptor == NULL) {
- PyErr_Format(PyExc_KeyError, "Couldn't find message %.200s", name);
- return NULL;
- }
-
- return PyMessageDescriptor_FromDescriptor(message_descriptor);
-}
-
-// Add a message class to our database.
-int RegisterMessageClass(PyDescriptorPool* self,
- const Descriptor* message_descriptor,
- CMessageClass* message_class) {
- Py_INCREF(message_class);
- typedef PyDescriptorPool::ClassesByMessageMap::iterator iterator;
- std::pair<iterator, bool> ret = self->classes_by_descriptor->insert(
- std::make_pair(message_descriptor, message_class));
- if (!ret.second) {
- // Update case: DECREF the previous value.
- Py_DECREF(ret.first->second);
- ret.first->second = message_class;
- }
- return 0;
-}
-
-// Retrieve the message class added to our database.
-CMessageClass* GetMessageClass(PyDescriptorPool* self,
- const Descriptor* message_descriptor) {
- typedef PyDescriptorPool::ClassesByMessageMap::iterator iterator;
- iterator ret = self->classes_by_descriptor->find(message_descriptor);
- if (ret == self->classes_by_descriptor->end()) {
- PyErr_Format(PyExc_TypeError, "No message class registered for '%s'",
- message_descriptor->full_name().c_str());
- return NULL;
- } else {
- return ret->second;
- }
-}
-
-PyObject* FindFileByName(PyDescriptorPool* self, PyObject* arg) {
- Py_ssize_t name_size;
- char* name;
- if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
- return NULL;
- }
-
- const FileDescriptor* file_descriptor =
- self->pool->FindFileByName(string(name, name_size));
- if (file_descriptor == NULL) {
- PyErr_Format(PyExc_KeyError, "Couldn't find file %.200s",
- name);
- return NULL;
- }
-
- return PyFileDescriptor_FromDescriptor(file_descriptor);
-}
-
-PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* arg) {
- Py_ssize_t name_size;
- char* name;
- if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
- return NULL;
- }
-
- const FieldDescriptor* field_descriptor =
- self->pool->FindFieldByName(string(name, name_size));
- if (field_descriptor == NULL) {
- PyErr_Format(PyExc_KeyError, "Couldn't find field %.200s",
- name);
- return NULL;
- }
-
- return PyFieldDescriptor_FromDescriptor(field_descriptor);
-}
-
-PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) {
- Py_ssize_t name_size;
- char* name;
- if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
- return NULL;
- }
-
- const FieldDescriptor* field_descriptor =
- self->pool->FindExtensionByName(string(name, name_size));
- if (field_descriptor == NULL) {
- PyErr_Format(PyExc_KeyError, "Couldn't find extension field %.200s", name);
- return NULL;
- }
-
- return PyFieldDescriptor_FromDescriptor(field_descriptor);
-}
-
-PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) {
- Py_ssize_t name_size;
- char* name;
- if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
- return NULL;
- }
-
- const EnumDescriptor* enum_descriptor =
- self->pool->FindEnumTypeByName(string(name, name_size));
- if (enum_descriptor == NULL) {
- PyErr_Format(PyExc_KeyError, "Couldn't find enum %.200s", name);
- return NULL;
- }
-
- return PyEnumDescriptor_FromDescriptor(enum_descriptor);
-}
-
-PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) {
- Py_ssize_t name_size;
- char* name;
- if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
- return NULL;
- }
-
- const OneofDescriptor* oneof_descriptor =
- self->pool->FindOneofByName(string(name, name_size));
- if (oneof_descriptor == NULL) {
- PyErr_Format(PyExc_KeyError, "Couldn't find oneof %.200s", name);
- return NULL;
- }
-
- return PyOneofDescriptor_FromDescriptor(oneof_descriptor);
-}
-
-PyObject* FindServiceByName(PyDescriptorPool* self, PyObject* arg) {
- Py_ssize_t name_size;
- char* name;
- if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
- return NULL;
- }
-
- const ServiceDescriptor* service_descriptor =
- self->pool->FindServiceByName(string(name, name_size));
- if (service_descriptor == NULL) {
- PyErr_Format(PyExc_KeyError, "Couldn't find service %.200s", name);
- return NULL;
- }
-
- return PyServiceDescriptor_FromDescriptor(service_descriptor);
-}
-
-PyObject* FindMethodByName(PyDescriptorPool* self, PyObject* arg) {
- Py_ssize_t name_size;
- char* name;
- if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
- return NULL;
- }
-
- const MethodDescriptor* method_descriptor =
- self->pool->FindMethodByName(string(name, name_size));
- if (method_descriptor == NULL) {
- PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
- return NULL;
- }
-
- return PyMethodDescriptor_FromDescriptor(method_descriptor);
-}
-
-PyObject* FindFileContainingSymbol(PyDescriptorPool* self, PyObject* arg) {
- Py_ssize_t name_size;
- char* name;
- if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
- return NULL;
- }
-
- const FileDescriptor* file_descriptor =
- self->pool->FindFileContainingSymbol(string(name, name_size));
- if (file_descriptor == NULL) {
- PyErr_Format(PyExc_KeyError, "Couldn't find symbol %.200s", name);
- return NULL;
- }
-
- return PyFileDescriptor_FromDescriptor(file_descriptor);
-}
-
-// These functions should not exist -- the only valid way to create
-// descriptors is to call Add() or AddSerializedFile().
-// But these AddDescriptor() functions were created in Python and some people
-// call them, so we support them for now for compatibility.
-// However we do check that the existing descriptor already exists in the pool,
-// which appears to always be true for existing calls -- but then why do people
-// call a function that will just be a no-op?
-// TODO(amauryfa): Need to investigate further.
-
-PyObject* AddFileDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
- const FileDescriptor* file_descriptor =
- PyFileDescriptor_AsDescriptor(descriptor);
- if (!file_descriptor) {
- return NULL;
- }
- if (file_descriptor !=
- self->pool->FindFileByName(file_descriptor->name())) {
- PyErr_Format(PyExc_ValueError,
- "The file descriptor %s does not belong to this pool",
- file_descriptor->name().c_str());
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-PyObject* AddDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
- const Descriptor* message_descriptor =
- PyMessageDescriptor_AsDescriptor(descriptor);
- if (!message_descriptor) {
- return NULL;
- }
- if (message_descriptor !=
- self->pool->FindMessageTypeByName(message_descriptor->full_name())) {
- PyErr_Format(PyExc_ValueError,
- "The message descriptor %s does not belong to this pool",
- message_descriptor->full_name().c_str());
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-PyObject* AddEnumDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
- const EnumDescriptor* enum_descriptor =
- PyEnumDescriptor_AsDescriptor(descriptor);
- if (!enum_descriptor) {
- return NULL;
- }
- if (enum_descriptor !=
- self->pool->FindEnumTypeByName(enum_descriptor->full_name())) {
- PyErr_Format(PyExc_ValueError,
- "The enum descriptor %s does not belong to this pool",
- enum_descriptor->full_name().c_str());
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-// The code below loads new Descriptors from a serialized FileDescriptorProto.
-
-
-// Collects errors that occur during proto file building to allow them to be
-// propagated in the python exception instead of only living in ERROR logs.
-class BuildFileErrorCollector : public DescriptorPool::ErrorCollector {
- public:
- BuildFileErrorCollector() : error_message(""), had_errors(false) {}
-
- void AddError(const string& filename, const string& element_name,
- const Message* descriptor, ErrorLocation location,
- const string& message) {
- // Replicates the logging behavior that happens in the C++ implementation
- // when an error collector is not passed in.
- if (!had_errors) {
- error_message +=
- ("Invalid proto descriptor for file \"" + filename + "\":\n");
- had_errors = true;
- }
- // As this only happens on failure and will result in the program not
- // running at all, no effort is made to optimize this string manipulation.
- error_message += (" " + element_name + ": " + message + "\n");
- }
-
- string error_message;
- bool had_errors;
-};
-
-PyObject* AddSerializedFile(PyDescriptorPool* self, PyObject* serialized_pb) {
- char* message_type;
- Py_ssize_t message_len;
-
- if (self->database != NULL) {
- PyErr_SetString(
- PyExc_ValueError,
- "Cannot call Add on a DescriptorPool that uses a DescriptorDatabase. "
- "Add your file to the underlying database.");
- return NULL;
- }
-
- if (PyBytes_AsStringAndSize(serialized_pb, &message_type, &message_len) < 0) {
- return NULL;
- }
-
- FileDescriptorProto file_proto;
- if (!file_proto.ParseFromArray(message_type, message_len)) {
- PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!");
- return NULL;
- }
-
- // If the file was already part of a C++ library, all its descriptors are in
- // the underlying pool. No need to do anything else.
- const FileDescriptor* generated_file = NULL;
- if (self->underlay) {
- generated_file = self->underlay->FindFileByName(file_proto.name());
- }
- if (generated_file != NULL) {
- return PyFileDescriptor_FromDescriptorWithSerializedPb(
- generated_file, serialized_pb);
- }
-
- BuildFileErrorCollector error_collector;
- const FileDescriptor* descriptor =
- self->pool->BuildFileCollectingErrors(file_proto,
- &error_collector);
- if (descriptor == NULL) {
- PyErr_Format(PyExc_TypeError,
- "Couldn't build proto file into descriptor pool!\n%s",
- error_collector.error_message.c_str());
- return NULL;
- }
-
- return PyFileDescriptor_FromDescriptorWithSerializedPb(
- descriptor, serialized_pb);
-}
-
-PyObject* Add(PyDescriptorPool* self, PyObject* file_descriptor_proto) {
- ScopedPyObjectPtr serialized_pb(
- PyObject_CallMethod(file_descriptor_proto, "SerializeToString", NULL));
- if (serialized_pb == NULL) {
- return NULL;
- }
- return AddSerializedFile(self, serialized_pb.get());
-}
-
-static PyMethodDef Methods[] = {
- { "Add", (PyCFunction)Add, METH_O,
- "Adds the FileDescriptorProto and its types to this pool." },
- { "AddSerializedFile", (PyCFunction)AddSerializedFile, METH_O,
- "Adds a serialized FileDescriptorProto to this pool." },
-
- // TODO(amauryfa): Understand why the Python implementation differs from
- // this one, ask users to use another API and deprecate these functions.
- { "AddFileDescriptor", (PyCFunction)AddFileDescriptor, METH_O,
- "No-op. Add() must have been called before." },
- { "AddDescriptor", (PyCFunction)AddDescriptor, METH_O,
- "No-op. Add() must have been called before." },
- { "AddEnumDescriptor", (PyCFunction)AddEnumDescriptor, METH_O,
- "No-op. Add() must have been called before." },
-
- { "FindFileByName", (PyCFunction)FindFileByName, METH_O,
- "Searches for a file descriptor by its .proto name." },
- { "FindMessageTypeByName", (PyCFunction)FindMessageByName, METH_O,
- "Searches for a message descriptor by full name." },
- { "FindFieldByName", (PyCFunction)FindFieldByName, METH_O,
- "Searches for a field descriptor by full name." },
- { "FindExtensionByName", (PyCFunction)FindExtensionByName, METH_O,
- "Searches for extension descriptor by full name." },
- { "FindEnumTypeByName", (PyCFunction)FindEnumTypeByName, METH_O,
- "Searches for enum type descriptor by full name." },
- { "FindOneofByName", (PyCFunction)FindOneofByName, METH_O,
- "Searches for oneof descriptor by full name." },
- { "FindServiceByName", (PyCFunction)FindServiceByName, METH_O,
- "Searches for service descriptor by full name." },
- { "FindMethodByName", (PyCFunction)FindMethodByName, METH_O,
- "Searches for method descriptor by full name." },
-
- { "FindFileContainingSymbol", (PyCFunction)FindFileContainingSymbol, METH_O,
- "Gets the FileDescriptor containing the specified symbol." },
- {NULL}
-};
-
-} // namespace cdescriptor_pool
-
-PyTypeObject PyDescriptorPool_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".DescriptorPool", // tp_name
- sizeof(PyDescriptorPool), // tp_basicsize
- 0, // tp_itemsize
- (destructor)cdescriptor_pool::Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A Descriptor Pool", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- cdescriptor_pool::Methods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- 0, // tp_alloc
- cdescriptor_pool::New, // tp_new
- PyObject_Del, // tp_free
-};
-
-// This is the DescriptorPool which contains all the definitions from the
-// generated _pb2.py modules.
-static PyDescriptorPool* python_generated_pool = NULL;
-
-bool InitDescriptorPool() {
- if (PyType_Ready(&PyDescriptorPool_Type) < 0)
- return false;
-
- // The Pool of messages declared in Python libraries.
- // generated_pool() contains all messages already linked in C++ libraries, and
- // is used as underlay.
- python_generated_pool = cdescriptor_pool::PyDescriptorPool_NewWithUnderlay(
- DescriptorPool::generated_pool());
- if (python_generated_pool == NULL) {
- return false;
- }
- // Register this pool to be found for C++-generated descriptors.
- descriptor_pool_map.insert(
- std::make_pair(DescriptorPool::generated_pool(),
- python_generated_pool));
-
- return true;
-}
-
-// The default DescriptorPool used everywhere in this module.
-// Today it's the python_generated_pool.
-// TODO(amauryfa): Remove all usages of this function: the pool should be
-// derived from the context.
-PyDescriptorPool* GetDefaultDescriptorPool() {
- return python_generated_pool;
-}
-
-PyDescriptorPool* GetDescriptorPool_FromPool(const DescriptorPool* pool) {
- // Fast path for standard descriptors.
- if (pool == python_generated_pool->pool ||
- pool == DescriptorPool::generated_pool()) {
- return python_generated_pool;
- }
- hash_map<const DescriptorPool*, PyDescriptorPool*>::iterator it =
- descriptor_pool_map.find(pool);
- if (it == descriptor_pool_map.end()) {
- PyErr_SetString(PyExc_KeyError, "Unknown descriptor pool");
- return NULL;
- }
- return it->second;
-}
-
-} // namespace python
-} // namespace protobuf
-} // namespace google
diff --git a/python/google/protobuf/pyext/descriptor_pool.h b/python/google/protobuf/pyext/descriptor_pool.h
deleted file mode 100644
index 2a42c112..00000000
--- a/python/google/protobuf/pyext/descriptor_pool.h
+++ /dev/null
@@ -1,167 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_POOL_H__
-#define GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_POOL_H__
-
-#include <Python.h>
-
-#include <google/protobuf/stubs/hash.h>
-#include <google/protobuf/descriptor.h>
-
-namespace google {
-namespace protobuf {
-class MessageFactory;
-
-namespace python {
-
-// The (meta) type of all Messages classes.
-struct CMessageClass;
-
-// Wraps operations to the global DescriptorPool which contains information
-// about all messages and fields.
-//
-// There is normally one pool per process. We make it a Python object only
-// because it contains many Python references.
-// TODO(amauryfa): See whether such objects can appear in reference cycles, and
-// consider adding support for the cyclic GC.
-//
-// "Methods" that interacts with this DescriptorPool are in the cdescriptor_pool
-// namespace.
-typedef struct PyDescriptorPool {
- PyObject_HEAD
-
- // The C++ pool containing Descriptors.
- DescriptorPool* pool;
-
- // The C++ pool acting as an underlay. Can be NULL.
- // This pointer is not owned and must stay alive.
- const DescriptorPool* underlay;
-
- // The C++ descriptor database used to fetch unknown protos. Can be NULL.
- // This pointer is owned.
- const DescriptorDatabase* database;
-
- // DynamicMessageFactory used to create C++ instances of messages.
- // This object cache the descriptors that were used, so the DescriptorPool
- // needs to get rid of it before it can delete itself.
- //
- // Note: A C++ MessageFactory is different from the Python MessageFactory.
- // The C++ one creates messages, when the Python one creates classes.
- MessageFactory* message_factory;
-
- // Make our own mapping to retrieve Python classes from C++ descriptors.
- //
- // Descriptor pointers stored here are owned by the DescriptorPool above.
- // Python references to classes are owned by this PyDescriptorPool.
- typedef hash_map<const Descriptor*, CMessageClass*> ClassesByMessageMap;
- ClassesByMessageMap* classes_by_descriptor;
-
- // Cache the options for any kind of descriptor.
- // Descriptor pointers are owned by the DescriptorPool above.
- // Python objects are owned by the map.
- hash_map<const void*, PyObject*>* descriptor_options;
-} PyDescriptorPool;
-
-
-extern PyTypeObject PyDescriptorPool_Type;
-
-namespace cdescriptor_pool {
-
-// Looks up a message by name.
-// Returns a message Descriptor, or NULL if not found.
-const Descriptor* FindMessageTypeByName(PyDescriptorPool* self,
- const string& name);
-
-// Registers a new Python class for the given message descriptor.
-// On error, returns -1 with a Python exception set.
-int RegisterMessageClass(PyDescriptorPool* self,
- const Descriptor* message_descriptor,
- CMessageClass* message_class);
-
-// Retrieves the Python class registered with the given message descriptor.
-//
-// Returns a *borrowed* reference if found, otherwise returns NULL with an
-// exception set.
-CMessageClass* GetMessageClass(PyDescriptorPool* self,
- const Descriptor* message_descriptor);
-
-// The functions below are also exposed as methods of the DescriptorPool type.
-
-// Looks up a message by name. Returns a PyMessageDescriptor corresponding to
-// the field on success, or NULL on failure.
-//
-// Returns a new reference.
-PyObject* FindMessageByName(PyDescriptorPool* self, PyObject* name);
-
-// Looks up a field by name. Returns a PyFieldDescriptor corresponding to
-// the field on success, or NULL on failure.
-//
-// Returns a new reference.
-PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* name);
-
-// Looks up an extension by name. Returns a PyFieldDescriptor corresponding
-// to the field on success, or NULL on failure.
-//
-// Returns a new reference.
-PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg);
-
-// Looks up an enum type by name. Returns a PyEnumDescriptor corresponding
-// to the field on success, or NULL on failure.
-//
-// Returns a new reference.
-PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg);
-
-// Looks up a oneof by name. Returns a COneofDescriptor corresponding
-// to the oneof on success, or NULL on failure.
-//
-// Returns a new reference.
-PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg);
-
-} // namespace cdescriptor_pool
-
-// Retrieve the global descriptor pool owned by the _message module.
-// This is the one used by pb2.py generated modules.
-// Returns a *borrowed* reference.
-// "Default" pool used to register messages from _pb2.py modules.
-PyDescriptorPool* GetDefaultDescriptorPool();
-
-// Retrieve the python descriptor pool owning a C++ descriptor pool.
-// Returns a *borrowed* reference.
-PyDescriptorPool* GetDescriptorPool_FromPool(const DescriptorPool* pool);
-
-// Initialize objects used by this module.
-bool InitDescriptorPool();
-
-} // namespace python
-} // namespace protobuf
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_POOL_H__
diff --git a/python/google/protobuf/pyext/extension_dict.cc b/python/google/protobuf/pyext/extension_dict.cc
deleted file mode 100644
index 21bbb8c2..00000000
--- a/python/google/protobuf/pyext/extension_dict.cc
+++ /dev/null
@@ -1,337 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: anuraag@google.com (Anuraag Agrawal)
-// Author: tibell@google.com (Johan Tibell)
-
-#include <google/protobuf/pyext/extension_dict.h>
-
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/dynamic_message.h>
-#include <google/protobuf/message.h>
-#include <google/protobuf/pyext/descriptor.h>
-#include <google/protobuf/pyext/descriptor_pool.h>
-#include <google/protobuf/pyext/message.h>
-#include <google/protobuf/pyext/repeated_composite_container.h>
-#include <google/protobuf/pyext/repeated_scalar_container.h>
-#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
-#include <google/protobuf/stubs/shared_ptr.h>
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-namespace extension_dict {
-
-PyObject* len(ExtensionDict* self) {
-#if PY_MAJOR_VERSION >= 3
- return PyLong_FromLong(PyDict_Size(self->values));
-#else
- return PyInt_FromLong(PyDict_Size(self->values));
-#endif
-}
-
-// TODO(tibell): Use VisitCompositeField.
-int ReleaseExtension(ExtensionDict* self,
- PyObject* extension,
- const FieldDescriptor* descriptor) {
- if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
- if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- if (repeated_composite_container::Release(
- reinterpret_cast<RepeatedCompositeContainer*>(
- extension)) < 0) {
- return -1;
- }
- } else {
- if (repeated_scalar_container::Release(
- reinterpret_cast<RepeatedScalarContainer*>(
- extension)) < 0) {
- return -1;
- }
- }
- } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- if (cmessage::ReleaseSubMessage(
- self->parent, descriptor,
- reinterpret_cast<CMessage*>(extension)) < 0) {
- return -1;
- }
- }
-
- return 0;
-}
-
-PyObject* subscript(ExtensionDict* self, PyObject* key) {
- const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key);
- if (descriptor == NULL) {
- return NULL;
- }
- if (!CheckFieldBelongsToMessage(descriptor, self->message)) {
- return NULL;
- }
-
- if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
- descriptor->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
- return cmessage::InternalGetScalar(self->message, descriptor);
- }
-
- PyObject* value = PyDict_GetItem(self->values, key);
- if (value != NULL) {
- Py_INCREF(value);
- return value;
- }
-
- if (self->parent == NULL) {
- // We are in "detached" state. Don't allow further modifications.
- // TODO(amauryfa): Support adding non-scalars to a detached extension dict.
- // This probably requires to store the type of the main message.
- PyErr_SetObject(PyExc_KeyError, key);
- return NULL;
- }
-
- if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
- descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- PyObject* sub_message = cmessage::InternalGetSubMessage(
- self->parent, descriptor);
- if (sub_message == NULL) {
- return NULL;
- }
- PyDict_SetItem(self->values, key, sub_message);
- return sub_message;
- }
-
- if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
- if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- CMessageClass* message_class = cdescriptor_pool::GetMessageClass(
- cmessage::GetDescriptorPoolForMessage(self->parent),
- descriptor->message_type());
- if (message_class == NULL) {
- return NULL;
- }
- PyObject* py_container = repeated_composite_container::NewContainer(
- self->parent, descriptor, message_class);
- if (py_container == NULL) {
- return NULL;
- }
- PyDict_SetItem(self->values, key, py_container);
- return py_container;
- } else {
- PyObject* py_container = repeated_scalar_container::NewContainer(
- self->parent, descriptor);
- if (py_container == NULL) {
- return NULL;
- }
- PyDict_SetItem(self->values, key, py_container);
- return py_container;
- }
- }
- PyErr_SetString(PyExc_ValueError, "control reached unexpected line");
- return NULL;
-}
-
-int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value) {
- const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key);
- if (descriptor == NULL) {
- return -1;
- }
- if (!CheckFieldBelongsToMessage(descriptor, self->message)) {
- return -1;
- }
-
- if (descriptor->label() != FieldDescriptor::LABEL_OPTIONAL ||
- descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- PyErr_SetString(PyExc_TypeError, "Extension is repeated and/or composite "
- "type");
- return -1;
- }
- if (self->parent) {
- cmessage::AssureWritable(self->parent);
- if (cmessage::InternalSetScalar(self->parent, descriptor, value) < 0) {
- return -1;
- }
- }
- // TODO(tibell): We shouldn't write scalars to the cache.
- PyDict_SetItem(self->values, key, value);
- return 0;
-}
-
-PyObject* ClearExtension(ExtensionDict* self, PyObject* extension) {
- const FieldDescriptor* descriptor =
- cmessage::GetExtensionDescriptor(extension);
- if (descriptor == NULL) {
- return NULL;
- }
- PyObject* value = PyDict_GetItem(self->values, extension);
- if (self->parent) {
- if (value != NULL) {
- if (ReleaseExtension(self, value, descriptor) < 0) {
- return NULL;
- }
- }
- if (ScopedPyObjectPtr(cmessage::ClearFieldByDescriptor(
- self->parent, descriptor)) == NULL) {
- return NULL;
- }
- }
- if (PyDict_DelItem(self->values, extension) < 0) {
- PyErr_Clear();
- }
- Py_RETURN_NONE;
-}
-
-PyObject* HasExtension(ExtensionDict* self, PyObject* extension) {
- const FieldDescriptor* descriptor =
- cmessage::GetExtensionDescriptor(extension);
- if (descriptor == NULL) {
- return NULL;
- }
- if (self->parent) {
- return cmessage::HasFieldByDescriptor(self->parent, descriptor);
- } else {
- int exists = PyDict_Contains(self->values, extension);
- if (exists < 0) {
- return NULL;
- }
- return PyBool_FromLong(exists);
- }
-}
-
-PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* name) {
- ScopedPyObjectPtr extensions_by_name(PyObject_GetAttrString(
- reinterpret_cast<PyObject*>(self->parent), "_extensions_by_name"));
- if (extensions_by_name == NULL) {
- return NULL;
- }
- PyObject* result = PyDict_GetItem(extensions_by_name.get(), name);
- if (result == NULL) {
- Py_RETURN_NONE;
- } else {
- Py_INCREF(result);
- return result;
- }
-}
-
-PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* number) {
- ScopedPyObjectPtr extensions_by_number(PyObject_GetAttrString(
- reinterpret_cast<PyObject*>(self->parent), "_extensions_by_number"));
- if (extensions_by_number == NULL) {
- return NULL;
- }
- PyObject* result = PyDict_GetItem(extensions_by_number.get(), number);
- if (result == NULL) {
- Py_RETURN_NONE;
- } else {
- Py_INCREF(result);
- return result;
- }
-}
-
-ExtensionDict* NewExtensionDict(CMessage *parent) {
- ExtensionDict* self = reinterpret_cast<ExtensionDict*>(
- PyType_GenericAlloc(&ExtensionDict_Type, 0));
- if (self == NULL) {
- return NULL;
- }
-
- self->parent = parent; // Store a borrowed reference.
- self->message = parent->message;
- self->owner = parent->owner;
- self->values = PyDict_New();
- return self;
-}
-
-void dealloc(ExtensionDict* self) {
- Py_CLEAR(self->values);
- self->owner.reset();
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
-}
-
-static PyMappingMethods MpMethods = {
- (lenfunc)len, /* mp_length */
- (binaryfunc)subscript, /* mp_subscript */
- (objobjargproc)ass_subscript,/* mp_ass_subscript */
-};
-
-#define EDMETHOD(name, args, doc) { #name, (PyCFunction)name, args, doc }
-static PyMethodDef Methods[] = {
- EDMETHOD(ClearExtension, METH_O, "Clears an extension from the object."),
- EDMETHOD(HasExtension, METH_O, "Checks if the object has an extension."),
- EDMETHOD(_FindExtensionByName, METH_O,
- "Finds an extension by name."),
- EDMETHOD(_FindExtensionByNumber, METH_O,
- "Finds an extension by field number."),
- { NULL, NULL }
-};
-
-} // namespace extension_dict
-
-PyTypeObject ExtensionDict_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".ExtensionDict", // tp_name
- sizeof(ExtensionDict), // tp_basicsize
- 0, // tp_itemsize
- (destructor)extension_dict::dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- &extension_dict::MpMethods, // tp_as_mapping
- PyObject_HashNotImplemented, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "An extension dict", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- extension_dict::Methods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
-};
-
-} // namespace python
-} // namespace protobuf
-} // namespace google
diff --git a/python/google/protobuf/pyext/extension_dict.h b/python/google/protobuf/pyext/extension_dict.h
deleted file mode 100644
index 2456eda1..00000000
--- a/python/google/protobuf/pyext/extension_dict.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: anuraag@google.com (Anuraag Agrawal)
-// Author: tibell@google.com (Johan Tibell)
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_EXTENSION_DICT_H__
-#define GOOGLE_PROTOBUF_PYTHON_CPP_EXTENSION_DICT_H__
-
-#include <Python.h>
-
-#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
-
-namespace google {
-namespace protobuf {
-
-class Message;
-class FieldDescriptor;
-
-#ifdef _SHARED_PTR_H
-using std::shared_ptr;
-#else
-using internal::shared_ptr;
-#endif
-
-namespace python {
-
-struct CMessage;
-
-typedef struct ExtensionDict {
- PyObject_HEAD;
-
- // This is the top-level C++ Message object that owns the whole
- // proto tree. Every Python container class holds a
- // reference to it in order to keep it alive as long as there's a
- // Python object that references any part of the tree.
- shared_ptr<Message> owner;
-
- // Weak reference to parent message. Used to make sure
- // the parent is writable when an extension field is modified.
- CMessage* parent;
-
- // Pointer to the C++ Message that this ExtensionDict extends.
- // Not owned by us.
- Message* message;
-
- // A dict of child messages, indexed by Extension descriptors.
- // Similar to CMessage::composite_fields.
- PyObject* values;
-} ExtensionDict;
-
-extern PyTypeObject ExtensionDict_Type;
-
-namespace extension_dict {
-
-// Builds an Extensions dict for a specific message.
-ExtensionDict* NewExtensionDict(CMessage *parent);
-
-// Gets the number of extension values in this ExtensionDict as a python object.
-//
-// Returns a new reference.
-PyObject* len(ExtensionDict* self);
-
-// Releases extensions referenced outside this dictionary to keep outside
-// references alive.
-//
-// Returns 0 on success, -1 on failure.
-int ReleaseExtension(ExtensionDict* self,
- PyObject* extension,
- const FieldDescriptor* descriptor);
-
-// Gets an extension from the dict for the given extension descriptor.
-//
-// Returns a new reference.
-PyObject* subscript(ExtensionDict* self, PyObject* key);
-
-// Assigns a value to an extension in the dict. Can only be used for singular
-// simple types.
-//
-// Returns 0 on success, -1 on failure.
-int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value);
-
-// Clears an extension from the dict. Will release the extension if there
-// is still an external reference left to it.
-//
-// Returns None on success.
-PyObject* ClearExtension(ExtensionDict* self,
- PyObject* extension);
-
-// Gets an extension from the dict given the extension name as opposed to
-// descriptor.
-//
-// Returns a new reference.
-PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* name);
-
-// Gets an extension from the dict given the extension field number as
-// opposed to descriptor.
-//
-// Returns a new reference.
-PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* number);
-
-} // namespace extension_dict
-} // namespace python
-} // namespace protobuf
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_CPP_EXTENSION_DICT_H__
diff --git a/python/google/protobuf/pyext/map_container.cc b/python/google/protobuf/pyext/map_container.cc
deleted file mode 100644
index 90438df1..00000000
--- a/python/google/protobuf/pyext/map_container.cc
+++ /dev/null
@@ -1,969 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: haberman@google.com (Josh Haberman)
-
-#include <google/protobuf/pyext/map_container.h>
-
-#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
-
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/map_field.h>
-#include <google/protobuf/map.h>
-#include <google/protobuf/message.h>
-#include <google/protobuf/pyext/message.h>
-#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
-
-#if PY_MAJOR_VERSION >= 3
- #define PyInt_FromLong PyLong_FromLong
- #define PyInt_FromSize_t PyLong_FromSize_t
-#endif
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-// Functions that need access to map reflection functionality.
-// They need to be contained in this class because it is friended.
-class MapReflectionFriend {
- public:
- // Methods that are in common between the map types.
- static PyObject* Contains(PyObject* _self, PyObject* key);
- static Py_ssize_t Length(PyObject* _self);
- static PyObject* GetIterator(PyObject *_self);
- static PyObject* IterNext(PyObject* _self);
-
- // Methods that differ between the map types.
- static PyObject* ScalarMapGetItem(PyObject* _self, PyObject* key);
- static PyObject* MessageMapGetItem(PyObject* _self, PyObject* key);
- static int ScalarMapSetItem(PyObject* _self, PyObject* key, PyObject* v);
- static int MessageMapSetItem(PyObject* _self, PyObject* key, PyObject* v);
-};
-
-struct MapIterator {
- PyObject_HEAD;
-
- google::protobuf::scoped_ptr< ::google::protobuf::MapIterator> iter;
-
- // A pointer back to the container, so we can notice changes to the version.
- // We own a ref on this.
- MapContainer* container;
-
- // We need to keep a ref on the Message* too, because
- // MapIterator::~MapIterator() accesses it. Normally this would be ok because
- // the ref on container (above) would guarantee outlive semantics. However in
- // the case of ClearField(), InitializeAndCopyToParentContainer() resets the
- // message pointer (and the owner) to a different message, a copy of the
- // original. But our iterator still points to the original, which could now
- // get deleted before us.
- //
- // To prevent this, we ensure that the Message will always stay alive as long
- // as this iterator does. This is solely for the benefit of the MapIterator
- // destructor -- we should never actually access the iterator in this state
- // except to delete it.
- shared_ptr<Message> owner;
-
- // The version of the map when we took the iterator to it.
- //
- // We store this so that if the map is modified during iteration we can throw
- // an error.
- uint64 version;
-
- // True if the container is empty. We signal this separately to avoid calling
- // any of the iteration methods, which are non-const.
- bool empty;
-};
-
-Message* MapContainer::GetMutableMessage() {
- cmessage::AssureWritable(parent);
- return const_cast<Message*>(message);
-}
-
-// Consumes a reference on the Python string object.
-static bool PyStringToSTL(PyObject* py_string, string* stl_string) {
- char *value;
- Py_ssize_t value_len;
-
- if (!py_string) {
- return false;
- }
- if (PyBytes_AsStringAndSize(py_string, &value, &value_len) < 0) {
- Py_DECREF(py_string);
- return false;
- } else {
- stl_string->assign(value, value_len);
- Py_DECREF(py_string);
- return true;
- }
-}
-
-static bool PythonToMapKey(PyObject* obj,
- const FieldDescriptor* field_descriptor,
- MapKey* key) {
- switch (field_descriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32: {
- GOOGLE_CHECK_GET_INT32(obj, value, false);
- key->SetInt32Value(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_INT64: {
- GOOGLE_CHECK_GET_INT64(obj, value, false);
- key->SetInt64Value(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT32: {
- GOOGLE_CHECK_GET_UINT32(obj, value, false);
- key->SetUInt32Value(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT64: {
- GOOGLE_CHECK_GET_UINT64(obj, value, false);
- key->SetUInt64Value(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_BOOL: {
- GOOGLE_CHECK_GET_BOOL(obj, value, false);
- key->SetBoolValue(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- string str;
- if (!PyStringToSTL(CheckString(obj, field_descriptor), &str)) {
- return false;
- }
- key->SetStringValue(str);
- break;
- }
- default:
- PyErr_Format(
- PyExc_SystemError, "Type %d cannot be a map key",
- field_descriptor->cpp_type());
- return false;
- }
- return true;
-}
-
-static PyObject* MapKeyToPython(const FieldDescriptor* field_descriptor,
- const MapKey& key) {
- switch (field_descriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
- return PyInt_FromLong(key.GetInt32Value());
- case FieldDescriptor::CPPTYPE_INT64:
- return PyLong_FromLongLong(key.GetInt64Value());
- case FieldDescriptor::CPPTYPE_UINT32:
- return PyInt_FromSize_t(key.GetUInt32Value());
- case FieldDescriptor::CPPTYPE_UINT64:
- return PyLong_FromUnsignedLongLong(key.GetUInt64Value());
- case FieldDescriptor::CPPTYPE_BOOL:
- return PyBool_FromLong(key.GetBoolValue());
- case FieldDescriptor::CPPTYPE_STRING:
- return ToStringObject(field_descriptor, key.GetStringValue());
- default:
- PyErr_Format(
- PyExc_SystemError, "Couldn't convert type %d to value",
- field_descriptor->cpp_type());
- return NULL;
- }
-}
-
-// This is only used for ScalarMap, so we don't need to handle the
-// CPPTYPE_MESSAGE case.
-PyObject* MapValueRefToPython(const FieldDescriptor* field_descriptor,
- MapValueRef* value) {
- switch (field_descriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
- return PyInt_FromLong(value->GetInt32Value());
- case FieldDescriptor::CPPTYPE_INT64:
- return PyLong_FromLongLong(value->GetInt64Value());
- case FieldDescriptor::CPPTYPE_UINT32:
- return PyInt_FromSize_t(value->GetUInt32Value());
- case FieldDescriptor::CPPTYPE_UINT64:
- return PyLong_FromUnsignedLongLong(value->GetUInt64Value());
- case FieldDescriptor::CPPTYPE_FLOAT:
- return PyFloat_FromDouble(value->GetFloatValue());
- case FieldDescriptor::CPPTYPE_DOUBLE:
- return PyFloat_FromDouble(value->GetDoubleValue());
- case FieldDescriptor::CPPTYPE_BOOL:
- return PyBool_FromLong(value->GetBoolValue());
- case FieldDescriptor::CPPTYPE_STRING:
- return ToStringObject(field_descriptor, value->GetStringValue());
- case FieldDescriptor::CPPTYPE_ENUM:
- return PyInt_FromLong(value->GetEnumValue());
- default:
- PyErr_Format(
- PyExc_SystemError, "Couldn't convert type %d to value",
- field_descriptor->cpp_type());
- return NULL;
- }
-}
-
-// This is only used for ScalarMap, so we don't need to handle the
-// CPPTYPE_MESSAGE case.
-static bool PythonToMapValueRef(PyObject* obj,
- const FieldDescriptor* field_descriptor,
- bool allow_unknown_enum_values,
- MapValueRef* value_ref) {
- switch (field_descriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32: {
- GOOGLE_CHECK_GET_INT32(obj, value, false);
- value_ref->SetInt32Value(value);
- return true;
- }
- case FieldDescriptor::CPPTYPE_INT64: {
- GOOGLE_CHECK_GET_INT64(obj, value, false);
- value_ref->SetInt64Value(value);
- return true;
- }
- case FieldDescriptor::CPPTYPE_UINT32: {
- GOOGLE_CHECK_GET_UINT32(obj, value, false);
- value_ref->SetUInt32Value(value);
- return true;
- }
- case FieldDescriptor::CPPTYPE_UINT64: {
- GOOGLE_CHECK_GET_UINT64(obj, value, false);
- value_ref->SetUInt64Value(value);
- return true;
- }
- case FieldDescriptor::CPPTYPE_FLOAT: {
- GOOGLE_CHECK_GET_FLOAT(obj, value, false);
- value_ref->SetFloatValue(value);
- return true;
- }
- case FieldDescriptor::CPPTYPE_DOUBLE: {
- GOOGLE_CHECK_GET_DOUBLE(obj, value, false);
- value_ref->SetDoubleValue(value);
- return true;
- }
- case FieldDescriptor::CPPTYPE_BOOL: {
- GOOGLE_CHECK_GET_BOOL(obj, value, false);
- value_ref->SetBoolValue(value);
- return true;;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- string str;
- if (!PyStringToSTL(CheckString(obj, field_descriptor), &str)) {
- return false;
- }
- value_ref->SetStringValue(str);
- return true;
- }
- case FieldDescriptor::CPPTYPE_ENUM: {
- GOOGLE_CHECK_GET_INT32(obj, value, false);
- if (allow_unknown_enum_values) {
- value_ref->SetEnumValue(value);
- return true;
- } else {
- const EnumDescriptor* enum_descriptor = field_descriptor->enum_type();
- const EnumValueDescriptor* enum_value =
- enum_descriptor->FindValueByNumber(value);
- if (enum_value != NULL) {
- value_ref->SetEnumValue(value);
- return true;
- } else {
- PyErr_Format(PyExc_ValueError, "Unknown enum value: %d", value);
- return false;
- }
- }
- break;
- }
- default:
- PyErr_Format(
- PyExc_SystemError, "Setting value to a field of unknown type %d",
- field_descriptor->cpp_type());
- return false;
- }
-}
-
-// Map methods common to ScalarMap and MessageMap //////////////////////////////
-
-static MapContainer* GetMap(PyObject* obj) {
- return reinterpret_cast<MapContainer*>(obj);
-}
-
-Py_ssize_t MapReflectionFriend::Length(PyObject* _self) {
- MapContainer* self = GetMap(_self);
- const google::protobuf::Message* message = self->message;
- return message->GetReflection()->MapSize(*message,
- self->parent_field_descriptor);
-}
-
-PyObject* Clear(PyObject* _self) {
- MapContainer* self = GetMap(_self);
- Message* message = self->GetMutableMessage();
- const Reflection* reflection = message->GetReflection();
-
- reflection->ClearField(message, self->parent_field_descriptor);
-
- Py_RETURN_NONE;
-}
-
-PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) {
- MapContainer* self = GetMap(_self);
-
- const Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
- MapKey map_key;
-
- if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) {
- return NULL;
- }
-
- if (reflection->ContainsMapKey(*message, self->parent_field_descriptor,
- map_key)) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-// Initializes the underlying Message object of "to" so it becomes a new parent
-// repeated scalar, and copies all the values from "from" to it. A child scalar
-// container can be released by passing it as both from and to (e.g. making it
-// the recipient of the new parent message and copying the values from itself).
-static int InitializeAndCopyToParentContainer(MapContainer* from,
- MapContainer* to) {
- // For now we require from == to, re-evaluate if we want to support deep copy
- // as in repeated_scalar_container.cc.
- GOOGLE_DCHECK(from == to);
- Message* new_message = from->message->New();
-
- if (MapReflectionFriend::Length(reinterpret_cast<PyObject*>(from)) > 0) {
- // A somewhat roundabout way of copying just one field from old_message to
- // new_message. This is the best we can do with what Reflection gives us.
- Message* mutable_old = from->GetMutableMessage();
- vector<const FieldDescriptor*> fields;
- fields.push_back(from->parent_field_descriptor);
-
- // Move the map field into the new message.
- mutable_old->GetReflection()->SwapFields(mutable_old, new_message, fields);
-
- // If/when we support from != to, this will be required also to copy the
- // map field back into the existing message:
- // mutable_old->MergeFrom(*new_message);
- }
-
- // If from == to this could delete old_message.
- to->owner.reset(new_message);
-
- to->parent = NULL;
- to->parent_field_descriptor = from->parent_field_descriptor;
- to->message = new_message;
-
- // Invalidate iterators, since they point to the old copy of the field.
- to->version++;
-
- return 0;
-}
-
-int MapContainer::Release() {
- return InitializeAndCopyToParentContainer(this, this);
-}
-
-
-// ScalarMap ///////////////////////////////////////////////////////////////////
-
-PyObject *NewScalarMapContainer(
- CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_descriptor) {
- if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) {
- return NULL;
- }
-
-#if PY_MAJOR_VERSION >= 3
- ScopedPyObjectPtr obj(PyType_GenericAlloc(
- reinterpret_cast<PyTypeObject *>(ScalarMapContainer_Type), 0));
-#else
- ScopedPyObjectPtr obj(PyType_GenericAlloc(&ScalarMapContainer_Type, 0));
-#endif
- if (obj.get() == NULL) {
- return PyErr_Format(PyExc_RuntimeError,
- "Could not allocate new container.");
- }
-
- MapContainer* self = GetMap(obj.get());
-
- self->message = parent->message;
- self->parent = parent;
- self->parent_field_descriptor = parent_field_descriptor;
- self->owner = parent->owner;
- self->version = 0;
-
- self->key_field_descriptor =
- parent_field_descriptor->message_type()->FindFieldByName("key");
- self->value_field_descriptor =
- parent_field_descriptor->message_type()->FindFieldByName("value");
-
- if (self->key_field_descriptor == NULL ||
- self->value_field_descriptor == NULL) {
- return PyErr_Format(PyExc_KeyError,
- "Map entry descriptor did not have key/value fields");
- }
-
- return obj.release();
-}
-
-PyObject* MapReflectionFriend::ScalarMapGetItem(PyObject* _self,
- PyObject* key) {
- MapContainer* self = GetMap(_self);
-
- Message* message = self->GetMutableMessage();
- const Reflection* reflection = message->GetReflection();
- MapKey map_key;
- MapValueRef value;
-
- if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) {
- return NULL;
- }
-
- if (reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor,
- map_key, &value)) {
- self->version++;
- }
-
- return MapValueRefToPython(self->value_field_descriptor, &value);
-}
-
-int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key,
- PyObject* v) {
- MapContainer* self = GetMap(_self);
-
- Message* message = self->GetMutableMessage();
- const Reflection* reflection = message->GetReflection();
- MapKey map_key;
- MapValueRef value;
-
- if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) {
- return -1;
- }
-
- self->version++;
-
- if (v) {
- // Set item to v.
- reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor,
- map_key, &value);
-
- return PythonToMapValueRef(v, self->value_field_descriptor,
- reflection->SupportsUnknownEnumValues(), &value)
- ? 0
- : -1;
- } else {
- // Delete key from map.
- if (reflection->DeleteMapValue(message, self->parent_field_descriptor,
- map_key)) {
- return 0;
- } else {
- PyErr_Format(PyExc_KeyError, "Key not present in map");
- return -1;
- }
- }
-}
-
-static PyObject* ScalarMapGet(PyObject* self, PyObject* args) {
- PyObject* key;
- PyObject* default_value = NULL;
- if (PyArg_ParseTuple(args, "O|O", &key, &default_value) < 0) {
- return NULL;
- }
-
- ScopedPyObjectPtr is_present(MapReflectionFriend::Contains(self, key));
- if (is_present.get() == NULL) {
- return NULL;
- }
-
- if (PyObject_IsTrue(is_present.get())) {
- return MapReflectionFriend::ScalarMapGetItem(self, key);
- } else {
- if (default_value != NULL) {
- Py_INCREF(default_value);
- return default_value;
- } else {
- Py_RETURN_NONE;
- }
- }
-}
-
-static void ScalarMapDealloc(PyObject* _self) {
- MapContainer* self = GetMap(_self);
- self->owner.reset();
- Py_TYPE(_self)->tp_free(_self);
-}
-
-static PyMethodDef ScalarMapMethods[] = {
- { "__contains__", MapReflectionFriend::Contains, METH_O,
- "Tests whether a key is a member of the map." },
- { "clear", (PyCFunction)Clear, METH_NOARGS,
- "Removes all elements from the map." },
- { "get", ScalarMapGet, METH_VARARGS,
- "Gets the value for the given key if present, or otherwise a default" },
- /*
- { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
- "Makes a deep copy of the class." },
- { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
- "Outputs picklable representation of the repeated field." },
- */
- {NULL, NULL},
-};
-
-#if PY_MAJOR_VERSION >= 3
- static PyType_Slot ScalarMapContainer_Type_slots[] = {
- {Py_tp_dealloc, (void *)ScalarMapDealloc},
- {Py_mp_length, (void *)MapReflectionFriend::Length},
- {Py_mp_subscript, (void *)MapReflectionFriend::ScalarMapGetItem},
- {Py_mp_ass_subscript, (void *)MapReflectionFriend::ScalarMapSetItem},
- {Py_tp_methods, (void *)ScalarMapMethods},
- {Py_tp_iter, (void *)MapReflectionFriend::GetIterator},
- {0, 0},
- };
-
- PyType_Spec ScalarMapContainer_Type_spec = {
- FULL_MODULE_NAME ".ScalarMapContainer",
- sizeof(MapContainer),
- 0,
- Py_TPFLAGS_DEFAULT,
- ScalarMapContainer_Type_slots
- };
- PyObject *ScalarMapContainer_Type;
-#else
- static PyMappingMethods ScalarMapMappingMethods = {
- MapReflectionFriend::Length, // mp_length
- MapReflectionFriend::ScalarMapGetItem, // mp_subscript
- MapReflectionFriend::ScalarMapSetItem, // mp_ass_subscript
- };
-
- PyTypeObject ScalarMapContainer_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".ScalarMapContainer", // tp_name
- sizeof(MapContainer), // tp_basicsize
- 0, // tp_itemsize
- ScalarMapDealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- &ScalarMapMappingMethods, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A scalar map container", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- MapReflectionFriend::GetIterator, // tp_iter
- 0, // tp_iternext
- ScalarMapMethods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- };
-#endif
-
-
-// MessageMap //////////////////////////////////////////////////////////////////
-
-static MessageMapContainer* GetMessageMap(PyObject* obj) {
- return reinterpret_cast<MessageMapContainer*>(obj);
-}
-
-static PyObject* GetCMessage(MessageMapContainer* self, Message* message) {
- // Get or create the CMessage object corresponding to this message.
- ScopedPyObjectPtr key(PyLong_FromVoidPtr(message));
- PyObject* ret = PyDict_GetItem(self->message_dict, key.get());
-
- if (ret == NULL) {
- CMessage* cmsg = cmessage::NewEmptyMessage(self->message_class);
- ret = reinterpret_cast<PyObject*>(cmsg);
-
- if (cmsg == NULL) {
- return NULL;
- }
- cmsg->owner = self->owner;
- cmsg->message = message;
- cmsg->parent = self->parent;
-
- if (PyDict_SetItem(self->message_dict, key.get(), ret) < 0) {
- Py_DECREF(ret);
- return NULL;
- }
- } else {
- Py_INCREF(ret);
- }
-
- return ret;
-}
-
-PyObject* NewMessageMapContainer(
- CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_descriptor,
- CMessageClass* message_class) {
- if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) {
- return NULL;
- }
-
-#if PY_MAJOR_VERSION >= 3
- PyObject* obj = PyType_GenericAlloc(
- reinterpret_cast<PyTypeObject *>(MessageMapContainer_Type), 0);
-#else
- PyObject* obj = PyType_GenericAlloc(&MessageMapContainer_Type, 0);
-#endif
- if (obj == NULL) {
- return PyErr_Format(PyExc_RuntimeError,
- "Could not allocate new container.");
- }
-
- MessageMapContainer* self = GetMessageMap(obj);
-
- self->message = parent->message;
- self->parent = parent;
- self->parent_field_descriptor = parent_field_descriptor;
- self->owner = parent->owner;
- self->version = 0;
-
- self->key_field_descriptor =
- parent_field_descriptor->message_type()->FindFieldByName("key");
- self->value_field_descriptor =
- parent_field_descriptor->message_type()->FindFieldByName("value");
-
- self->message_dict = PyDict_New();
- if (self->message_dict == NULL) {
- return PyErr_Format(PyExc_RuntimeError,
- "Could not allocate message dict.");
- }
-
- Py_INCREF(message_class);
- self->message_class = message_class;
-
- if (self->key_field_descriptor == NULL ||
- self->value_field_descriptor == NULL) {
- Py_DECREF(obj);
- return PyErr_Format(PyExc_KeyError,
- "Map entry descriptor did not have key/value fields");
- }
-
- return obj;
-}
-
-int MapReflectionFriend::MessageMapSetItem(PyObject* _self, PyObject* key,
- PyObject* v) {
- if (v) {
- PyErr_Format(PyExc_ValueError,
- "Direct assignment of submessage not allowed");
- return -1;
- }
-
- // Now we know that this is a delete, not a set.
-
- MessageMapContainer* self = GetMessageMap(_self);
- Message* message = self->GetMutableMessage();
- const Reflection* reflection = message->GetReflection();
- MapKey map_key;
- MapValueRef value;
-
- self->version++;
-
- if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) {
- return -1;
- }
-
- // Delete key from map.
- if (reflection->DeleteMapValue(message, self->parent_field_descriptor,
- map_key)) {
- return 0;
- } else {
- PyErr_Format(PyExc_KeyError, "Key not present in map");
- return -1;
- }
-}
-
-PyObject* MapReflectionFriend::MessageMapGetItem(PyObject* _self,
- PyObject* key) {
- MessageMapContainer* self = GetMessageMap(_self);
-
- Message* message = self->GetMutableMessage();
- const Reflection* reflection = message->GetReflection();
- MapKey map_key;
- MapValueRef value;
-
- if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) {
- return NULL;
- }
-
- if (reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor,
- map_key, &value)) {
- self->version++;
- }
-
- return GetCMessage(self, value.MutableMessageValue());
-}
-
-PyObject* MessageMapGet(PyObject* self, PyObject* args) {
- PyObject* key;
- PyObject* default_value = NULL;
- if (PyArg_ParseTuple(args, "O|O", &key, &default_value) < 0) {
- return NULL;
- }
-
- ScopedPyObjectPtr is_present(MapReflectionFriend::Contains(self, key));
- if (is_present.get() == NULL) {
- return NULL;
- }
-
- if (PyObject_IsTrue(is_present.get())) {
- return MapReflectionFriend::MessageMapGetItem(self, key);
- } else {
- if (default_value != NULL) {
- Py_INCREF(default_value);
- return default_value;
- } else {
- Py_RETURN_NONE;
- }
- }
-}
-
-static void MessageMapDealloc(PyObject* _self) {
- MessageMapContainer* self = GetMessageMap(_self);
- self->owner.reset();
- Py_DECREF(self->message_dict);
- Py_DECREF(self->message_class);
- Py_TYPE(_self)->tp_free(_self);
-}
-
-static PyMethodDef MessageMapMethods[] = {
- { "__contains__", (PyCFunction)MapReflectionFriend::Contains, METH_O,
- "Tests whether the map contains this element."},
- { "clear", (PyCFunction)Clear, METH_NOARGS,
- "Removes all elements from the map."},
- { "get", MessageMapGet, METH_VARARGS,
- "Gets the value for the given key if present, or otherwise a default" },
- { "get_or_create", MapReflectionFriend::MessageMapGetItem, METH_O,
- "Alias for getitem, useful to make explicit that the map is mutated." },
- /*
- { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
- "Makes a deep copy of the class." },
- { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
- "Outputs picklable representation of the repeated field." },
- */
- {NULL, NULL},
-};
-
-#if PY_MAJOR_VERSION >= 3
- static PyType_Slot MessageMapContainer_Type_slots[] = {
- {Py_tp_dealloc, (void *)MessageMapDealloc},
- {Py_mp_length, (void *)MapReflectionFriend::Length},
- {Py_mp_subscript, (void *)MapReflectionFriend::MessageMapGetItem},
- {Py_mp_ass_subscript, (void *)MapReflectionFriend::MessageMapSetItem},
- {Py_tp_methods, (void *)MessageMapMethods},
- {Py_tp_iter, (void *)MapReflectionFriend::GetIterator},
- {0, 0}
- };
-
- PyType_Spec MessageMapContainer_Type_spec = {
- FULL_MODULE_NAME ".MessageMapContainer",
- sizeof(MessageMapContainer),
- 0,
- Py_TPFLAGS_DEFAULT,
- MessageMapContainer_Type_slots
- };
-
- PyObject *MessageMapContainer_Type;
-#else
- static PyMappingMethods MessageMapMappingMethods = {
- MapReflectionFriend::Length, // mp_length
- MapReflectionFriend::MessageMapGetItem, // mp_subscript
- MapReflectionFriend::MessageMapSetItem, // mp_ass_subscript
- };
-
- PyTypeObject MessageMapContainer_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".MessageMapContainer", // tp_name
- sizeof(MessageMapContainer), // tp_basicsize
- 0, // tp_itemsize
- MessageMapDealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- &MessageMapMappingMethods, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A map container for message", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- MapReflectionFriend::GetIterator, // tp_iter
- 0, // tp_iternext
- MessageMapMethods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- };
-#endif
-
-// MapIterator /////////////////////////////////////////////////////////////////
-
-static MapIterator* GetIter(PyObject* obj) {
- return reinterpret_cast<MapIterator*>(obj);
-}
-
-PyObject* MapReflectionFriend::GetIterator(PyObject *_self) {
- MapContainer* self = GetMap(_self);
-
- ScopedPyObjectPtr obj(PyType_GenericAlloc(&MapIterator_Type, 0));
- if (obj == NULL) {
- return PyErr_Format(PyExc_KeyError, "Could not allocate iterator");
- }
-
- MapIterator* iter = GetIter(obj.get());
-
- Py_INCREF(self);
- iter->container = self;
- iter->version = self->version;
- iter->owner = self->owner;
-
- if (MapReflectionFriend::Length(_self) > 0) {
- Message* message = self->GetMutableMessage();
- const Reflection* reflection = message->GetReflection();
-
- iter->iter.reset(new ::google::protobuf::MapIterator(
- reflection->MapBegin(message, self->parent_field_descriptor)));
- }
-
- return obj.release();
-}
-
-PyObject* MapReflectionFriend::IterNext(PyObject* _self) {
- MapIterator* self = GetIter(_self);
-
- // This won't catch mutations to the map performed by MergeFrom(); no easy way
- // to address that.
- if (self->version != self->container->version) {
- return PyErr_Format(PyExc_RuntimeError,
- "Map modified during iteration.");
- }
-
- if (self->iter.get() == NULL) {
- return NULL;
- }
-
- Message* message = self->container->GetMutableMessage();
- const Reflection* reflection = message->GetReflection();
-
- if (*self->iter ==
- reflection->MapEnd(message, self->container->parent_field_descriptor)) {
- return NULL;
- }
-
- PyObject* ret = MapKeyToPython(self->container->key_field_descriptor,
- self->iter->GetKey());
-
- ++(*self->iter);
-
- return ret;
-}
-
-static void DeallocMapIterator(PyObject* _self) {
- MapIterator* self = GetIter(_self);
- self->iter.reset();
- self->owner.reset();
- Py_XDECREF(self->container);
- Py_TYPE(_self)->tp_free(_self);
-}
-
-PyTypeObject MapIterator_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".MapIterator", // tp_name
- sizeof(MapIterator), // tp_basicsize
- 0, // tp_itemsize
- DeallocMapIterator, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A scalar map iterator", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- PyObject_SelfIter, // tp_iter
- MapReflectionFriend::IterNext, // tp_iternext
- 0, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
-};
-
-} // namespace python
-} // namespace protobuf
-} // namespace google
diff --git a/python/google/protobuf/pyext/map_container.h b/python/google/protobuf/pyext/map_container.h
deleted file mode 100644
index fbd6713f..00000000
--- a/python/google/protobuf/pyext/map_container.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_MAP_CONTAINER_H__
-#define GOOGLE_PROTOBUF_PYTHON_CPP_MAP_CONTAINER_H__
-
-#include <Python.h>
-
-#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
-
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/message.h>
-
-namespace google {
-namespace protobuf {
-
-class Message;
-
-#ifdef _SHARED_PTR_H
-using std::shared_ptr;
-#else
-using internal::shared_ptr;
-#endif
-
-namespace python {
-
-struct CMessage;
-struct CMessageClass;
-
-// This struct is used directly for ScalarMap, and is the base class of
-// MessageMapContainer, which is used for MessageMap.
-struct MapContainer {
- PyObject_HEAD;
-
- // This is the top-level C++ Message object that owns the whole
- // proto tree. Every Python MapContainer holds a
- // reference to it in order to keep it alive as long as there's a
- // Python object that references any part of the tree.
- shared_ptr<Message> owner;
-
- // Pointer to the C++ Message that contains this container. The
- // MapContainer does not own this pointer.
- const Message* message;
-
- // Use to get a mutable message when necessary.
- Message* GetMutableMessage();
-
- // Weak reference to a parent CMessage object (i.e. may be NULL.)
- //
- // Used to make sure all ancestors are also mutable when first
- // modifying the container.
- CMessage* parent;
-
- // Pointer to the parent's descriptor that describes this
- // field. Used together with the parent's message when making a
- // default message instance mutable.
- // The pointer is owned by the global DescriptorPool.
- const FieldDescriptor* parent_field_descriptor;
- const FieldDescriptor* key_field_descriptor;
- const FieldDescriptor* value_field_descriptor;
-
- // We bump this whenever we perform a mutation, to invalidate existing
- // iterators.
- uint64 version;
-
- // Releases the messages in the container to a new message.
- //
- // Returns 0 on success, -1 on failure.
- int Release();
-
- // Set the owner field of self and any children of self.
- void SetOwner(const shared_ptr<Message>& new_owner) {
- owner = new_owner;
- }
-};
-
-struct MessageMapContainer : public MapContainer {
- // The type used to create new child messages.
- CMessageClass* message_class;
-
- // A dict mapping Message* -> CMessage.
- PyObject* message_dict;
-};
-
-#if PY_MAJOR_VERSION >= 3
- extern PyObject *MessageMapContainer_Type;
- extern PyType_Spec MessageMapContainer_Type_spec;
- extern PyObject *ScalarMapContainer_Type;
- extern PyType_Spec ScalarMapContainer_Type_spec;
-#else
- extern PyTypeObject MessageMapContainer_Type;
- extern PyTypeObject ScalarMapContainer_Type;
-#endif
-
-extern PyTypeObject MapIterator_Type; // Both map types use the same iterator.
-
-// Builds a MapContainer object, from a parent message and a
-// field descriptor.
-extern PyObject* NewScalarMapContainer(
- CMessage* parent, const FieldDescriptor* parent_field_descriptor);
-
-// Builds a MessageMap object, from a parent message and a
-// field descriptor.
-extern PyObject* NewMessageMapContainer(
- CMessage* parent, const FieldDescriptor* parent_field_descriptor,
- CMessageClass* message_class);
-
-} // namespace python
-} // namespace protobuf
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_CPP_MAP_CONTAINER_H__
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
deleted file mode 100644
index a9261f20..00000000
--- a/python/google/protobuf/pyext/message.cc
+++ /dev/null
@@ -1,3085 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: anuraag@google.com (Anuraag Agrawal)
-// Author: tibell@google.com (Johan Tibell)
-
-#include <google/protobuf/pyext/message.h>
-
-#include <map>
-#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
-#include <string>
-#include <vector>
-#include <structmember.h> // A Python header file.
-
-#ifndef PyVarObject_HEAD_INIT
-#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
-#endif
-#ifndef Py_TYPE
-#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
-#endif
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/util/message_differencer.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/message.h>
-#include <google/protobuf/text_format.h>
-#include <google/protobuf/unknown_field_set.h>
-#include <google/protobuf/pyext/descriptor.h>
-#include <google/protobuf/pyext/descriptor_pool.h>
-#include <google/protobuf/pyext/extension_dict.h>
-#include <google/protobuf/pyext/repeated_composite_container.h>
-#include <google/protobuf/pyext/repeated_scalar_container.h>
-#include <google/protobuf/pyext/map_container.h>
-#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
-#include <google/protobuf/stubs/strutil.h>
-
-#if PY_MAJOR_VERSION >= 3
- #define PyInt_Check PyLong_Check
- #define PyInt_AsLong PyLong_AsLong
- #define PyInt_FromLong PyLong_FromLong
- #define PyInt_FromSize_t PyLong_FromSize_t
- #define PyString_Check PyUnicode_Check
- #define PyString_FromString PyUnicode_FromString
- #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
- #if PY_VERSION_HEX < 0x03030000
- #error "Python 3.0 - 3.2 are not supported."
- #else
- #define PyString_AsString(ob) \
- (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AsString(ob))
- #define PyString_AsStringAndSize(ob, charpp, sizep) \
- (PyUnicode_Check(ob)? \
- ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
- PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
- #endif
-#endif
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-static PyObject* kDESCRIPTOR;
-static PyObject* k_extensions_by_name;
-static PyObject* k_extensions_by_number;
-PyObject* EnumTypeWrapper_class;
-static PyObject* PythonMessage_class;
-static PyObject* kEmptyWeakref;
-static PyObject* WKT_classes = NULL;
-
-namespace message_meta {
-
-static int InsertEmptyWeakref(PyTypeObject* base);
-
-// Add the number of a field descriptor to the containing message class.
-// Equivalent to:
-// _cls.<field>_FIELD_NUMBER = <number>
-static bool AddFieldNumberToClass(
- PyObject* cls, const FieldDescriptor* field_descriptor) {
- string constant_name = field_descriptor->name() + "_FIELD_NUMBER";
- UpperString(&constant_name);
- ScopedPyObjectPtr attr_name(PyString_FromStringAndSize(
- constant_name.c_str(), constant_name.size()));
- if (attr_name == NULL) {
- return false;
- }
- ScopedPyObjectPtr number(PyInt_FromLong(field_descriptor->number()));
- if (number == NULL) {
- return false;
- }
- if (PyObject_SetAttr(cls, attr_name.get(), number.get()) == -1) {
- return false;
- }
- return true;
-}
-
-
-// Finalize the creation of the Message class.
-static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) {
- // If there are extension_ranges, the message is "extendable", and extension
- // classes will register themselves in this class.
- if (descriptor->extension_range_count() > 0) {
- ScopedPyObjectPtr by_name(PyDict_New());
- if (PyObject_SetAttr(cls, k_extensions_by_name, by_name.get()) < 0) {
- return -1;
- }
- ScopedPyObjectPtr by_number(PyDict_New());
- if (PyObject_SetAttr(cls, k_extensions_by_number, by_number.get()) < 0) {
- return -1;
- }
- }
-
- // For each field set: cls.<field>_FIELD_NUMBER = <number>
- for (int i = 0; i < descriptor->field_count(); ++i) {
- if (!AddFieldNumberToClass(cls, descriptor->field(i))) {
- return -1;
- }
- }
-
- // For each enum set cls.<enum name> = EnumTypeWrapper(<enum descriptor>).
- for (int i = 0; i < descriptor->enum_type_count(); ++i) {
- const EnumDescriptor* enum_descriptor = descriptor->enum_type(i);
- ScopedPyObjectPtr enum_type(
- PyEnumDescriptor_FromDescriptor(enum_descriptor));
- if (enum_type == NULL) {
- return -1;
- }
- // Add wrapped enum type to message class.
- ScopedPyObjectPtr wrapped(PyObject_CallFunctionObjArgs(
- EnumTypeWrapper_class, enum_type.get(), NULL));
- if (wrapped == NULL) {
- return -1;
- }
- if (PyObject_SetAttrString(
- cls, enum_descriptor->name().c_str(), wrapped.get()) == -1) {
- return -1;
- }
-
- // For each enum value add cls.<name> = <number>
- for (int j = 0; j < enum_descriptor->value_count(); ++j) {
- const EnumValueDescriptor* enum_value_descriptor =
- enum_descriptor->value(j);
- ScopedPyObjectPtr value_number(PyInt_FromLong(
- enum_value_descriptor->number()));
- if (value_number == NULL) {
- return -1;
- }
- if (PyObject_SetAttrString(cls, enum_value_descriptor->name().c_str(),
- value_number.get()) == -1) {
- return -1;
- }
- }
- }
-
- // For each extension set cls.<extension name> = <extension descriptor>.
- //
- // Extension descriptors come from
- // <message descriptor>.extensions_by_name[name]
- // which was defined previously.
- for (int i = 0; i < descriptor->extension_count(); ++i) {
- const google::protobuf::FieldDescriptor* field = descriptor->extension(i);
- ScopedPyObjectPtr extension_field(PyFieldDescriptor_FromDescriptor(field));
- if (extension_field == NULL) {
- return -1;
- }
-
- // Add the extension field to the message class.
- if (PyObject_SetAttrString(
- cls, field->name().c_str(), extension_field.get()) == -1) {
- return -1;
- }
-
- // For each extension set cls.<extension name>_FIELD_NUMBER = <number>.
- if (!AddFieldNumberToClass(cls, field)) {
- return -1;
- }
- }
-
- return 0;
-}
-
-static PyObject* New(PyTypeObject* type,
- PyObject* args, PyObject* kwargs) {
- static char *kwlist[] = {"name", "bases", "dict", 0};
- PyObject *bases, *dict;
- const char* name;
-
- // Check arguments: (name, bases, dict)
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO!O!:type", kwlist,
- &name,
- &PyTuple_Type, &bases,
- &PyDict_Type, &dict)) {
- return NULL;
- }
-
- // Check bases: only (), or (message.Message,) are allowed
- if (!(PyTuple_GET_SIZE(bases) == 0 ||
- (PyTuple_GET_SIZE(bases) == 1 &&
- PyTuple_GET_ITEM(bases, 0) == PythonMessage_class))) {
- PyErr_SetString(PyExc_TypeError,
- "A Message class can only inherit from Message");
- return NULL;
- }
-
- // Check dict['DESCRIPTOR']
- PyObject* py_descriptor = PyDict_GetItem(dict, kDESCRIPTOR);
- if (py_descriptor == NULL) {
- PyErr_SetString(PyExc_TypeError, "Message class has no DESCRIPTOR");
- return NULL;
- }
- if (!PyObject_TypeCheck(py_descriptor, &PyMessageDescriptor_Type)) {
- PyErr_Format(PyExc_TypeError, "Expected a message Descriptor, got %s",
- py_descriptor->ob_type->tp_name);
- return NULL;
- }
-
- // Build the arguments to the base metaclass.
- // We change the __bases__ classes.
- ScopedPyObjectPtr new_args;
- const Descriptor* message_descriptor =
- PyMessageDescriptor_AsDescriptor(py_descriptor);
- if (message_descriptor == NULL) {
- return NULL;
- }
-
- if (WKT_classes == NULL) {
- ScopedPyObjectPtr well_known_types(PyImport_ImportModule(
- "google.protobuf.internal.well_known_types"));
- GOOGLE_DCHECK(well_known_types != NULL);
-
- WKT_classes = PyObject_GetAttrString(well_known_types.get(), "WKTBASES");
- GOOGLE_DCHECK(WKT_classes != NULL);
- }
-
- PyObject* well_known_class = PyDict_GetItemString(
- WKT_classes, message_descriptor->full_name().c_str());
- if (well_known_class == NULL) {
- new_args.reset(Py_BuildValue("s(OO)O", name, &CMessage_Type,
- PythonMessage_class, dict));
- } else {
- new_args.reset(Py_BuildValue("s(OOO)O", name, &CMessage_Type,
- PythonMessage_class, well_known_class, dict));
- }
-
- if (new_args == NULL) {
- return NULL;
- }
- // Call the base metaclass.
- ScopedPyObjectPtr result(PyType_Type.tp_new(type, new_args.get(), NULL));
- if (result == NULL) {
- return NULL;
- }
- CMessageClass* newtype = reinterpret_cast<CMessageClass*>(result.get());
-
- // Insert the empty weakref into the base classes.
- if (InsertEmptyWeakref(
- reinterpret_cast<PyTypeObject*>(PythonMessage_class)) < 0 ||
- InsertEmptyWeakref(&CMessage_Type) < 0) {
- return NULL;
- }
-
- // Cache the descriptor, both as Python object and as C++ pointer.
- const Descriptor* descriptor =
- PyMessageDescriptor_AsDescriptor(py_descriptor);
- if (descriptor == NULL) {
- return NULL;
- }
- Py_INCREF(py_descriptor);
- newtype->py_message_descriptor = py_descriptor;
- newtype->message_descriptor = descriptor;
- // TODO(amauryfa): Don't always use the canonical pool of the descriptor,
- // use the MessageFactory optionally passed in the class dict.
- newtype->py_descriptor_pool = GetDescriptorPool_FromPool(
- descriptor->file()->pool());
- if (newtype->py_descriptor_pool == NULL) {
- return NULL;
- }
- Py_INCREF(newtype->py_descriptor_pool);
-
- // Add the message to the DescriptorPool.
- if (cdescriptor_pool::RegisterMessageClass(newtype->py_descriptor_pool,
- descriptor, newtype) < 0) {
- return NULL;
- }
-
- // Continue with type initialization: add other descriptors, enum values...
- if (AddDescriptors(result.get(), descriptor) < 0) {
- return NULL;
- }
- return result.release();
-}
-
-static void Dealloc(CMessageClass *self) {
- Py_DECREF(self->py_message_descriptor);
- Py_DECREF(self->py_descriptor_pool);
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
-}
-
-
-// This function inserts and empty weakref at the end of the list of
-// subclasses for the main protocol buffer Message class.
-//
-// This eliminates a O(n^2) behaviour in the internal add_subclass
-// routine.
-static int InsertEmptyWeakref(PyTypeObject *base_type) {
-#if PY_MAJOR_VERSION >= 3
- // Python 3.4 has already included the fix for the issue that this
- // hack addresses. For further background and the fix please see
- // https://bugs.python.org/issue17936.
- return 0;
-#else
- PyObject *subclasses = base_type->tp_subclasses;
- if (subclasses && PyList_CheckExact(subclasses)) {
- return PyList_Append(subclasses, kEmptyWeakref);
- }
- return 0;
-#endif // PY_MAJOR_VERSION >= 3
-}
-
-} // namespace message_meta
-
-PyTypeObject CMessageClass_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".MessageMeta", // tp_name
- sizeof(CMessageClass), // tp_basicsize
- 0, // tp_itemsize
- (destructor)message_meta::Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags
- "The metaclass of ProtocolMessages", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- 0, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- 0, // tp_alloc
- message_meta::New, // tp_new
-};
-
-static CMessageClass* CheckMessageClass(PyTypeObject* cls) {
- if (!PyObject_TypeCheck(cls, &CMessageClass_Type)) {
- PyErr_Format(PyExc_TypeError, "Class %s is not a Message", cls->tp_name);
- return NULL;
- }
- return reinterpret_cast<CMessageClass*>(cls);
-}
-
-static const Descriptor* GetMessageDescriptor(PyTypeObject* cls) {
- CMessageClass* type = CheckMessageClass(cls);
- if (type == NULL) {
- return NULL;
- }
- return type->message_descriptor;
-}
-
-// Forward declarations
-namespace cmessage {
-int InternalReleaseFieldByDescriptor(
- CMessage* self,
- const FieldDescriptor* field_descriptor,
- PyObject* composite_field);
-} // namespace cmessage
-
-// ---------------------------------------------------------------------
-// Visiting the composite children of a CMessage
-
-struct ChildVisitor {
- // Returns 0 on success, -1 on failure.
- int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
- return 0;
- }
-
- // Returns 0 on success, -1 on failure.
- int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
- return 0;
- }
-
- // Returns 0 on success, -1 on failure.
- int VisitCMessage(CMessage* cmessage,
- const FieldDescriptor* field_descriptor) {
- return 0;
- }
-};
-
-// Apply a function to a composite field. Does nothing if child is of
-// non-composite type.
-template<class Visitor>
-static int VisitCompositeField(const FieldDescriptor* descriptor,
- PyObject* child,
- Visitor visitor) {
- if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
- if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- if (descriptor->is_map()) {
- MapContainer* container = reinterpret_cast<MapContainer*>(child);
- if (visitor.VisitMapContainer(container) == -1) {
- return -1;
- }
- } else {
- RepeatedCompositeContainer* container =
- reinterpret_cast<RepeatedCompositeContainer*>(child);
- if (visitor.VisitRepeatedCompositeContainer(container) == -1)
- return -1;
- }
- } else {
- RepeatedScalarContainer* container =
- reinterpret_cast<RepeatedScalarContainer*>(child);
- if (visitor.VisitRepeatedScalarContainer(container) == -1)
- return -1;
- }
- } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- CMessage* cmsg = reinterpret_cast<CMessage*>(child);
- if (visitor.VisitCMessage(cmsg, descriptor) == -1)
- return -1;
- }
- // The ExtensionDict might contain non-composite fields, which we
- // skip here.
- return 0;
-}
-
-// Visit each composite field and extension field of this CMessage.
-// Returns -1 on error and 0 on success.
-template<class Visitor>
-int ForEachCompositeField(CMessage* self, Visitor visitor) {
- Py_ssize_t pos = 0;
- PyObject* key;
- PyObject* field;
-
- // Visit normal fields.
- if (self->composite_fields) {
- // Never use self->message in this function, it may be already freed.
- const Descriptor* message_descriptor =
- GetMessageDescriptor(Py_TYPE(self));
- while (PyDict_Next(self->composite_fields, &pos, &key, &field)) {
- Py_ssize_t key_str_size;
- char *key_str_data;
- if (PyString_AsStringAndSize(key, &key_str_data, &key_str_size) != 0)
- return -1;
- const string key_str(key_str_data, key_str_size);
- const FieldDescriptor* descriptor =
- message_descriptor->FindFieldByName(key_str);
- if (descriptor != NULL) {
- if (VisitCompositeField(descriptor, field, visitor) == -1)
- return -1;
- }
- }
- }
-
- // Visit extension fields.
- if (self->extensions != NULL) {
- pos = 0;
- while (PyDict_Next(self->extensions->values, &pos, &key, &field)) {
- const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key);
- if (descriptor == NULL)
- return -1;
- if (VisitCompositeField(descriptor, field, visitor) == -1)
- return -1;
- }
- }
-
- return 0;
-}
-
-// ---------------------------------------------------------------------
-
-// Constants used for integer type range checking.
-PyObject* kPythonZero;
-PyObject* kint32min_py;
-PyObject* kint32max_py;
-PyObject* kuint32max_py;
-PyObject* kint64min_py;
-PyObject* kint64max_py;
-PyObject* kuint64max_py;
-
-PyObject* EncodeError_class;
-PyObject* DecodeError_class;
-PyObject* PickleError_class;
-
-// Constant PyString values used for GetAttr/GetItem.
-static PyObject* k_cdescriptor;
-static PyObject* kfull_name;
-
-/* Is 64bit */
-void FormatTypeError(PyObject* arg, char* expected_types) {
- PyObject* repr = PyObject_Repr(arg);
- if (repr) {
- PyErr_Format(PyExc_TypeError,
- "%.100s has type %.100s, but expected one of: %s",
- PyString_AsString(repr),
- Py_TYPE(arg)->tp_name,
- expected_types);
- Py_DECREF(repr);
- }
-}
-
-template<class T>
-bool CheckAndGetInteger(
- PyObject* arg, T* value, PyObject* min, PyObject* max) {
- bool is_long = PyLong_Check(arg);
-#if PY_MAJOR_VERSION < 3
- if (!PyInt_Check(arg) && !is_long) {
- FormatTypeError(arg, "int, long");
- return false;
- }
- if (PyObject_Compare(min, arg) > 0 || PyObject_Compare(max, arg) < 0) {
-#else
- if (!is_long) {
- FormatTypeError(arg, "int");
- return false;
- }
- if (PyObject_RichCompareBool(min, arg, Py_LE) != 1 ||
- PyObject_RichCompareBool(max, arg, Py_GE) != 1) {
-#endif
- if (!PyErr_Occurred()) {
- PyObject *s = PyObject_Str(arg);
- if (s) {
- PyErr_Format(PyExc_ValueError,
- "Value out of range: %s",
- PyString_AsString(s));
- Py_DECREF(s);
- }
- }
- return false;
- }
-#if PY_MAJOR_VERSION < 3
- if (!is_long) {
- *value = static_cast<T>(PyInt_AsLong(arg));
- } else // NOLINT
-#endif
- {
- if (min == kPythonZero) {
- *value = static_cast<T>(PyLong_AsUnsignedLongLong(arg));
- } else {
- *value = static_cast<T>(PyLong_AsLongLong(arg));
- }
- }
- return true;
-}
-
-// These are referenced by repeated_scalar_container, and must
-// be explicitly instantiated.
-template bool CheckAndGetInteger<int32>(
- PyObject*, int32*, PyObject*, PyObject*);
-template bool CheckAndGetInteger<int64>(
- PyObject*, int64*, PyObject*, PyObject*);
-template bool CheckAndGetInteger<uint32>(
- PyObject*, uint32*, PyObject*, PyObject*);
-template bool CheckAndGetInteger<uint64>(
- PyObject*, uint64*, PyObject*, PyObject*);
-
-bool CheckAndGetDouble(PyObject* arg, double* value) {
- if (!PyInt_Check(arg) && !PyLong_Check(arg) &&
- !PyFloat_Check(arg)) {
- FormatTypeError(arg, "int, long, float");
- return false;
- }
- *value = PyFloat_AsDouble(arg);
- return true;
-}
-
-bool CheckAndGetFloat(PyObject* arg, float* value) {
- double double_value;
- if (!CheckAndGetDouble(arg, &double_value)) {
- return false;
- }
- *value = static_cast<float>(double_value);
- return true;
-}
-
-bool CheckAndGetBool(PyObject* arg, bool* value) {
- if (!PyInt_Check(arg) && !PyBool_Check(arg) && !PyLong_Check(arg)) {
- FormatTypeError(arg, "int, long, bool");
- return false;
- }
- *value = static_cast<bool>(PyInt_AsLong(arg));
- return true;
-}
-
-// Checks whether the given object (which must be "bytes" or "unicode") contains
-// valid UTF-8.
-bool IsValidUTF8(PyObject* obj) {
- if (PyBytes_Check(obj)) {
- PyObject* unicode = PyUnicode_FromEncodedObject(obj, "utf-8", NULL);
-
- // Clear the error indicator; we report our own error when desired.
- PyErr_Clear();
-
- if (unicode) {
- Py_DECREF(unicode);
- return true;
- } else {
- return false;
- }
- } else {
- // Unicode object, known to be valid UTF-8.
- return true;
- }
-}
-
-bool AllowInvalidUTF8(const FieldDescriptor* field) { return false; }
-
-PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor) {
- GOOGLE_DCHECK(descriptor->type() == FieldDescriptor::TYPE_STRING ||
- descriptor->type() == FieldDescriptor::TYPE_BYTES);
- if (descriptor->type() == FieldDescriptor::TYPE_STRING) {
- if (!PyBytes_Check(arg) && !PyUnicode_Check(arg)) {
- FormatTypeError(arg, "bytes, unicode");
- return NULL;
- }
-
- if (!IsValidUTF8(arg) && !AllowInvalidUTF8(descriptor)) {
- PyObject* repr = PyObject_Repr(arg);
- PyErr_Format(PyExc_ValueError,
- "%s has type str, but isn't valid UTF-8 "
- "encoding. Non-UTF-8 strings must be converted to "
- "unicode objects before being added.",
- PyString_AsString(repr));
- Py_DECREF(repr);
- return NULL;
- }
- } else if (!PyBytes_Check(arg)) {
- FormatTypeError(arg, "bytes");
- return NULL;
- }
-
- PyObject* encoded_string = NULL;
- if (descriptor->type() == FieldDescriptor::TYPE_STRING) {
- if (PyBytes_Check(arg)) {
- // The bytes were already validated as correctly encoded UTF-8 above.
- encoded_string = arg; // Already encoded.
- Py_INCREF(encoded_string);
- } else {
- encoded_string = PyUnicode_AsEncodedObject(arg, "utf-8", NULL);
- }
- } else {
- // In this case field type is "bytes".
- encoded_string = arg;
- Py_INCREF(encoded_string);
- }
-
- return encoded_string;
-}
-
-bool CheckAndSetString(
- PyObject* arg, Message* message,
- const FieldDescriptor* descriptor,
- const Reflection* reflection,
- bool append,
- int index) {
- ScopedPyObjectPtr encoded_string(CheckString(arg, descriptor));
-
- if (encoded_string.get() == NULL) {
- return false;
- }
-
- char* value;
- Py_ssize_t value_len;
- if (PyBytes_AsStringAndSize(encoded_string.get(), &value, &value_len) < 0) {
- return false;
- }
-
- string value_string(value, value_len);
- if (append) {
- reflection->AddString(message, descriptor, value_string);
- } else if (index < 0) {
- reflection->SetString(message, descriptor, value_string);
- } else {
- reflection->SetRepeatedString(message, descriptor, index, value_string);
- }
- return true;
-}
-
-PyObject* ToStringObject(const FieldDescriptor* descriptor, string value) {
- if (descriptor->type() != FieldDescriptor::TYPE_STRING) {
- return PyBytes_FromStringAndSize(value.c_str(), value.length());
- }
-
- PyObject* result = PyUnicode_DecodeUTF8(value.c_str(), value.length(), NULL);
- // If the string can't be decoded in UTF-8, just return a string object that
- // contains the raw bytes. This can't happen if the value was assigned using
- // the members of the Python message object, but can happen if the values were
- // parsed from the wire (binary).
- if (result == NULL) {
- PyErr_Clear();
- result = PyBytes_FromStringAndSize(value.c_str(), value.length());
- }
- return result;
-}
-
-bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor,
- const Message* message) {
- if (message->GetDescriptor() == field_descriptor->containing_type()) {
- return true;
- }
- PyErr_Format(PyExc_KeyError, "Field '%s' does not belong to message '%s'",
- field_descriptor->full_name().c_str(),
- message->GetDescriptor()->full_name().c_str());
- return false;
-}
-
-namespace cmessage {
-
-PyDescriptorPool* GetDescriptorPoolForMessage(CMessage* message) {
- // No need to check the type: the type of instances of CMessage is always
- // an instance of CMessageClass. Let's prove it with a debug-only check.
- GOOGLE_DCHECK(PyObject_TypeCheck(message, &CMessage_Type));
- return reinterpret_cast<CMessageClass*>(Py_TYPE(message))->py_descriptor_pool;
-}
-
-MessageFactory* GetFactoryForMessage(CMessage* message) {
- return GetDescriptorPoolForMessage(message)->message_factory;
-}
-
-static int MaybeReleaseOverlappingOneofField(
- CMessage* cmessage,
- const FieldDescriptor* field) {
-#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
- Message* message = cmessage->message;
- const Reflection* reflection = message->GetReflection();
- if (!field->containing_oneof() ||
- !reflection->HasOneof(*message, field->containing_oneof()) ||
- reflection->HasField(*message, field)) {
- // No other field in this oneof, no need to release.
- return 0;
- }
-
- const OneofDescriptor* oneof = field->containing_oneof();
- const FieldDescriptor* existing_field =
- reflection->GetOneofFieldDescriptor(*message, oneof);
- if (existing_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
- // Non-message fields don't need to be released.
- return 0;
- }
- const char* field_name = existing_field->name().c_str();
- PyObject* child_message = cmessage->composite_fields ?
- PyDict_GetItemString(cmessage->composite_fields, field_name) : NULL;
- if (child_message == NULL) {
- // No python reference to this field so no need to release.
- return 0;
- }
-
- if (InternalReleaseFieldByDescriptor(
- cmessage, existing_field, child_message) < 0) {
- return -1;
- }
- return PyDict_DelItemString(cmessage->composite_fields, field_name);
-#else
- return 0;
-#endif
-}
-
-// ---------------------------------------------------------------------
-// Making a message writable
-
-static Message* GetMutableMessage(
- CMessage* parent,
- const FieldDescriptor* parent_field) {
- Message* parent_message = parent->message;
- const Reflection* reflection = parent_message->GetReflection();
- if (MaybeReleaseOverlappingOneofField(parent, parent_field) < 0) {
- return NULL;
- }
- return reflection->MutableMessage(
- parent_message, parent_field, GetFactoryForMessage(parent));
-}
-
-struct FixupMessageReference : public ChildVisitor {
- // message must outlive this object.
- explicit FixupMessageReference(Message* message) :
- message_(message) {}
-
- int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
- container->message = message_;
- return 0;
- }
-
- int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
- container->message = message_;
- return 0;
- }
-
- int VisitMapContainer(MapContainer* container) {
- container->message = message_;
- return 0;
- }
-
- private:
- Message* message_;
-};
-
-int AssureWritable(CMessage* self) {
- if (self == NULL || !self->read_only) {
- return 0;
- }
-
- if (self->parent == NULL) {
- // If parent is NULL but we are trying to modify a read-only message, this
- // is a reference to a constant default instance that needs to be replaced
- // with a mutable top-level message.
- self->message = self->message->New();
- self->owner.reset(self->message);
- // Cascade the new owner to eventual children: even if this message is
- // empty, some submessages or repeated containers might exist already.
- SetOwner(self, self->owner);
- } else {
- // Otherwise, we need a mutable child message.
- if (AssureWritable(self->parent) == -1)
- return -1;
-
- // Make self->message writable.
- Message* mutable_message = GetMutableMessage(
- self->parent,
- self->parent_field_descriptor);
- if (mutable_message == NULL) {
- return -1;
- }
- self->message = mutable_message;
- }
- self->read_only = false;
-
- // When a CMessage is made writable its Message pointer is updated
- // to point to a new mutable Message. When that happens we need to
- // update any references to the old, read-only CMessage. There are
- // four places such references occur: RepeatedScalarContainer,
- // RepeatedCompositeContainer, MapContainer, and ExtensionDict.
- if (self->extensions != NULL)
- self->extensions->message = self->message;
- if (ForEachCompositeField(self, FixupMessageReference(self->message)) == -1)
- return -1;
-
- return 0;
-}
-
-// --- Globals:
-
-// Retrieve a C++ FieldDescriptor for a message attribute.
-// The C++ message must be valid.
-// TODO(amauryfa): This function should stay internal, because exception
-// handling is not consistent.
-static const FieldDescriptor* GetFieldDescriptor(
- CMessage* self, PyObject* name) {
- const Descriptor *message_descriptor = self->message->GetDescriptor();
- char* field_name;
- Py_ssize_t size;
- if (PyString_AsStringAndSize(name, &field_name, &size) < 0) {
- return NULL;
- }
- const FieldDescriptor *field_descriptor =
- message_descriptor->FindFieldByName(string(field_name, size));
- if (field_descriptor == NULL) {
- // Note: No exception is set!
- return NULL;
- }
- return field_descriptor;
-}
-
-// Retrieve a C++ FieldDescriptor for an extension handle.
-const FieldDescriptor* GetExtensionDescriptor(PyObject* extension) {
- ScopedPyObjectPtr cdescriptor;
- if (!PyObject_TypeCheck(extension, &PyFieldDescriptor_Type)) {
- // Most callers consider extensions as a plain dictionary. We should
- // allow input which is not a field descriptor, and simply pretend it does
- // not exist.
- PyErr_SetObject(PyExc_KeyError, extension);
- return NULL;
- }
- return PyFieldDescriptor_AsDescriptor(extension);
-}
-
-// If value is a string, convert it into an enum value based on the labels in
-// descriptor, otherwise simply return value. Always returns a new reference.
-static PyObject* GetIntegerEnumValue(const FieldDescriptor& descriptor,
- PyObject* value) {
- if (PyString_Check(value) || PyUnicode_Check(value)) {
- const EnumDescriptor* enum_descriptor = descriptor.enum_type();
- if (enum_descriptor == NULL) {
- PyErr_SetString(PyExc_TypeError, "not an enum field");
- return NULL;
- }
- char* enum_label;
- Py_ssize_t size;
- if (PyString_AsStringAndSize(value, &enum_label, &size) < 0) {
- return NULL;
- }
- const EnumValueDescriptor* enum_value_descriptor =
- enum_descriptor->FindValueByName(string(enum_label, size));
- if (enum_value_descriptor == NULL) {
- PyErr_SetString(PyExc_ValueError, "unknown enum label");
- return NULL;
- }
- return PyInt_FromLong(enum_value_descriptor->number());
- }
- Py_INCREF(value);
- return value;
-}
-
-// If cmessage_list is not NULL, this function releases values into the
-// container CMessages instead of just removing. Repeated composite container
-// needs to do this to make sure CMessages stay alive if they're still
-// referenced after deletion. Repeated scalar container doesn't need to worry.
-int InternalDeleteRepeatedField(
- CMessage* self,
- const FieldDescriptor* field_descriptor,
- PyObject* slice,
- PyObject* cmessage_list) {
- Message* message = self->message;
- Py_ssize_t length, from, to, step, slice_length;
- const Reflection* reflection = message->GetReflection();
- int min, max;
- length = reflection->FieldSize(*message, field_descriptor);
-
- if (PyInt_Check(slice) || PyLong_Check(slice)) {
- from = to = PyLong_AsLong(slice);
- if (from < 0) {
- from = to = length + from;
- }
- step = 1;
- min = max = from;
-
- // Range check.
- if (from < 0 || from >= length) {
- PyErr_Format(PyExc_IndexError, "list assignment index out of range");
- return -1;
- }
- } else if (PySlice_Check(slice)) {
- from = to = step = slice_length = 0;
- PySlice_GetIndicesEx(
-#if PY_MAJOR_VERSION < 3
- reinterpret_cast<PySliceObject*>(slice),
-#else
- slice,
-#endif
- length, &from, &to, &step, &slice_length);
- if (from < to) {
- min = from;
- max = to - 1;
- } else {
- min = to + 1;
- max = from;
- }
- } else {
- PyErr_SetString(PyExc_TypeError, "list indices must be integers");
- return -1;
- }
-
- Py_ssize_t i = from;
- std::vector<bool> to_delete(length, false);
- while (i >= min && i <= max) {
- to_delete[i] = true;
- i += step;
- }
-
- to = 0;
- for (i = 0; i < length; ++i) {
- if (!to_delete[i]) {
- if (i != to) {
- reflection->SwapElements(message, field_descriptor, i, to);
- if (cmessage_list != NULL) {
- // If a list of cmessages is passed in (i.e. from a repeated
- // composite container), swap those as well to correspond to the
- // swaps in the underlying message so they're in the right order
- // when we start releasing.
- PyObject* tmp = PyList_GET_ITEM(cmessage_list, i);
- PyList_SET_ITEM(cmessage_list, i,
- PyList_GET_ITEM(cmessage_list, to));
- PyList_SET_ITEM(cmessage_list, to, tmp);
- }
- }
- ++to;
- }
- }
-
- while (i > to) {
- if (cmessage_list == NULL) {
- reflection->RemoveLast(message, field_descriptor);
- } else {
- CMessage* last_cmessage = reinterpret_cast<CMessage*>(
- PyList_GET_ITEM(cmessage_list, PyList_GET_SIZE(cmessage_list) - 1));
- repeated_composite_container::ReleaseLastTo(
- self, field_descriptor, last_cmessage);
- if (PySequence_DelItem(cmessage_list, -1) < 0) {
- return -1;
- }
- }
- --i;
- }
-
- return 0;
-}
-
-// Initializes fields of a message. Used in constructors.
-int InitAttributes(CMessage* self, PyObject* kwargs) {
- if (kwargs == NULL) {
- return 0;
- }
-
- Py_ssize_t pos = 0;
- PyObject* name;
- PyObject* value;
- while (PyDict_Next(kwargs, &pos, &name, &value)) {
- if (!PyString_Check(name)) {
- PyErr_SetString(PyExc_ValueError, "Field name must be a string");
- return -1;
- }
- const FieldDescriptor* descriptor = GetFieldDescriptor(self, name);
- if (descriptor == NULL) {
- PyErr_Format(PyExc_ValueError, "Protocol message %s has no \"%s\" field.",
- self->message->GetDescriptor()->name().c_str(),
- PyString_AsString(name));
- return -1;
- }
- if (value == Py_None) {
- // field=None is the same as no field at all.
- continue;
- }
- if (descriptor->is_map()) {
- ScopedPyObjectPtr map(GetAttr(self, name));
- const FieldDescriptor* value_descriptor =
- descriptor->message_type()->FindFieldByName("value");
- if (value_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- Py_ssize_t map_pos = 0;
- PyObject* map_key;
- PyObject* map_value;
- while (PyDict_Next(value, &map_pos, &map_key, &map_value)) {
- ScopedPyObjectPtr function_return;
- function_return.reset(PyObject_GetItem(map.get(), map_key));
- if (function_return.get() == NULL) {
- return -1;
- }
- ScopedPyObjectPtr ok(PyObject_CallMethod(
- function_return.get(), "MergeFrom", "O", map_value));
- if (ok.get() == NULL) {
- return -1;
- }
- }
- } else {
- ScopedPyObjectPtr function_return;
- function_return.reset(
- PyObject_CallMethod(map.get(), "update", "O", value));
- if (function_return.get() == NULL) {
- return -1;
- }
- }
- } else if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
- ScopedPyObjectPtr container(GetAttr(self, name));
- if (container == NULL) {
- return -1;
- }
- if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- RepeatedCompositeContainer* rc_container =
- reinterpret_cast<RepeatedCompositeContainer*>(container.get());
- ScopedPyObjectPtr iter(PyObject_GetIter(value));
- if (iter == NULL) {
- PyErr_SetString(PyExc_TypeError, "Value must be iterable");
- return -1;
- }
- ScopedPyObjectPtr next;
- while ((next.reset(PyIter_Next(iter.get()))) != NULL) {
- PyObject* kwargs = (PyDict_Check(next.get()) ? next.get() : NULL);
- ScopedPyObjectPtr new_msg(
- repeated_composite_container::Add(rc_container, NULL, kwargs));
- if (new_msg == NULL) {
- return -1;
- }
- if (kwargs == NULL) {
- // next was not a dict, it's a message we need to merge
- ScopedPyObjectPtr merged(MergeFrom(
- reinterpret_cast<CMessage*>(new_msg.get()), next.get()));
- if (merged.get() == NULL) {
- return -1;
- }
- }
- }
- if (PyErr_Occurred()) {
- // Check to see how PyIter_Next() exited.
- return -1;
- }
- } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
- RepeatedScalarContainer* rs_container =
- reinterpret_cast<RepeatedScalarContainer*>(container.get());
- ScopedPyObjectPtr iter(PyObject_GetIter(value));
- if (iter == NULL) {
- PyErr_SetString(PyExc_TypeError, "Value must be iterable");
- return -1;
- }
- ScopedPyObjectPtr next;
- while ((next.reset(PyIter_Next(iter.get()))) != NULL) {
- ScopedPyObjectPtr enum_value(
- GetIntegerEnumValue(*descriptor, next.get()));
- if (enum_value == NULL) {
- return -1;
- }
- ScopedPyObjectPtr new_msg(repeated_scalar_container::Append(
- rs_container, enum_value.get()));
- if (new_msg == NULL) {
- return -1;
- }
- }
- if (PyErr_Occurred()) {
- // Check to see how PyIter_Next() exited.
- return -1;
- }
- } else {
- if (ScopedPyObjectPtr(repeated_scalar_container::Extend(
- reinterpret_cast<RepeatedScalarContainer*>(container.get()),
- value)) ==
- NULL) {
- return -1;
- }
- }
- } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- ScopedPyObjectPtr message(GetAttr(self, name));
- if (message == NULL) {
- return -1;
- }
- CMessage* cmessage = reinterpret_cast<CMessage*>(message.get());
- if (PyDict_Check(value)) {
- if (InitAttributes(cmessage, value) < 0) {
- return -1;
- }
- } else {
- ScopedPyObjectPtr merged(MergeFrom(cmessage, value));
- if (merged == NULL) {
- return -1;
- }
- }
- } else {
- ScopedPyObjectPtr new_val;
- if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
- new_val.reset(GetIntegerEnumValue(*descriptor, value));
- if (new_val == NULL) {
- return -1;
- }
- }
- if (SetAttr(self, name, (new_val.get() == NULL) ? value : new_val.get()) <
- 0) {
- return -1;
- }
- }
- }
- return 0;
-}
-
-// Allocates an incomplete Python Message: the caller must fill self->message,
-// self->owner and eventually self->parent.
-CMessage* NewEmptyMessage(CMessageClass* type) {
- CMessage* self = reinterpret_cast<CMessage*>(
- PyType_GenericAlloc(&type->super.ht_type, 0));
- if (self == NULL) {
- return NULL;
- }
-
- self->message = NULL;
- self->parent = NULL;
- self->parent_field_descriptor = NULL;
- self->read_only = false;
- self->extensions = NULL;
-
- self->composite_fields = NULL;
-
- return self;
-}
-
-// The __new__ method of Message classes.
-// Creates a new C++ message and takes ownership.
-static PyObject* New(PyTypeObject* cls,
- PyObject* unused_args, PyObject* unused_kwargs) {
- CMessageClass* type = CheckMessageClass(cls);
- if (type == NULL) {
- return NULL;
- }
- // Retrieve the message descriptor and the default instance (=prototype).
- const Descriptor* message_descriptor = type->message_descriptor;
- if (message_descriptor == NULL) {
- return NULL;
- }
- const Message* default_message = type->py_descriptor_pool->message_factory
- ->GetPrototype(message_descriptor);
- if (default_message == NULL) {
- PyErr_SetString(PyExc_TypeError, message_descriptor->full_name().c_str());
- return NULL;
- }
-
- CMessage* self = NewEmptyMessage(type);
- if (self == NULL) {
- return NULL;
- }
- self->message = default_message->New();
- self->owner.reset(self->message);
- return reinterpret_cast<PyObject*>(self);
-}
-
-// The __init__ method of Message classes.
-// It initializes fields from keywords passed to the constructor.
-static int Init(CMessage* self, PyObject* args, PyObject* kwargs) {
- if (PyTuple_Size(args) != 0) {
- PyErr_SetString(PyExc_TypeError, "No positional arguments allowed");
- return -1;
- }
-
- return InitAttributes(self, kwargs);
-}
-
-// ---------------------------------------------------------------------
-// Deallocating a CMessage
-//
-// Deallocating a CMessage requires that we clear any weak references
-// from children to the message being deallocated.
-
-// Clear the weak reference from the child to the parent.
-struct ClearWeakReferences : public ChildVisitor {
- int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
- container->parent = NULL;
- // The elements in the container have the same parent as the
- // container itself, so NULL out that pointer as well.
- const Py_ssize_t n = PyList_GET_SIZE(container->child_messages);
- for (Py_ssize_t i = 0; i < n; ++i) {
- CMessage* child_cmessage = reinterpret_cast<CMessage*>(
- PyList_GET_ITEM(container->child_messages, i));
- child_cmessage->parent = NULL;
- }
- return 0;
- }
-
- int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
- container->parent = NULL;
- return 0;
- }
-
- int VisitMapContainer(MapContainer* container) {
- container->parent = NULL;
- return 0;
- }
-
- int VisitCMessage(CMessage* cmessage,
- const FieldDescriptor* field_descriptor) {
- cmessage->parent = NULL;
- return 0;
- }
-};
-
-static void Dealloc(CMessage* self) {
- // Null out all weak references from children to this message.
- GOOGLE_CHECK_EQ(0, ForEachCompositeField(self, ClearWeakReferences()));
- if (self->extensions) {
- self->extensions->parent = NULL;
- }
-
- Py_CLEAR(self->extensions);
- Py_CLEAR(self->composite_fields);
- self->owner.reset();
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
-}
-
-// ---------------------------------------------------------------------
-
-
-PyObject* IsInitialized(CMessage* self, PyObject* args) {
- PyObject* errors = NULL;
- if (PyArg_ParseTuple(args, "|O", &errors) < 0) {
- return NULL;
- }
- if (self->message->IsInitialized()) {
- Py_RETURN_TRUE;
- }
- if (errors != NULL) {
- ScopedPyObjectPtr initialization_errors(
- FindInitializationErrors(self));
- if (initialization_errors == NULL) {
- return NULL;
- }
- ScopedPyObjectPtr extend_name(PyString_FromString("extend"));
- if (extend_name == NULL) {
- return NULL;
- }
- ScopedPyObjectPtr result(PyObject_CallMethodObjArgs(
- errors,
- extend_name.get(),
- initialization_errors.get(),
- NULL));
- if (result == NULL) {
- return NULL;
- }
- }
- Py_RETURN_FALSE;
-}
-
-PyObject* HasFieldByDescriptor(
- CMessage* self, const FieldDescriptor* field_descriptor) {
- Message* message = self->message;
- if (!CheckFieldBelongsToMessage(field_descriptor, message)) {
- return NULL;
- }
- if (field_descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
- PyErr_SetString(PyExc_KeyError,
- "Field is repeated. A singular method is required.");
- return NULL;
- }
- bool has_field =
- message->GetReflection()->HasField(*message, field_descriptor);
- return PyBool_FromLong(has_field ? 1 : 0);
-}
-
-const FieldDescriptor* FindFieldWithOneofs(
- const Message* message, const string& field_name, bool* in_oneof) {
- *in_oneof = false;
- const Descriptor* descriptor = message->GetDescriptor();
- const FieldDescriptor* field_descriptor =
- descriptor->FindFieldByName(field_name);
- if (field_descriptor != NULL) {
- return field_descriptor;
- }
- const OneofDescriptor* oneof_desc =
- descriptor->FindOneofByName(field_name);
- if (oneof_desc != NULL) {
- *in_oneof = true;
- return message->GetReflection()->GetOneofFieldDescriptor(*message,
- oneof_desc);
- }
- return NULL;
-}
-
-bool CheckHasPresence(const FieldDescriptor* field_descriptor, bool in_oneof) {
- if (field_descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
- PyErr_Format(PyExc_ValueError,
- "Protocol message has no singular \"%s\" field.",
- field_descriptor->name().c_str());
- return false;
- }
-
- if (field_descriptor->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
- // HasField() for a oneof *itself* isn't supported.
- if (in_oneof) {
- PyErr_Format(PyExc_ValueError,
- "Can't test oneof field \"%s\" for presence in proto3, use "
- "WhichOneof instead.",
- field_descriptor->containing_oneof()->name().c_str());
- return false;
- }
-
- // ...but HasField() for fields *in* a oneof is supported.
- if (field_descriptor->containing_oneof() != NULL) {
- return true;
- }
-
- if (field_descriptor->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
- PyErr_Format(
- PyExc_ValueError,
- "Can't test non-submessage field \"%s\" for presence in proto3.",
- field_descriptor->name().c_str());
- return false;
- }
- }
-
- return true;
-}
-
-PyObject* HasField(CMessage* self, PyObject* arg) {
- char* field_name;
- Py_ssize_t size;
-#if PY_MAJOR_VERSION < 3
- if (PyString_AsStringAndSize(arg, &field_name, &size) < 0) {
- return NULL;
- }
-#else
- field_name = PyUnicode_AsUTF8AndSize(arg, &size);
- if (!field_name) {
- return NULL;
- }
-#endif
-
- Message* message = self->message;
- bool is_in_oneof;
- const FieldDescriptor* field_descriptor =
- FindFieldWithOneofs(message, string(field_name, size), &is_in_oneof);
- if (field_descriptor == NULL) {
- if (!is_in_oneof) {
- PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name);
- return NULL;
- } else {
- Py_RETURN_FALSE;
- }
- }
-
- if (!CheckHasPresence(field_descriptor, is_in_oneof)) {
- return NULL;
- }
-
- if (message->GetReflection()->HasField(*message, field_descriptor)) {
- Py_RETURN_TRUE;
- }
- if (!message->GetReflection()->SupportsUnknownEnumValues() &&
- field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
- // Special case: Python HasField() differs in semantics from C++
- // slightly: we return HasField('enum_field') == true if there is
- // an unknown enum value present. To implement this we have to
- // look in the UnknownFieldSet.
- const UnknownFieldSet& unknown_field_set =
- message->GetReflection()->GetUnknownFields(*message);
- for (int i = 0; i < unknown_field_set.field_count(); ++i) {
- if (unknown_field_set.field(i).number() == field_descriptor->number()) {
- Py_RETURN_TRUE;
- }
- }
- }
- Py_RETURN_FALSE;
-}
-
-PyObject* ClearExtension(CMessage* self, PyObject* extension) {
- if (self->extensions != NULL) {
- return extension_dict::ClearExtension(self->extensions, extension);
- } else {
- const FieldDescriptor* descriptor = GetExtensionDescriptor(extension);
- if (descriptor == NULL) {
- return NULL;
- }
- if (ScopedPyObjectPtr(ClearFieldByDescriptor(self, descriptor)) == NULL) {
- return NULL;
- }
- }
- Py_RETURN_NONE;
-}
-
-PyObject* HasExtension(CMessage* self, PyObject* extension) {
- const FieldDescriptor* descriptor = GetExtensionDescriptor(extension);
- if (descriptor == NULL) {
- return NULL;
- }
- return HasFieldByDescriptor(self, descriptor);
-}
-
-// ---------------------------------------------------------------------
-// Releasing messages
-//
-// The Python API's ClearField() and Clear() methods behave
-// differently than their C++ counterparts. While the C++ versions
-// clears the children the Python versions detaches the children,
-// without touching their content. This impedance mismatch causes
-// some complexity in the implementation, which is captured in this
-// section.
-//
-// When a CMessage field is cleared we need to:
-//
-// * Release the Message used as the backing store for the CMessage
-// from its parent.
-//
-// * Change the owner field of the released CMessage and all of its
-// children to point to the newly released Message.
-//
-// * Clear the weak references from the released CMessage to the
-// parent.
-//
-// When a RepeatedCompositeContainer field is cleared we need to:
-//
-// * Release all the Message used as the backing store for the
-// CMessages stored in the container.
-//
-// * Change the owner field of all the released CMessage and all of
-// their children to point to the newly released Messages.
-//
-// * Clear the weak references from the released container to the
-// parent.
-
-struct SetOwnerVisitor : public ChildVisitor {
- // new_owner must outlive this object.
- explicit SetOwnerVisitor(const shared_ptr<Message>& new_owner)
- : new_owner_(new_owner) {}
-
- int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
- repeated_composite_container::SetOwner(container, new_owner_);
- return 0;
- }
-
- int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
- repeated_scalar_container::SetOwner(container, new_owner_);
- return 0;
- }
-
- int VisitMapContainer(MapContainer* container) {
- container->SetOwner(new_owner_);
- return 0;
- }
-
- int VisitCMessage(CMessage* cmessage,
- const FieldDescriptor* field_descriptor) {
- return SetOwner(cmessage, new_owner_);
- }
-
- private:
- const shared_ptr<Message>& new_owner_;
-};
-
-// Change the owner of this CMessage and all its children, recursively.
-int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner) {
- self->owner = new_owner;
- if (ForEachCompositeField(self, SetOwnerVisitor(new_owner)) == -1)
- return -1;
- return 0;
-}
-
-// Releases the message specified by 'field' and returns the
-// pointer. If the field does not exist a new message is created using
-// 'descriptor'. The caller takes ownership of the returned pointer.
-Message* ReleaseMessage(CMessage* self,
- const Descriptor* descriptor,
- const FieldDescriptor* field_descriptor) {
- MessageFactory* message_factory = GetFactoryForMessage(self);
- Message* released_message = self->message->GetReflection()->ReleaseMessage(
- self->message, field_descriptor, message_factory);
- // ReleaseMessage will return NULL which differs from
- // child_cmessage->message, if the field does not exist. In this case,
- // the latter points to the default instance via a const_cast<>, so we
- // have to reset it to a new mutable object since we are taking ownership.
- if (released_message == NULL) {
- const Message* prototype = message_factory->GetPrototype(descriptor);
- GOOGLE_DCHECK(prototype != NULL);
- released_message = prototype->New();
- }
-
- return released_message;
-}
-
-int ReleaseSubMessage(CMessage* self,
- const FieldDescriptor* field_descriptor,
- CMessage* child_cmessage) {
- // Release the Message
- shared_ptr<Message> released_message(ReleaseMessage(
- self, child_cmessage->message->GetDescriptor(), field_descriptor));
- child_cmessage->message = released_message.get();
- child_cmessage->owner.swap(released_message);
- child_cmessage->parent = NULL;
- child_cmessage->parent_field_descriptor = NULL;
- child_cmessage->read_only = false;
- return ForEachCompositeField(child_cmessage,
- SetOwnerVisitor(child_cmessage->owner));
-}
-
-struct ReleaseChild : public ChildVisitor {
- // message must outlive this object.
- explicit ReleaseChild(CMessage* parent) :
- parent_(parent) {}
-
- int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
- return repeated_composite_container::Release(container);
- }
-
- int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
- return repeated_scalar_container::Release(container);
- }
-
- int VisitMapContainer(MapContainer* container) {
- return container->Release();
- }
-
- int VisitCMessage(CMessage* cmessage,
- const FieldDescriptor* field_descriptor) {
- return ReleaseSubMessage(parent_, field_descriptor, cmessage);
- }
-
- CMessage* parent_;
-};
-
-int InternalReleaseFieldByDescriptor(
- CMessage* self,
- const FieldDescriptor* field_descriptor,
- PyObject* composite_field) {
- return VisitCompositeField(
- field_descriptor,
- composite_field,
- ReleaseChild(self));
-}
-
-PyObject* ClearFieldByDescriptor(
- CMessage* self,
- const FieldDescriptor* descriptor) {
- if (!CheckFieldBelongsToMessage(descriptor, self->message)) {
- return NULL;
- }
- AssureWritable(self);
- self->message->GetReflection()->ClearField(self->message, descriptor);
- Py_RETURN_NONE;
-}
-
-PyObject* ClearField(CMessage* self, PyObject* arg) {
- if (!PyString_Check(arg)) {
- PyErr_SetString(PyExc_TypeError, "field name must be a string");
- return NULL;
- }
-#if PY_MAJOR_VERSION < 3
- const char* field_name = PyString_AS_STRING(arg);
- Py_ssize_t size = PyString_GET_SIZE(arg);
-#else
- Py_ssize_t size;
- const char* field_name = PyUnicode_AsUTF8AndSize(arg, &size);
-#endif
- AssureWritable(self);
- Message* message = self->message;
- ScopedPyObjectPtr arg_in_oneof;
- bool is_in_oneof;
- const FieldDescriptor* field_descriptor =
- FindFieldWithOneofs(message, string(field_name, size), &is_in_oneof);
- if (field_descriptor == NULL) {
- if (!is_in_oneof) {
- PyErr_Format(PyExc_ValueError,
- "Protocol message has no \"%s\" field.", field_name);
- return NULL;
- } else {
- Py_RETURN_NONE;
- }
- } else if (is_in_oneof) {
- const string& name = field_descriptor->name();
- arg_in_oneof.reset(PyString_FromStringAndSize(name.c_str(), name.size()));
- arg = arg_in_oneof.get();
- }
-
- PyObject* composite_field = self->composite_fields ?
- PyDict_GetItem(self->composite_fields, arg) : NULL;
-
- // Only release the field if there's a possibility that there are
- // references to it.
- if (composite_field != NULL) {
- if (InternalReleaseFieldByDescriptor(self, field_descriptor,
- composite_field) < 0) {
- return NULL;
- }
- PyDict_DelItem(self->composite_fields, arg);
- }
- message->GetReflection()->ClearField(message, field_descriptor);
- if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
- !message->GetReflection()->SupportsUnknownEnumValues()) {
- UnknownFieldSet* unknown_field_set =
- message->GetReflection()->MutableUnknownFields(message);
- unknown_field_set->DeleteByNumber(field_descriptor->number());
- }
-
- Py_RETURN_NONE;
-}
-
-PyObject* Clear(CMessage* self) {
- AssureWritable(self);
- if (ForEachCompositeField(self, ReleaseChild(self)) == -1)
- return NULL;
- Py_CLEAR(self->extensions);
- if (self->composite_fields) {
- PyDict_Clear(self->composite_fields);
- }
- self->message->Clear();
- Py_RETURN_NONE;
-}
-
-// ---------------------------------------------------------------------
-
-static string GetMessageName(CMessage* self) {
- if (self->parent_field_descriptor != NULL) {
- return self->parent_field_descriptor->full_name();
- } else {
- return self->message->GetDescriptor()->full_name();
- }
-}
-
-static PyObject* SerializeToString(CMessage* self, PyObject* args) {
- if (!self->message->IsInitialized()) {
- ScopedPyObjectPtr errors(FindInitializationErrors(self));
- if (errors == NULL) {
- return NULL;
- }
- ScopedPyObjectPtr comma(PyString_FromString(","));
- if (comma == NULL) {
- return NULL;
- }
- ScopedPyObjectPtr joined(
- PyObject_CallMethod(comma.get(), "join", "O", errors.get()));
- if (joined == NULL) {
- return NULL;
- }
-
- // TODO(haberman): this is a (hopefully temporary) hack. The unit testing
- // infrastructure reloads all pure-Python modules for every test, but not
- // C++ modules (because that's generally impossible:
- // http://bugs.python.org/issue1144263). But if we cache EncodeError, we'll
- // return the EncodeError from a previous load of the module, which won't
- // match a user's attempt to catch EncodeError. So we have to look it up
- // again every time.
- ScopedPyObjectPtr message_module(PyImport_ImportModule(
- "google.protobuf.message"));
- if (message_module.get() == NULL) {
- return NULL;
- }
-
- ScopedPyObjectPtr encode_error(
- PyObject_GetAttrString(message_module.get(), "EncodeError"));
- if (encode_error.get() == NULL) {
- return NULL;
- }
- PyErr_Format(encode_error.get(),
- "Message %s is missing required fields: %s",
- GetMessageName(self).c_str(), PyString_AsString(joined.get()));
- return NULL;
- }
- int size = self->message->ByteSize();
- if (size <= 0) {
- return PyBytes_FromString("");
- }
- PyObject* result = PyBytes_FromStringAndSize(NULL, size);
- if (result == NULL) {
- return NULL;
- }
- char* buffer = PyBytes_AS_STRING(result);
- self->message->SerializeWithCachedSizesToArray(
- reinterpret_cast<uint8*>(buffer));
- return result;
-}
-
-static PyObject* SerializePartialToString(CMessage* self) {
- string contents;
- self->message->SerializePartialToString(&contents);
- return PyBytes_FromStringAndSize(contents.c_str(), contents.size());
-}
-
-// Formats proto fields for ascii dumps using python formatting functions where
-// appropriate.
-class PythonFieldValuePrinter : public TextFormat::FieldValuePrinter {
- public:
- // Python has some differences from C++ when printing floating point numbers.
- //
- // 1) Trailing .0 is always printed.
- // 2) (Python2) Output is rounded to 12 digits.
- // 3) (Python3) The full precision of the double is preserved (and Python uses
- // David M. Gay's dtoa(), when the C++ code uses SimpleDtoa. There are some
- // differences, but they rarely happen)
- //
- // We override floating point printing with the C-API function for printing
- // Python floats to ensure consistency.
- string PrintFloat(float value) const { return PrintDouble(value); }
- string PrintDouble(double value) const {
- // This implementation is not highly optimized (it allocates two temporary
- // Python objects) but it is simple and portable. If this is shown to be a
- // performance bottleneck, we can optimize it, but the results will likely
- // be more complicated to accommodate the differing behavior of double
- // formatting between Python 2 and Python 3.
- //
- // (Though a valid question is: do we really want to make out output
- // dependent on the Python version?)
- ScopedPyObjectPtr py_value(PyFloat_FromDouble(value));
- if (!py_value.get()) {
- return string();
- }
-
- ScopedPyObjectPtr py_str(PyObject_Str(py_value.get()));
- if (!py_str.get()) {
- return string();
- }
-
- return string(PyString_AsString(py_str.get()));
- }
-};
-
-static PyObject* ToStr(CMessage* self) {
- TextFormat::Printer printer;
- // Passes ownership
- printer.SetDefaultFieldValuePrinter(new PythonFieldValuePrinter());
- printer.SetHideUnknownFields(true);
- string output;
- if (!printer.PrintToString(*self->message, &output)) {
- PyErr_SetString(PyExc_ValueError, "Unable to convert message to str");
- return NULL;
- }
- return PyString_FromString(output.c_str());
-}
-
-PyObject* MergeFrom(CMessage* self, PyObject* arg) {
- CMessage* other_message;
- if (!PyObject_TypeCheck(arg, &CMessage_Type)) {
- PyErr_Format(PyExc_TypeError,
- "Parameter to MergeFrom() must be instance of same class: "
- "expected %s got %s.",
- self->message->GetDescriptor()->full_name().c_str(),
- Py_TYPE(arg)->tp_name);
- return NULL;
- }
-
- other_message = reinterpret_cast<CMessage*>(arg);
- if (other_message->message->GetDescriptor() !=
- self->message->GetDescriptor()) {
- PyErr_Format(PyExc_TypeError,
- "Parameter to MergeFrom() must be instance of same class: "
- "expected %s got %s.",
- self->message->GetDescriptor()->full_name().c_str(),
- other_message->message->GetDescriptor()->full_name().c_str());
- return NULL;
- }
- AssureWritable(self);
-
- // TODO(tibell): Message::MergeFrom might turn some child Messages
- // into mutable messages, invalidating the message field in the
- // corresponding CMessages. We should run a FixupMessageReferences
- // pass here.
-
- self->message->MergeFrom(*other_message->message);
- Py_RETURN_NONE;
-}
-
-static PyObject* CopyFrom(CMessage* self, PyObject* arg) {
- CMessage* other_message;
- if (!PyObject_TypeCheck(arg, &CMessage_Type)) {
- PyErr_Format(PyExc_TypeError,
- "Parameter to CopyFrom() must be instance of same class: "
- "expected %s got %s.",
- self->message->GetDescriptor()->full_name().c_str(),
- Py_TYPE(arg)->tp_name);
- return NULL;
- }
-
- other_message = reinterpret_cast<CMessage*>(arg);
-
- if (self == other_message) {
- Py_RETURN_NONE;
- }
-
- if (other_message->message->GetDescriptor() !=
- self->message->GetDescriptor()) {
- PyErr_Format(PyExc_TypeError,
- "Parameter to CopyFrom() must be instance of same class: "
- "expected %s got %s.",
- self->message->GetDescriptor()->full_name().c_str(),
- other_message->message->GetDescriptor()->full_name().c_str());
- return NULL;
- }
-
- AssureWritable(self);
-
- // CopyFrom on the message will not clean up self->composite_fields,
- // which can leave us in an inconsistent state, so clear it out here.
- (void)ScopedPyObjectPtr(Clear(self));
-
- self->message->CopyFrom(*other_message->message);
-
- Py_RETURN_NONE;
-}
-
-// Protobuf has a 64MB limit built in, this variable will override this. Please
-// do not enable this unless you fully understand the implications: protobufs
-// must all be kept in memory at the same time, so if they grow too big you may
-// get OOM errors. The protobuf APIs do not provide any tools for processing
-// protobufs in chunks. If you have protos this big you should break them up if
-// it is at all convenient to do so.
-static bool allow_oversize_protos = false;
-
-// Provide a method in the module to set allow_oversize_protos to a boolean
-// value. This method returns the newly value of allow_oversize_protos.
-PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg) {
- if (!arg || !PyBool_Check(arg)) {
- PyErr_SetString(PyExc_TypeError,
- "Argument to SetAllowOversizeProtos must be boolean");
- return NULL;
- }
- allow_oversize_protos = PyObject_IsTrue(arg);
- if (allow_oversize_protos) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
- const void* data;
- Py_ssize_t data_length;
- if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) {
- return NULL;
- }
-
- AssureWritable(self);
- io::CodedInputStream input(
- reinterpret_cast<const uint8*>(data), data_length);
- if (allow_oversize_protos) {
- input.SetTotalBytesLimit(INT_MAX, INT_MAX);
- }
- PyDescriptorPool* pool = GetDescriptorPoolForMessage(self);
- input.SetExtensionRegistry(pool->pool, pool->message_factory);
- bool success = self->message->MergePartialFromCodedStream(&input);
- if (success) {
- return PyInt_FromLong(input.CurrentPosition());
- } else {
- PyErr_Format(DecodeError_class, "Error parsing message");
- return NULL;
- }
-}
-
-static PyObject* ParseFromString(CMessage* self, PyObject* arg) {
- if (ScopedPyObjectPtr(Clear(self)) == NULL) {
- return NULL;
- }
- return MergeFromString(self, arg);
-}
-
-static PyObject* ByteSize(CMessage* self, PyObject* args) {
- return PyLong_FromLong(self->message->ByteSize());
-}
-
-static PyObject* RegisterExtension(PyObject* cls,
- PyObject* extension_handle) {
- const FieldDescriptor* descriptor =
- GetExtensionDescriptor(extension_handle);
- if (descriptor == NULL) {
- return NULL;
- }
-
- ScopedPyObjectPtr extensions_by_name(
- PyObject_GetAttr(cls, k_extensions_by_name));
- if (extensions_by_name == NULL) {
- PyErr_SetString(PyExc_TypeError, "no extensions_by_name on class");
- return NULL;
- }
- ScopedPyObjectPtr full_name(PyObject_GetAttr(extension_handle, kfull_name));
- if (full_name == NULL) {
- return NULL;
- }
-
- // If the extension was already registered, check that it is the same.
- PyObject* existing_extension =
- PyDict_GetItem(extensions_by_name.get(), full_name.get());
- if (existing_extension != NULL) {
- const FieldDescriptor* existing_extension_descriptor =
- GetExtensionDescriptor(existing_extension);
- if (existing_extension_descriptor != descriptor) {
- PyErr_SetString(PyExc_ValueError, "Double registration of Extensions");
- return NULL;
- }
- // Nothing else to do.
- Py_RETURN_NONE;
- }
-
- if (PyDict_SetItem(extensions_by_name.get(), full_name.get(),
- extension_handle) < 0) {
- return NULL;
- }
-
- // Also store a mapping from extension number to implementing class.
- ScopedPyObjectPtr extensions_by_number(
- PyObject_GetAttr(cls, k_extensions_by_number));
- if (extensions_by_number == NULL) {
- PyErr_SetString(PyExc_TypeError, "no extensions_by_number on class");
- return NULL;
- }
-
- ScopedPyObjectPtr number(PyObject_GetAttrString(extension_handle, "number"));
- if (number == NULL) {
- return NULL;
- }
-
- // If the extension was already registered by number, check that it is the
- // same.
- existing_extension = PyDict_GetItem(extensions_by_number.get(), number.get());
- if (existing_extension != NULL) {
- const FieldDescriptor* existing_extension_descriptor =
- GetExtensionDescriptor(existing_extension);
- if (existing_extension_descriptor != descriptor) {
- const Descriptor* msg_desc = GetMessageDescriptor(
- reinterpret_cast<PyTypeObject*>(cls));
- PyErr_Format(
- PyExc_ValueError,
- "Extensions \"%s\" and \"%s\" both try to extend message type "
- "\"%s\" with field number %ld.",
- existing_extension_descriptor->full_name().c_str(),
- descriptor->full_name().c_str(),
- msg_desc->full_name().c_str(),
- PyInt_AsLong(number.get()));
- return NULL;
- }
- // Nothing else to do.
- Py_RETURN_NONE;
- }
- if (PyDict_SetItem(extensions_by_number.get(), number.get(),
- extension_handle) < 0) {
- return NULL;
- }
-
- // Check if it's a message set
- if (descriptor->is_extension() &&
- descriptor->containing_type()->options().message_set_wire_format() &&
- descriptor->type() == FieldDescriptor::TYPE_MESSAGE &&
- descriptor->label() == FieldDescriptor::LABEL_OPTIONAL) {
- ScopedPyObjectPtr message_name(PyString_FromStringAndSize(
- descriptor->message_type()->full_name().c_str(),
- descriptor->message_type()->full_name().size()));
- if (message_name == NULL) {
- return NULL;
- }
- PyDict_SetItem(extensions_by_name.get(), message_name.get(),
- extension_handle);
- }
-
- Py_RETURN_NONE;
-}
-
-static PyObject* SetInParent(CMessage* self, PyObject* args) {
- AssureWritable(self);
- Py_RETURN_NONE;
-}
-
-static PyObject* WhichOneof(CMessage* self, PyObject* arg) {
- Py_ssize_t name_size;
- char *name_data;
- if (PyString_AsStringAndSize(arg, &name_data, &name_size) < 0)
- return NULL;
- string oneof_name = string(name_data, name_size);
- const OneofDescriptor* oneof_desc =
- self->message->GetDescriptor()->FindOneofByName(oneof_name);
- if (oneof_desc == NULL) {
- PyErr_Format(PyExc_ValueError,
- "Protocol message has no oneof \"%s\" field.",
- oneof_name.c_str());
- return NULL;
- }
- const FieldDescriptor* field_in_oneof =
- self->message->GetReflection()->GetOneofFieldDescriptor(
- *self->message, oneof_desc);
- if (field_in_oneof == NULL) {
- Py_RETURN_NONE;
- } else {
- const string& name = field_in_oneof->name();
- return PyString_FromStringAndSize(name.c_str(), name.size());
- }
-}
-
-static PyObject* GetExtensionDict(CMessage* self, void *closure);
-
-static PyObject* ListFields(CMessage* self) {
- vector<const FieldDescriptor*> fields;
- self->message->GetReflection()->ListFields(*self->message, &fields);
-
- // Normally, the list will be exactly the size of the fields.
- ScopedPyObjectPtr all_fields(PyList_New(fields.size()));
- if (all_fields == NULL) {
- return NULL;
- }
-
- // When there are unknown extensions, the py list will *not* contain
- // the field information. Thus the actual size of the py list will be
- // smaller than the size of fields. Set the actual size at the end.
- Py_ssize_t actual_size = 0;
- for (size_t i = 0; i < fields.size(); ++i) {
- ScopedPyObjectPtr t(PyTuple_New(2));
- if (t == NULL) {
- return NULL;
- }
-
- if (fields[i]->is_extension()) {
- ScopedPyObjectPtr extension_field(
- PyFieldDescriptor_FromDescriptor(fields[i]));
- if (extension_field == NULL) {
- return NULL;
- }
- // With C++ descriptors, the field can always be retrieved, but for
- // unknown extensions which have not been imported in Python code, there
- // is no message class and we cannot retrieve the value.
- // TODO(amauryfa): consider building the class on the fly!
- if (fields[i]->message_type() != NULL &&
- cdescriptor_pool::GetMessageClass(
- GetDescriptorPoolForMessage(self),
- fields[i]->message_type()) == NULL) {
- PyErr_Clear();
- continue;
- }
- ScopedPyObjectPtr extensions(GetExtensionDict(self, NULL));
- if (extensions == NULL) {
- return NULL;
- }
- // 'extension' reference later stolen by PyTuple_SET_ITEM.
- PyObject* extension = PyObject_GetItem(
- extensions.get(), extension_field.get());
- if (extension == NULL) {
- return NULL;
- }
- PyTuple_SET_ITEM(t.get(), 0, extension_field.release());
- // Steals reference to 'extension'
- PyTuple_SET_ITEM(t.get(), 1, extension);
- } else {
- // Normal field
- const string& field_name = fields[i]->name();
- ScopedPyObjectPtr py_field_name(PyString_FromStringAndSize(
- field_name.c_str(), field_name.length()));
- if (py_field_name == NULL) {
- PyErr_SetString(PyExc_ValueError, "bad string");
- return NULL;
- }
- ScopedPyObjectPtr field_descriptor(
- PyFieldDescriptor_FromDescriptor(fields[i]));
- if (field_descriptor == NULL) {
- return NULL;
- }
-
- PyObject* field_value = GetAttr(self, py_field_name.get());
- if (field_value == NULL) {
- PyErr_SetObject(PyExc_ValueError, py_field_name.get());
- return NULL;
- }
- PyTuple_SET_ITEM(t.get(), 0, field_descriptor.release());
- PyTuple_SET_ITEM(t.get(), 1, field_value);
- }
- PyList_SET_ITEM(all_fields.get(), actual_size, t.release());
- ++actual_size;
- }
- if (static_cast<size_t>(actual_size) != fields.size() &&
- (PyList_SetSlice(all_fields.get(), actual_size, fields.size(), NULL) <
- 0)) {
- return NULL;
- }
- return all_fields.release();
-}
-
-static PyObject* DiscardUnknownFields(CMessage* self) {
- AssureWritable(self);
- self->message->DiscardUnknownFields();
- Py_RETURN_NONE;
-}
-
-PyObject* FindInitializationErrors(CMessage* self) {
- Message* message = self->message;
- vector<string> errors;
- message->FindInitializationErrors(&errors);
-
- PyObject* error_list = PyList_New(errors.size());
- if (error_list == NULL) {
- return NULL;
- }
- for (size_t i = 0; i < errors.size(); ++i) {
- const string& error = errors[i];
- PyObject* error_string = PyString_FromStringAndSize(
- error.c_str(), error.length());
- if (error_string == NULL) {
- Py_DECREF(error_list);
- return NULL;
- }
- PyList_SET_ITEM(error_list, i, error_string);
- }
- return error_list;
-}
-
-static PyObject* RichCompare(CMessage* self, PyObject* other, int opid) {
- // Only equality comparisons are implemented.
- if (opid != Py_EQ && opid != Py_NE) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- bool equals = true;
- // If other is not a message, it cannot be equal.
- if (!PyObject_TypeCheck(other, &CMessage_Type)) {
- equals = false;
- }
- const google::protobuf::Message* other_message =
- reinterpret_cast<CMessage*>(other)->message;
- // If messages don't have the same descriptors, they are not equal.
- if (equals &&
- self->message->GetDescriptor() != other_message->GetDescriptor()) {
- equals = false;
- }
- // Check the message contents.
- if (equals && !google::protobuf::util::MessageDifferencer::Equals(
- *self->message,
- *reinterpret_cast<CMessage*>(other)->message)) {
- equals = false;
- }
- if (equals ^ (opid == Py_EQ)) {
- Py_RETURN_FALSE;
- } else {
- Py_RETURN_TRUE;
- }
-}
-
-PyObject* InternalGetScalar(const Message* message,
- const FieldDescriptor* field_descriptor) {
- const Reflection* reflection = message->GetReflection();
-
- if (!CheckFieldBelongsToMessage(field_descriptor, message)) {
- return NULL;
- }
-
- PyObject* result = NULL;
- switch (field_descriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32: {
- int32 value = reflection->GetInt32(*message, field_descriptor);
- result = PyInt_FromLong(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_INT64: {
- int64 value = reflection->GetInt64(*message, field_descriptor);
- result = PyLong_FromLongLong(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT32: {
- uint32 value = reflection->GetUInt32(*message, field_descriptor);
- result = PyInt_FromSize_t(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT64: {
- uint64 value = reflection->GetUInt64(*message, field_descriptor);
- result = PyLong_FromUnsignedLongLong(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_FLOAT: {
- float value = reflection->GetFloat(*message, field_descriptor);
- result = PyFloat_FromDouble(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_DOUBLE: {
- double value = reflection->GetDouble(*message, field_descriptor);
- result = PyFloat_FromDouble(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_BOOL: {
- bool value = reflection->GetBool(*message, field_descriptor);
- result = PyBool_FromLong(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- string value = reflection->GetString(*message, field_descriptor);
- result = ToStringObject(field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_ENUM: {
- if (!message->GetReflection()->SupportsUnknownEnumValues() &&
- !message->GetReflection()->HasField(*message, field_descriptor)) {
- // Look for the value in the unknown fields.
- const UnknownFieldSet& unknown_field_set =
- message->GetReflection()->GetUnknownFields(*message);
- for (int i = 0; i < unknown_field_set.field_count(); ++i) {
- if (unknown_field_set.field(i).number() ==
- field_descriptor->number() &&
- unknown_field_set.field(i).type() ==
- google::protobuf::UnknownField::TYPE_VARINT) {
- result = PyInt_FromLong(unknown_field_set.field(i).varint());
- break;
- }
- }
- }
-
- if (result == NULL) {
- const EnumValueDescriptor* enum_value =
- message->GetReflection()->GetEnum(*message, field_descriptor);
- result = PyInt_FromLong(enum_value->number());
- }
- break;
- }
- default:
- PyErr_Format(
- PyExc_SystemError, "Getting a value from a field of unknown type %d",
- field_descriptor->cpp_type());
- }
-
- return result;
-}
-
-PyObject* InternalGetSubMessage(
- CMessage* self, const FieldDescriptor* field_descriptor) {
- const Reflection* reflection = self->message->GetReflection();
- PyDescriptorPool* pool = GetDescriptorPoolForMessage(self);
- const Message& sub_message = reflection->GetMessage(
- *self->message, field_descriptor, pool->message_factory);
-
- CMessageClass* message_class = cdescriptor_pool::GetMessageClass(
- pool, field_descriptor->message_type());
- if (message_class == NULL) {
- return NULL;
- }
-
- CMessage* cmsg = cmessage::NewEmptyMessage(message_class);
- if (cmsg == NULL) {
- return NULL;
- }
-
- cmsg->owner = self->owner;
- cmsg->parent = self;
- cmsg->parent_field_descriptor = field_descriptor;
- cmsg->read_only = !reflection->HasField(*self->message, field_descriptor);
- cmsg->message = const_cast<Message*>(&sub_message);
-
- return reinterpret_cast<PyObject*>(cmsg);
-}
-
-int InternalSetNonOneofScalar(
- Message* message,
- const FieldDescriptor* field_descriptor,
- PyObject* arg) {
- const Reflection* reflection = message->GetReflection();
-
- if (!CheckFieldBelongsToMessage(field_descriptor, message)) {
- return -1;
- }
-
- switch (field_descriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32: {
- GOOGLE_CHECK_GET_INT32(arg, value, -1);
- reflection->SetInt32(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_INT64: {
- GOOGLE_CHECK_GET_INT64(arg, value, -1);
- reflection->SetInt64(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT32: {
- GOOGLE_CHECK_GET_UINT32(arg, value, -1);
- reflection->SetUInt32(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT64: {
- GOOGLE_CHECK_GET_UINT64(arg, value, -1);
- reflection->SetUInt64(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_FLOAT: {
- GOOGLE_CHECK_GET_FLOAT(arg, value, -1);
- reflection->SetFloat(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_DOUBLE: {
- GOOGLE_CHECK_GET_DOUBLE(arg, value, -1);
- reflection->SetDouble(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_BOOL: {
- GOOGLE_CHECK_GET_BOOL(arg, value, -1);
- reflection->SetBool(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- if (!CheckAndSetString(
- arg, message, field_descriptor, reflection, false, -1)) {
- return -1;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_ENUM: {
- GOOGLE_CHECK_GET_INT32(arg, value, -1);
- if (reflection->SupportsUnknownEnumValues()) {
- reflection->SetEnumValue(message, field_descriptor, value);
- } else {
- const EnumDescriptor* enum_descriptor = field_descriptor->enum_type();
- const EnumValueDescriptor* enum_value =
- enum_descriptor->FindValueByNumber(value);
- if (enum_value != NULL) {
- reflection->SetEnum(message, field_descriptor, enum_value);
- } else {
- PyErr_Format(PyExc_ValueError, "Unknown enum value: %d", value);
- return -1;
- }
- }
- break;
- }
- default:
- PyErr_Format(
- PyExc_SystemError, "Setting value to a field of unknown type %d",
- field_descriptor->cpp_type());
- return -1;
- }
-
- return 0;
-}
-
-int InternalSetScalar(
- CMessage* self,
- const FieldDescriptor* field_descriptor,
- PyObject* arg) {
- if (!CheckFieldBelongsToMessage(field_descriptor, self->message)) {
- return -1;
- }
-
- if (MaybeReleaseOverlappingOneofField(self, field_descriptor) < 0) {
- return -1;
- }
-
- return InternalSetNonOneofScalar(self->message, field_descriptor, arg);
-}
-
-PyObject* FromString(PyTypeObject* cls, PyObject* serialized) {
- PyObject* py_cmsg = PyObject_CallObject(
- reinterpret_cast<PyObject*>(cls), NULL);
- if (py_cmsg == NULL) {
- return NULL;
- }
- CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
-
- ScopedPyObjectPtr py_length(MergeFromString(cmsg, serialized));
- if (py_length == NULL) {
- Py_DECREF(py_cmsg);
- return NULL;
- }
-
- return py_cmsg;
-}
-
-PyObject* DeepCopy(CMessage* self, PyObject* arg) {
- PyObject* clone = PyObject_CallObject(
- reinterpret_cast<PyObject*>(Py_TYPE(self)), NULL);
- if (clone == NULL) {
- return NULL;
- }
- if (!PyObject_TypeCheck(clone, &CMessage_Type)) {
- Py_DECREF(clone);
- return NULL;
- }
- if (ScopedPyObjectPtr(MergeFrom(
- reinterpret_cast<CMessage*>(clone),
- reinterpret_cast<PyObject*>(self))) == NULL) {
- Py_DECREF(clone);
- return NULL;
- }
- return clone;
-}
-
-PyObject* ToUnicode(CMessage* self) {
- // Lazy import to prevent circular dependencies
- ScopedPyObjectPtr text_format(
- PyImport_ImportModule("google.protobuf.text_format"));
- if (text_format == NULL) {
- return NULL;
- }
- ScopedPyObjectPtr method_name(PyString_FromString("MessageToString"));
- if (method_name == NULL) {
- return NULL;
- }
- Py_INCREF(Py_True);
- ScopedPyObjectPtr encoded(PyObject_CallMethodObjArgs(
- text_format.get(), method_name.get(), self, Py_True, NULL));
- Py_DECREF(Py_True);
- if (encoded == NULL) {
- return NULL;
- }
-#if PY_MAJOR_VERSION < 3
- PyObject* decoded = PyString_AsDecodedObject(encoded.get(), "utf-8", NULL);
-#else
- PyObject* decoded = PyUnicode_FromEncodedObject(encoded.get(), "utf-8", NULL);
-#endif
- if (decoded == NULL) {
- return NULL;
- }
- return decoded;
-}
-
-PyObject* Reduce(CMessage* self) {
- ScopedPyObjectPtr constructor(reinterpret_cast<PyObject*>(Py_TYPE(self)));
- constructor.inc();
- ScopedPyObjectPtr args(PyTuple_New(0));
- if (args == NULL) {
- return NULL;
- }
- ScopedPyObjectPtr state(PyDict_New());
- if (state == NULL) {
- return NULL;
- }
- ScopedPyObjectPtr serialized(SerializePartialToString(self));
- if (serialized == NULL) {
- return NULL;
- }
- if (PyDict_SetItemString(state.get(), "serialized", serialized.get()) < 0) {
- return NULL;
- }
- return Py_BuildValue("OOO", constructor.get(), args.get(), state.get());
-}
-
-PyObject* SetState(CMessage* self, PyObject* state) {
- if (!PyDict_Check(state)) {
- PyErr_SetString(PyExc_TypeError, "state not a dict");
- return NULL;
- }
- PyObject* serialized = PyDict_GetItemString(state, "serialized");
- if (serialized == NULL) {
- return NULL;
- }
- if (ScopedPyObjectPtr(ParseFromString(self, serialized)) == NULL) {
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-// CMessage static methods:
-PyObject* _CheckCalledFromGeneratedFile(PyObject* unused,
- PyObject* unused_arg) {
- if (!_CalledFromGeneratedFile(1)) {
- PyErr_SetString(PyExc_TypeError,
- "Descriptors should not be created directly, "
- "but only retrieved from their parent.");
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-static PyObject* GetExtensionDict(CMessage* self, void *closure) {
- if (self->extensions) {
- Py_INCREF(self->extensions);
- return reinterpret_cast<PyObject*>(self->extensions);
- }
-
- // If there are extension_ranges, the message is "extendable". Allocate a
- // dictionary to store the extension fields.
- const Descriptor* descriptor = GetMessageDescriptor(Py_TYPE(self));
- if (descriptor->extension_range_count() > 0) {
- ExtensionDict* extension_dict = extension_dict::NewExtensionDict(self);
- if (extension_dict == NULL) {
- return NULL;
- }
- self->extensions = extension_dict;
- Py_INCREF(self->extensions);
- return reinterpret_cast<PyObject*>(self->extensions);
- }
-
- PyErr_SetNone(PyExc_AttributeError);
- return NULL;
-}
-
-static PyGetSetDef Getters[] = {
- {"Extensions", (getter)GetExtensionDict, NULL, "Extension dict"},
- {NULL}
-};
-
-static PyMethodDef Methods[] = {
- { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
- "Makes a deep copy of the class." },
- { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
- "Outputs picklable representation of the message." },
- { "__setstate__", (PyCFunction)SetState, METH_O,
- "Inputs picklable representation of the message." },
- { "__unicode__", (PyCFunction)ToUnicode, METH_NOARGS,
- "Outputs a unicode representation of the message." },
- { "ByteSize", (PyCFunction)ByteSize, METH_NOARGS,
- "Returns the size of the message in bytes." },
- { "Clear", (PyCFunction)Clear, METH_NOARGS,
- "Clears the message." },
- { "ClearExtension", (PyCFunction)ClearExtension, METH_O,
- "Clears a message field." },
- { "ClearField", (PyCFunction)ClearField, METH_O,
- "Clears a message field." },
- { "CopyFrom", (PyCFunction)CopyFrom, METH_O,
- "Copies a protocol message into the current message." },
- { "DiscardUnknownFields", (PyCFunction)DiscardUnknownFields, METH_NOARGS,
- "Discards the unknown fields." },
- { "FindInitializationErrors", (PyCFunction)FindInitializationErrors,
- METH_NOARGS,
- "Finds unset required fields." },
- { "FromString", (PyCFunction)FromString, METH_O | METH_CLASS,
- "Creates new method instance from given serialized data." },
- { "HasExtension", (PyCFunction)HasExtension, METH_O,
- "Checks if a message field is set." },
- { "HasField", (PyCFunction)HasField, METH_O,
- "Checks if a message field is set." },
- { "IsInitialized", (PyCFunction)IsInitialized, METH_VARARGS,
- "Checks if all required fields of a protocol message are set." },
- { "ListFields", (PyCFunction)ListFields, METH_NOARGS,
- "Lists all set fields of a message." },
- { "MergeFrom", (PyCFunction)MergeFrom, METH_O,
- "Merges a protocol message into the current message." },
- { "MergeFromString", (PyCFunction)MergeFromString, METH_O,
- "Merges a serialized message into the current message." },
- { "ParseFromString", (PyCFunction)ParseFromString, METH_O,
- "Parses a serialized message into the current message." },
- { "RegisterExtension", (PyCFunction)RegisterExtension, METH_O | METH_CLASS,
- "Registers an extension with the current message." },
- { "SerializePartialToString", (PyCFunction)SerializePartialToString,
- METH_NOARGS,
- "Serializes the message to a string, even if it isn't initialized." },
- { "SerializeToString", (PyCFunction)SerializeToString, METH_NOARGS,
- "Serializes the message to a string, only for initialized messages." },
- { "SetInParent", (PyCFunction)SetInParent, METH_NOARGS,
- "Sets the has bit of the given field in its parent message." },
- { "WhichOneof", (PyCFunction)WhichOneof, METH_O,
- "Returns the name of the field set inside a oneof, "
- "or None if no field is set." },
-
- // Static Methods.
- { "_CheckCalledFromGeneratedFile", (PyCFunction)_CheckCalledFromGeneratedFile,
- METH_NOARGS | METH_STATIC,
- "Raises TypeError if the caller is not in a _pb2.py file."},
- { NULL, NULL}
-};
-
-static bool SetCompositeField(
- CMessage* self, PyObject* name, PyObject* value) {
- if (self->composite_fields == NULL) {
- self->composite_fields = PyDict_New();
- if (self->composite_fields == NULL) {
- return false;
- }
- }
- return PyDict_SetItem(self->composite_fields, name, value) == 0;
-}
-
-PyObject* GetAttr(CMessage* self, PyObject* name) {
- PyObject* value = self->composite_fields ?
- PyDict_GetItem(self->composite_fields, name) : NULL;
- if (value != NULL) {
- Py_INCREF(value);
- return value;
- }
-
- const FieldDescriptor* field_descriptor = GetFieldDescriptor(self, name);
- if (field_descriptor == NULL) {
- return CMessage_Type.tp_base->tp_getattro(
- reinterpret_cast<PyObject*>(self), name);
- }
-
- if (field_descriptor->is_map()) {
- PyObject* py_container = NULL;
- const Descriptor* entry_type = field_descriptor->message_type();
- const FieldDescriptor* value_type = entry_type->FindFieldByName("value");
- if (value_type->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- CMessageClass* value_class = cdescriptor_pool::GetMessageClass(
- GetDescriptorPoolForMessage(self), value_type->message_type());
- if (value_class == NULL) {
- return NULL;
- }
- py_container =
- NewMessageMapContainer(self, field_descriptor, value_class);
- } else {
- py_container = NewScalarMapContainer(self, field_descriptor);
- }
- if (py_container == NULL) {
- return NULL;
- }
- if (!SetCompositeField(self, name, py_container)) {
- Py_DECREF(py_container);
- return NULL;
- }
- return py_container;
- }
-
- if (field_descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
- PyObject* py_container = NULL;
- if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- CMessageClass* message_class = cdescriptor_pool::GetMessageClass(
- GetDescriptorPoolForMessage(self), field_descriptor->message_type());
- if (message_class == NULL) {
- return NULL;
- }
- py_container = repeated_composite_container::NewContainer(
- self, field_descriptor, message_class);
- } else {
- py_container = repeated_scalar_container::NewContainer(
- self, field_descriptor);
- }
- if (py_container == NULL) {
- return NULL;
- }
- if (!SetCompositeField(self, name, py_container)) {
- Py_DECREF(py_container);
- return NULL;
- }
- return py_container;
- }
-
- if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- PyObject* sub_message = InternalGetSubMessage(self, field_descriptor);
- if (sub_message == NULL) {
- return NULL;
- }
- if (!SetCompositeField(self, name, sub_message)) {
- Py_DECREF(sub_message);
- return NULL;
- }
- return sub_message;
- }
-
- return InternalGetScalar(self->message, field_descriptor);
-}
-
-int SetAttr(CMessage* self, PyObject* name, PyObject* value) {
- if (self->composite_fields && PyDict_Contains(self->composite_fields, name)) {
- PyErr_SetString(PyExc_TypeError, "Can't set composite field");
- return -1;
- }
-
- const FieldDescriptor* field_descriptor = GetFieldDescriptor(self, name);
- if (field_descriptor != NULL) {
- AssureWritable(self);
- if (field_descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
- PyErr_Format(PyExc_AttributeError, "Assignment not allowed to repeated "
- "field \"%s\" in protocol message object.",
- field_descriptor->name().c_str());
- return -1;
- } else {
- if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- PyErr_Format(PyExc_AttributeError, "Assignment not allowed to "
- "field \"%s\" in protocol message object.",
- field_descriptor->name().c_str());
- return -1;
- } else {
- return InternalSetScalar(self, field_descriptor, value);
- }
- }
- }
-
- PyErr_Format(PyExc_AttributeError,
- "Assignment not allowed "
- "(no field \"%s\" in protocol message object).",
- PyString_AsString(name));
- return -1;
-}
-
-} // namespace cmessage
-
-PyTypeObject CMessage_Type = {
- PyVarObject_HEAD_INIT(&CMessageClass_Type, 0)
- FULL_MODULE_NAME ".CMessage", // tp_name
- sizeof(CMessage), // tp_basicsize
- 0, // tp_itemsize
- (destructor)cmessage::Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- (reprfunc)cmessage::ToStr, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- PyObject_HashNotImplemented, // tp_hash
- 0, // tp_call
- (reprfunc)cmessage::ToStr, // tp_str
- (getattrofunc)cmessage::GetAttr, // tp_getattro
- (setattrofunc)cmessage::SetAttr, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags
- "A ProtocolMessage", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- (richcmpfunc)cmessage::RichCompare, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- cmessage::Methods, // tp_methods
- 0, // tp_members
- cmessage::Getters, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- (initproc)cmessage::Init, // tp_init
- 0, // tp_alloc
- cmessage::New, // tp_new
-};
-
-// --- Exposing the C proto living inside Python proto to C code:
-
-const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg);
-Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg);
-
-static const Message* GetCProtoInsidePyProtoImpl(PyObject* msg) {
- if (!PyObject_TypeCheck(msg, &CMessage_Type)) {
- return NULL;
- }
- CMessage* cmsg = reinterpret_cast<CMessage*>(msg);
- return cmsg->message;
-}
-
-static Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) {
- if (!PyObject_TypeCheck(msg, &CMessage_Type)) {
- return NULL;
- }
- CMessage* cmsg = reinterpret_cast<CMessage*>(msg);
- if ((cmsg->composite_fields && PyDict_Size(cmsg->composite_fields) != 0) ||
- (cmsg->extensions != NULL &&
- PyDict_Size(cmsg->extensions->values) != 0)) {
- // There is currently no way of accurately syncing arbitrary changes to
- // the underlying C++ message back to the CMessage (e.g. removed repeated
- // composite containers). We only allow direct mutation of the underlying
- // C++ message if there is no child data in the CMessage.
- return NULL;
- }
- cmessage::AssureWritable(cmsg);
- return cmsg->message;
-}
-
-static const char module_docstring[] =
-"python-proto2 is a module that can be used to enhance proto2 Python API\n"
-"performance.\n"
-"\n"
-"It provides access to the protocol buffers C++ reflection API that\n"
-"implements the basic protocol buffer functions.";
-
-void InitGlobals() {
- // TODO(gps): Check all return values in this function for NULL and propagate
- // the error (MemoryError) on up to result in an import failure. These should
- // also be freed and reset to NULL during finalization.
- kPythonZero = PyInt_FromLong(0);
- kint32min_py = PyInt_FromLong(kint32min);
- kint32max_py = PyInt_FromLong(kint32max);
- kuint32max_py = PyLong_FromLongLong(kuint32max);
- kint64min_py = PyLong_FromLongLong(kint64min);
- kint64max_py = PyLong_FromLongLong(kint64max);
- kuint64max_py = PyLong_FromUnsignedLongLong(kuint64max);
-
- kDESCRIPTOR = PyString_FromString("DESCRIPTOR");
- k_cdescriptor = PyString_FromString("_cdescriptor");
- kfull_name = PyString_FromString("full_name");
- k_extensions_by_name = PyString_FromString("_extensions_by_name");
- k_extensions_by_number = PyString_FromString("_extensions_by_number");
-
- PyObject *dummy_obj = PySet_New(NULL);
- kEmptyWeakref = PyWeakref_NewRef(dummy_obj, NULL);
- Py_DECREF(dummy_obj);
-}
-
-bool InitProto2MessageModule(PyObject *m) {
- // Initialize types and globals in descriptor.cc
- if (!InitDescriptor()) {
- return false;
- }
-
- // Initialize types and globals in descriptor_pool.cc
- if (!InitDescriptorPool()) {
- return false;
- }
-
- // Initialize constants defined in this file.
- InitGlobals();
-
- CMessageClass_Type.tp_base = &PyType_Type;
- if (PyType_Ready(&CMessageClass_Type) < 0) {
- return false;
- }
- PyModule_AddObject(m, "MessageMeta",
- reinterpret_cast<PyObject*>(&CMessageClass_Type));
-
- if (PyType_Ready(&CMessage_Type) < 0) {
- return false;
- }
-
- // DESCRIPTOR is set on each protocol buffer message class elsewhere, but set
- // it here as well to document that subclasses need to set it.
- PyDict_SetItem(CMessage_Type.tp_dict, kDESCRIPTOR, Py_None);
- // Subclasses with message extensions will override _extensions_by_name and
- // _extensions_by_number with fresh mutable dictionaries in AddDescriptors.
- // All other classes can share this same immutable mapping.
- ScopedPyObjectPtr empty_dict(PyDict_New());
- if (empty_dict == NULL) {
- return false;
- }
- ScopedPyObjectPtr immutable_dict(PyDictProxy_New(empty_dict.get()));
- if (immutable_dict == NULL) {
- return false;
- }
- if (PyDict_SetItem(CMessage_Type.tp_dict,
- k_extensions_by_name, immutable_dict.get()) < 0) {
- return false;
- }
- if (PyDict_SetItem(CMessage_Type.tp_dict,
- k_extensions_by_number, immutable_dict.get()) < 0) {
- return false;
- }
-
- PyModule_AddObject(m, "Message", reinterpret_cast<PyObject*>(&CMessage_Type));
-
- // Initialize Repeated container types.
- {
- if (PyType_Ready(&RepeatedScalarContainer_Type) < 0) {
- return false;
- }
-
- PyModule_AddObject(m, "RepeatedScalarContainer",
- reinterpret_cast<PyObject*>(
- &RepeatedScalarContainer_Type));
-
- if (PyType_Ready(&RepeatedCompositeContainer_Type) < 0) {
- return false;
- }
-
- PyModule_AddObject(
- m, "RepeatedCompositeContainer",
- reinterpret_cast<PyObject*>(
- &RepeatedCompositeContainer_Type));
-
- // Register them as collections.Sequence
- ScopedPyObjectPtr collections(PyImport_ImportModule("collections"));
- if (collections == NULL) {
- return false;
- }
- ScopedPyObjectPtr mutable_sequence(
- PyObject_GetAttrString(collections.get(), "MutableSequence"));
- if (mutable_sequence == NULL) {
- return false;
- }
- if (ScopedPyObjectPtr(
- PyObject_CallMethod(mutable_sequence.get(), "register", "O",
- &RepeatedScalarContainer_Type)) == NULL) {
- return false;
- }
- if (ScopedPyObjectPtr(
- PyObject_CallMethod(mutable_sequence.get(), "register", "O",
- &RepeatedCompositeContainer_Type)) == NULL) {
- return false;
- }
- }
-
- // Initialize Map container types.
- {
- // ScalarMapContainer_Type derives from our MutableMapping type.
- ScopedPyObjectPtr containers(PyImport_ImportModule(
- "google.protobuf.internal.containers"));
- if (containers == NULL) {
- return false;
- }
-
- ScopedPyObjectPtr mutable_mapping(
- PyObject_GetAttrString(containers.get(), "MutableMapping"));
- if (mutable_mapping == NULL) {
- return false;
- }
-
- if (!PyObject_TypeCheck(mutable_mapping.get(), &PyType_Type)) {
- return false;
- }
-
- Py_INCREF(mutable_mapping.get());
-#if PY_MAJOR_VERSION >= 3
- PyObject* bases = PyTuple_New(1);
- PyTuple_SET_ITEM(bases, 0, mutable_mapping.get());
-
- ScalarMapContainer_Type =
- PyType_FromSpecWithBases(&ScalarMapContainer_Type_spec, bases);
- PyModule_AddObject(m, "ScalarMapContainer", ScalarMapContainer_Type);
-#else
- ScalarMapContainer_Type.tp_base =
- reinterpret_cast<PyTypeObject*>(mutable_mapping.get());
-
- if (PyType_Ready(&ScalarMapContainer_Type) < 0) {
- return false;
- }
-
- PyModule_AddObject(m, "ScalarMapContainer",
- reinterpret_cast<PyObject*>(&ScalarMapContainer_Type));
-#endif
-
- if (PyType_Ready(&MapIterator_Type) < 0) {
- return false;
- }
-
- PyModule_AddObject(m, "MapIterator",
- reinterpret_cast<PyObject*>(&MapIterator_Type));
-
-
-#if PY_MAJOR_VERSION >= 3
- MessageMapContainer_Type =
- PyType_FromSpecWithBases(&MessageMapContainer_Type_spec, bases);
- PyModule_AddObject(m, "MessageMapContainer", MessageMapContainer_Type);
-#else
- Py_INCREF(mutable_mapping.get());
- MessageMapContainer_Type.tp_base =
- reinterpret_cast<PyTypeObject*>(mutable_mapping.get());
-
- if (PyType_Ready(&MessageMapContainer_Type) < 0) {
- return false;
- }
-
- PyModule_AddObject(m, "MessageMapContainer",
- reinterpret_cast<PyObject*>(&MessageMapContainer_Type));
-#endif
- }
-
- if (PyType_Ready(&ExtensionDict_Type) < 0) {
- return false;
- }
- PyModule_AddObject(
- m, "ExtensionDict",
- reinterpret_cast<PyObject*>(&ExtensionDict_Type));
-
- // Expose the DescriptorPool used to hold all descriptors added from generated
- // pb2.py files.
- // PyModule_AddObject steals a reference.
- Py_INCREF(GetDefaultDescriptorPool());
- PyModule_AddObject(m, "default_pool",
- reinterpret_cast<PyObject*>(GetDefaultDescriptorPool()));
-
- PyModule_AddObject(m, "DescriptorPool", reinterpret_cast<PyObject*>(
- &PyDescriptorPool_Type));
-
- // This implementation provides full Descriptor types, we advertise it so that
- // descriptor.py can use them in replacement of the Python classes.
- PyModule_AddIntConstant(m, "_USE_C_DESCRIPTORS", 1);
-
- PyModule_AddObject(m, "Descriptor", reinterpret_cast<PyObject*>(
- &PyMessageDescriptor_Type));
- PyModule_AddObject(m, "FieldDescriptor", reinterpret_cast<PyObject*>(
- &PyFieldDescriptor_Type));
- PyModule_AddObject(m, "EnumDescriptor", reinterpret_cast<PyObject*>(
- &PyEnumDescriptor_Type));
- PyModule_AddObject(m, "EnumValueDescriptor", reinterpret_cast<PyObject*>(
- &PyEnumValueDescriptor_Type));
- PyModule_AddObject(m, "FileDescriptor", reinterpret_cast<PyObject*>(
- &PyFileDescriptor_Type));
- PyModule_AddObject(m, "OneofDescriptor", reinterpret_cast<PyObject*>(
- &PyOneofDescriptor_Type));
- PyModule_AddObject(m, "ServiceDescriptor", reinterpret_cast<PyObject*>(
- &PyServiceDescriptor_Type));
- PyModule_AddObject(m, "MethodDescriptor", reinterpret_cast<PyObject*>(
- &PyMethodDescriptor_Type));
-
- PyObject* enum_type_wrapper = PyImport_ImportModule(
- "google.protobuf.internal.enum_type_wrapper");
- if (enum_type_wrapper == NULL) {
- return false;
- }
- EnumTypeWrapper_class =
- PyObject_GetAttrString(enum_type_wrapper, "EnumTypeWrapper");
- Py_DECREF(enum_type_wrapper);
-
- PyObject* message_module = PyImport_ImportModule(
- "google.protobuf.message");
- if (message_module == NULL) {
- return false;
- }
- EncodeError_class = PyObject_GetAttrString(message_module, "EncodeError");
- DecodeError_class = PyObject_GetAttrString(message_module, "DecodeError");
- PythonMessage_class = PyObject_GetAttrString(message_module, "Message");
- Py_DECREF(message_module);
-
- PyObject* pickle_module = PyImport_ImportModule("pickle");
- if (pickle_module == NULL) {
- return false;
- }
- PickleError_class = PyObject_GetAttrString(pickle_module, "PickleError");
- Py_DECREF(pickle_module);
-
- // Override {Get,Mutable}CProtoInsidePyProto.
- GetCProtoInsidePyProtoPtr = GetCProtoInsidePyProtoImpl;
- MutableCProtoInsidePyProtoPtr = MutableCProtoInsidePyProtoImpl;
-
- return true;
-}
-
-} // namespace python
-} // namespace protobuf
-
-} // namespace google
diff --git a/python/google/protobuf/pyext/message.h b/python/google/protobuf/pyext/message.h
deleted file mode 100644
index 8b399e05..00000000
--- a/python/google/protobuf/pyext/message.h
+++ /dev/null
@@ -1,365 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: anuraag@google.com (Anuraag Agrawal)
-// Author: tibell@google.com (Johan Tibell)
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__
-#define GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__
-
-#include <Python.h>
-
-#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
-#include <string>
-
-namespace google {
-namespace protobuf {
-
-class Message;
-class Reflection;
-class FieldDescriptor;
-class Descriptor;
-class DescriptorPool;
-class MessageFactory;
-
-#ifdef _SHARED_PTR_H
-using std::shared_ptr;
-using std::string;
-#else
-using internal::shared_ptr;
-#endif
-
-namespace python {
-
-struct ExtensionDict;
-struct PyDescriptorPool;
-
-typedef struct CMessage {
- PyObject_HEAD;
-
- // This is the top-level C++ Message object that owns the whole
- // proto tree. Every Python CMessage holds a reference to it in
- // order to keep it alive as long as there's a Python object that
- // references any part of the tree.
- shared_ptr<Message> owner;
-
- // Weak reference to a parent CMessage object. This is NULL for any top-level
- // message and is set for any child message (i.e. a child submessage or a
- // part of a repeated composite field).
- //
- // Used to make sure all ancestors are also mutable when first modifying
- // a child submessage (in other words, turning a default message instance
- // into a mutable one).
- //
- // If a submessage is released (becomes a new top-level message), this field
- // MUST be set to NULL. The parent may get deallocated and further attempts
- // to use this pointer will result in a crash.
- struct CMessage* parent;
-
- // Pointer to the parent's descriptor that describes this submessage.
- // Used together with the parent's message when making a default message
- // instance mutable.
- // The pointer is owned by the global DescriptorPool.
- const FieldDescriptor* parent_field_descriptor;
-
- // Pointer to the C++ Message object for this CMessage. The
- // CMessage does not own this pointer.
- Message* message;
-
- // Indicates this submessage is pointing to a default instance of a message.
- // Submessages are always first created as read only messages and are then
- // made writable, at which point this field is set to false.
- bool read_only;
-
- // A reference to a Python dictionary containing CMessage,
- // RepeatedCompositeContainer, and RepeatedScalarContainer
- // objects. Used as a cache to make sure we don't have to make a
- // Python wrapper for the C++ Message objects on every access, or
- // deal with the synchronization nightmare that could create.
- PyObject* composite_fields;
-
- // A reference to the dictionary containing the message's extensions.
- // Similar to composite_fields, acting as a cache, but also contains the
- // required extension dict logic.
- ExtensionDict* extensions;
-} CMessage;
-
-extern PyTypeObject CMessage_Type;
-
-
-// The (meta) type of all Messages classes.
-// It allows us to cache some C++ pointers in the class object itself, they are
-// faster to extract than from the type's dictionary.
-
-struct CMessageClass {
- // This is how CPython subclasses C structures: the base structure must be
- // the first member of the object.
- PyHeapTypeObject super;
-
- // C++ descriptor of this message.
- const Descriptor* message_descriptor;
-
- // Owned reference, used to keep the pointer above alive.
- PyObject* py_message_descriptor;
-
- // The Python DescriptorPool used to create the class. It is needed to resolve
- // fields descriptors, including extensions fields; its C++ MessageFactory is
- // used to instantiate submessages.
- // This can be different from DESCRIPTOR.file.pool, in the case of a custom
- // DescriptorPool which defines new extensions.
- // We own the reference, because it's important to keep the descriptors and
- // factory alive.
- PyDescriptorPool* py_descriptor_pool;
-
- PyObject* AsPyObject() {
- return reinterpret_cast<PyObject*>(this);
- }
-};
-
-
-namespace cmessage {
-
-// Internal function to create a new empty Message Python object, but with empty
-// pointers to the C++ objects.
-// The caller must fill self->message, self->owner and eventually self->parent.
-CMessage* NewEmptyMessage(CMessageClass* type);
-
-// Release a submessage from its proto tree, making it a new top-level messgae.
-// A new message will be created if this is a read-only default instance.
-//
-// Corresponds to reflection api method ReleaseMessage.
-int ReleaseSubMessage(CMessage* self,
- const FieldDescriptor* field_descriptor,
- CMessage* child_cmessage);
-
-// Retrieves the C++ descriptor of a Python Extension descriptor.
-// On error, return NULL with an exception set.
-const FieldDescriptor* GetExtensionDescriptor(PyObject* extension);
-
-// Initializes a new CMessage instance for a submessage. Only called once per
-// submessage as the result is cached in composite_fields.
-//
-// Corresponds to reflection api method GetMessage.
-PyObject* InternalGetSubMessage(
- CMessage* self, const FieldDescriptor* field_descriptor);
-
-// Deletes a range of C++ submessages in a repeated field (following a
-// removal in a RepeatedCompositeContainer).
-//
-// Releases messages to the provided cmessage_list if it is not NULL rather
-// than just removing them from the underlying proto. This cmessage_list must
-// have a CMessage for each underlying submessage. The CMessages referred to
-// by slice will be removed from cmessage_list by this function.
-//
-// Corresponds to reflection api method RemoveLast.
-int InternalDeleteRepeatedField(CMessage* self,
- const FieldDescriptor* field_descriptor,
- PyObject* slice, PyObject* cmessage_list);
-
-// Sets the specified scalar value to the message.
-int InternalSetScalar(CMessage* self,
- const FieldDescriptor* field_descriptor,
- PyObject* value);
-
-// Sets the specified scalar value to the message. Requires it is not a Oneof.
-int InternalSetNonOneofScalar(Message* message,
- const FieldDescriptor* field_descriptor,
- PyObject* arg);
-
-// Retrieves the specified scalar value from the message.
-//
-// Returns a new python reference.
-PyObject* InternalGetScalar(const Message* message,
- const FieldDescriptor* field_descriptor);
-
-// Clears the message, removing all contained data. Extension dictionary and
-// submessages are released first if there are remaining external references.
-//
-// Corresponds to message api method Clear.
-PyObject* Clear(CMessage* self);
-
-// Clears the data described by the given descriptor. Used to clear extensions
-// (which don't have names). Extension release is handled by ExtensionDict
-// class, not this function.
-// TODO(anuraag): Try to make this discrepancy in release semantics with
-// ClearField less confusing.
-//
-// Corresponds to reflection api method ClearField.
-PyObject* ClearFieldByDescriptor(
- CMessage* self, const FieldDescriptor* descriptor);
-
-// Clears the data for the given field name. The message is released if there
-// are any external references.
-//
-// Corresponds to reflection api method ClearField.
-PyObject* ClearField(CMessage* self, PyObject* arg);
-
-// Checks if the message has the field described by the descriptor. Used for
-// extensions (which have no name).
-//
-// Corresponds to reflection api method HasField
-PyObject* HasFieldByDescriptor(
- CMessage* self, const FieldDescriptor* field_descriptor);
-
-// Checks if the message has the named field.
-//
-// Corresponds to reflection api method HasField.
-PyObject* HasField(CMessage* self, PyObject* arg);
-
-// Initializes values of fields on a newly constructed message.
-int InitAttributes(CMessage* self, PyObject* kwargs);
-
-PyObject* MergeFrom(CMessage* self, PyObject* arg);
-
-// Retrieves an attribute named 'name' from CMessage 'self'. Returns
-// the attribute value on success, or NULL on failure.
-//
-// Returns a new reference.
-PyObject* GetAttr(CMessage* self, PyObject* name);
-
-// Set the value of the attribute named 'name', for CMessage 'self',
-// to the value 'value'. Returns -1 on failure.
-int SetAttr(CMessage* self, PyObject* name, PyObject* value);
-
-PyObject* FindInitializationErrors(CMessage* self);
-
-// Set the owner field of self and any children of self, recursively.
-// Used when self is being released and thus has a new owner (the
-// released Message.)
-int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner);
-
-int AssureWritable(CMessage* self);
-
-// Returns the "best" DescriptorPool for the given message.
-// This is often equivalent to message.DESCRIPTOR.pool, but not always, when
-// the message class was created from a MessageFactory using a custom pool which
-// uses the generated pool as an underlay.
-//
-// The returned pool is suitable for finding fields and building submessages,
-// even in the case of extensions.
-PyDescriptorPool* GetDescriptorPoolForMessage(CMessage* message);
-
-PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg);
-
-} // namespace cmessage
-
-
-/* Is 64bit */
-#define IS_64BIT (SIZEOF_LONG == 8)
-
-#define FIELD_IS_REPEATED(field_descriptor) \
- ((field_descriptor)->label() == FieldDescriptor::LABEL_REPEATED)
-
-#define GOOGLE_CHECK_GET_INT32(arg, value, err) \
- int32 value; \
- if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \
- return err; \
- }
-
-#define GOOGLE_CHECK_GET_INT64(arg, value, err) \
- int64 value; \
- if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \
- return err; \
- }
-
-#define GOOGLE_CHECK_GET_UINT32(arg, value, err) \
- uint32 value; \
- if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \
- return err; \
- }
-
-#define GOOGLE_CHECK_GET_UINT64(arg, value, err) \
- uint64 value; \
- if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \
- return err; \
- }
-
-#define GOOGLE_CHECK_GET_FLOAT(arg, value, err) \
- float value; \
- if (!CheckAndGetFloat(arg, &value)) { \
- return err; \
- } \
-
-#define GOOGLE_CHECK_GET_DOUBLE(arg, value, err) \
- double value; \
- if (!CheckAndGetDouble(arg, &value)) { \
- return err; \
- }
-
-#define GOOGLE_CHECK_GET_BOOL(arg, value, err) \
- bool value; \
- if (!CheckAndGetBool(arg, &value)) { \
- return err; \
- }
-
-
-extern PyObject* kPythonZero;
-extern PyObject* kint32min_py;
-extern PyObject* kint32max_py;
-extern PyObject* kuint32max_py;
-extern PyObject* kint64min_py;
-extern PyObject* kint64max_py;
-extern PyObject* kuint64max_py;
-
-#define FULL_MODULE_NAME "google.protobuf.pyext._message"
-
-void FormatTypeError(PyObject* arg, char* expected_types);
-template<class T>
-bool CheckAndGetInteger(
- PyObject* arg, T* value, PyObject* min, PyObject* max);
-bool CheckAndGetDouble(PyObject* arg, double* value);
-bool CheckAndGetFloat(PyObject* arg, float* value);
-bool CheckAndGetBool(PyObject* arg, bool* value);
-PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor);
-bool CheckAndSetString(
- PyObject* arg, Message* message,
- const FieldDescriptor* descriptor,
- const Reflection* reflection,
- bool append,
- int index);
-PyObject* ToStringObject(const FieldDescriptor* descriptor, string value);
-
-// Check if the passed field descriptor belongs to the given message.
-// If not, return false and set a Python exception (a KeyError)
-bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor,
- const Message* message);
-
-extern PyObject* PickleError_class;
-
-bool InitProto2MessageModule(PyObject *m);
-
-} // namespace python
-} // namespace protobuf
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__
diff --git a/python/google/protobuf/pyext/message_module.cc b/python/google/protobuf/pyext/message_module.cc
deleted file mode 100644
index d90d9de3..00000000
--- a/python/google/protobuf/pyext/message_module.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <google/protobuf/pyext/message.h>
-
-static const char module_docstring[] =
-"python-proto2 is a module that can be used to enhance proto2 Python API\n"
-"performance.\n"
-"\n"
-"It provides access to the protocol buffers C++ reflection API that\n"
-"implements the basic protocol buffer functions.";
-
-static PyMethodDef ModuleMethods[] = {
- {"SetAllowOversizeProtos",
- (PyCFunction)google::protobuf::python::cmessage::SetAllowOversizeProtos,
- METH_O, "Enable/disable oversize proto parsing."},
- { NULL, NULL}
-};
-
-#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef _module = {
- PyModuleDef_HEAD_INIT,
- "_message",
- module_docstring,
- -1,
- ModuleMethods, /* m_methods */
- NULL,
- NULL,
- NULL,
- NULL
-};
-#define INITFUNC PyInit__message
-#define INITFUNC_ERRORVAL NULL
-#else // Python 2
-#define INITFUNC init_message
-#define INITFUNC_ERRORVAL
-#endif
-
-extern "C" {
- PyMODINIT_FUNC INITFUNC(void) {
- PyObject* m;
-#if PY_MAJOR_VERSION >= 3
- m = PyModule_Create(&_module);
-#else
- m = Py_InitModule3("_message", ModuleMethods,
- module_docstring);
-#endif
- if (m == NULL) {
- return INITFUNC_ERRORVAL;
- }
-
- if (!google::protobuf::python::InitProto2MessageModule(m)) {
- Py_DECREF(m);
- return INITFUNC_ERRORVAL;
- }
-
-#if PY_MAJOR_VERSION >= 3
- return m;
-#endif
- }
-}
diff --git a/python/google/protobuf/pyext/proto2_api_test.proto b/python/google/protobuf/pyext/proto2_api_test.proto
deleted file mode 100644
index 18aecfb7..00000000
--- a/python/google/protobuf/pyext/proto2_api_test.proto
+++ /dev/null
@@ -1,40 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto2";
-
-import "google/protobuf/internal/cpp/proto1_api_test.proto";
-
-package google.protobuf.python.internal;
-
-message TestNestedProto1APIMessage {
- optional int32 a = 1;
- optional TestMessage.NestedMessage b = 2;
-}
diff --git a/python/google/protobuf/pyext/python.proto b/python/google/protobuf/pyext/python.proto
deleted file mode 100644
index cce645d7..00000000
--- a/python/google/protobuf/pyext/python.proto
+++ /dev/null
@@ -1,68 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: tibell@google.com (Johan Tibell)
-//
-// These message definitions are used to exercises known corner cases
-// in the C++ implementation of the Python API.
-
-syntax = "proto2";
-
-package google.protobuf.python.internal;
-
-// Protos optimized for SPEED use a strict superset of the generated code
-// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
-// tests for speed unless explicitly testing code size optimization.
-option optimize_for = SPEED;
-
-message TestAllTypes {
- message NestedMessage {
- optional int32 bb = 1;
- optional ForeignMessage cc = 2;
- }
-
- repeated NestedMessage repeated_nested_message = 1;
- optional NestedMessage optional_nested_message = 2;
- optional int32 optional_int32 = 3;
-}
-
-message ForeignMessage {
- optional int32 c = 1;
- repeated int32 d = 2;
-}
-
-message TestAllExtensions {
- extensions 1 to max;
-}
-
-extend TestAllExtensions {
- optional TestAllTypes.NestedMessage optional_nested_message_extension = 1;
- repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 2;
-}
diff --git a/python/google/protobuf/pyext/python_protobuf.h b/python/google/protobuf/pyext/python_protobuf.h
deleted file mode 100644
index beb6e460..00000000
--- a/python/google/protobuf/pyext/python_protobuf.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: qrczak@google.com (Marcin Kowalczyk)
-//
-// This module exposes the C proto inside the given Python proto, in
-// case the Python proto is implemented with a C proto.
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
-#define GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
-
-#include <Python.h>
-
-namespace google {
-namespace protobuf {
-
-class Message;
-
-namespace python {
-
-// Return the pointer to the C proto inside the given Python proto,
-// or NULL when this is not a Python proto implemented with a C proto.
-const Message* GetCProtoInsidePyProto(PyObject* msg);
-Message* MutableCProtoInsidePyProto(PyObject* msg);
-
-} // namespace python
-} // namespace protobuf
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc
deleted file mode 100644
index 4f339e77..00000000
--- a/python/google/protobuf/pyext/repeated_composite_container.cc
+++ /dev/null
@@ -1,612 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: anuraag@google.com (Anuraag Agrawal)
-// Author: tibell@google.com (Johan Tibell)
-
-#include <google/protobuf/pyext/repeated_composite_container.h>
-
-#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
-
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/dynamic_message.h>
-#include <google/protobuf/message.h>
-#include <google/protobuf/pyext/descriptor.h>
-#include <google/protobuf/pyext/descriptor_pool.h>
-#include <google/protobuf/pyext/message.h>
-#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
-
-#if PY_MAJOR_VERSION >= 3
- #define PyInt_Check PyLong_Check
- #define PyInt_AsLong PyLong_AsLong
- #define PyInt_FromLong PyLong_FromLong
-#endif
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-namespace repeated_composite_container {
-
-// TODO(tibell): We might also want to check:
-// GOOGLE_CHECK_NOTNULL((self)->owner.get());
-#define GOOGLE_CHECK_ATTACHED(self) \
- do { \
- GOOGLE_CHECK_NOTNULL((self)->message); \
- GOOGLE_CHECK_NOTNULL((self)->parent_field_descriptor); \
- } while (0);
-
-#define GOOGLE_CHECK_RELEASED(self) \
- do { \
- GOOGLE_CHECK((self)->owner.get() == NULL); \
- GOOGLE_CHECK((self)->message == NULL); \
- GOOGLE_CHECK((self)->parent_field_descriptor == NULL); \
- GOOGLE_CHECK((self)->parent == NULL); \
- } while (0);
-
-// ---------------------------------------------------------------------
-// len()
-
-static Py_ssize_t Length(RepeatedCompositeContainer* self) {
- Message* message = self->message;
- if (message != NULL) {
- return message->GetReflection()->FieldSize(*message,
- self->parent_field_descriptor);
- } else {
- // The container has been released (i.e. by a call to Clear() or
- // ClearField() on the parent) and thus there's no message.
- return PyList_GET_SIZE(self->child_messages);
- }
-}
-
-// Returns 0 if successful; returns -1 and sets an exception if
-// unsuccessful.
-static int UpdateChildMessages(RepeatedCompositeContainer* self) {
- if (self->message == NULL)
- return 0;
-
- // A MergeFrom on a parent message could have caused extra messages to be
- // added in the underlying protobuf so add them to our list. They can never
- // be removed in such a way so there's no need to worry about that.
- Py_ssize_t message_length = Length(self);
- Py_ssize_t child_length = PyList_GET_SIZE(self->child_messages);
- Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
- for (Py_ssize_t i = child_length; i < message_length; ++i) {
- const Message& sub_message = reflection->GetRepeatedMessage(
- *(self->message), self->parent_field_descriptor, i);
- CMessage* cmsg = cmessage::NewEmptyMessage(self->child_message_class);
- ScopedPyObjectPtr py_cmsg(reinterpret_cast<PyObject*>(cmsg));
- if (cmsg == NULL) {
- return -1;
- }
- cmsg->owner = self->owner;
- cmsg->message = const_cast<Message*>(&sub_message);
- cmsg->parent = self->parent;
- if (PyList_Append(self->child_messages, py_cmsg.get()) < 0) {
- return -1;
- }
- }
- return 0;
-}
-
-// ---------------------------------------------------------------------
-// add()
-
-static PyObject* AddToAttached(RepeatedCompositeContainer* self,
- PyObject* args,
- PyObject* kwargs) {
- GOOGLE_CHECK_ATTACHED(self);
-
- if (UpdateChildMessages(self) < 0) {
- return NULL;
- }
- if (cmessage::AssureWritable(self->parent) == -1)
- return NULL;
- Message* message = self->message;
- Message* sub_message =
- message->GetReflection()->AddMessage(message,
- self->parent_field_descriptor);
- CMessage* cmsg = cmessage::NewEmptyMessage(self->child_message_class);
- if (cmsg == NULL)
- return NULL;
-
- cmsg->owner = self->owner;
- cmsg->message = sub_message;
- cmsg->parent = self->parent;
- if (cmessage::InitAttributes(cmsg, kwargs) < 0) {
- Py_DECREF(cmsg);
- return NULL;
- }
-
- PyObject* py_cmsg = reinterpret_cast<PyObject*>(cmsg);
- if (PyList_Append(self->child_messages, py_cmsg) < 0) {
- Py_DECREF(py_cmsg);
- return NULL;
- }
- return py_cmsg;
-}
-
-static PyObject* AddToReleased(RepeatedCompositeContainer* self,
- PyObject* args,
- PyObject* kwargs) {
- GOOGLE_CHECK_RELEASED(self);
-
- // Create a new Message detached from the rest.
- PyObject* py_cmsg = PyEval_CallObjectWithKeywords(
- self->child_message_class->AsPyObject(), NULL, kwargs);
- if (py_cmsg == NULL)
- return NULL;
-
- if (PyList_Append(self->child_messages, py_cmsg) < 0) {
- Py_DECREF(py_cmsg);
- return NULL;
- }
- return py_cmsg;
-}
-
-PyObject* Add(RepeatedCompositeContainer* self,
- PyObject* args,
- PyObject* kwargs) {
- if (self->message == NULL)
- return AddToReleased(self, args, kwargs);
- else
- return AddToAttached(self, args, kwargs);
-}
-
-// ---------------------------------------------------------------------
-// extend()
-
-PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value) {
- cmessage::AssureWritable(self->parent);
- if (UpdateChildMessages(self) < 0) {
- return NULL;
- }
- ScopedPyObjectPtr iter(PyObject_GetIter(value));
- if (iter == NULL) {
- PyErr_SetString(PyExc_TypeError, "Value must be iterable");
- return NULL;
- }
- ScopedPyObjectPtr next;
- while ((next.reset(PyIter_Next(iter.get()))) != NULL) {
- if (!PyObject_TypeCheck(next.get(), &CMessage_Type)) {
- PyErr_SetString(PyExc_TypeError, "Not a cmessage");
- return NULL;
- }
- ScopedPyObjectPtr new_message(Add(self, NULL, NULL));
- if (new_message == NULL) {
- return NULL;
- }
- CMessage* new_cmessage = reinterpret_cast<CMessage*>(new_message.get());
- if (ScopedPyObjectPtr(cmessage::MergeFrom(new_cmessage, next.get())) ==
- NULL) {
- return NULL;
- }
- }
- if (PyErr_Occurred()) {
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other) {
- if (UpdateChildMessages(self) < 0) {
- return NULL;
- }
- return Extend(self, other);
-}
-
-PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice) {
- if (UpdateChildMessages(self) < 0) {
- return NULL;
- }
- // Just forward the call to the subscript-handling function of the
- // list containing the child messages.
- return PyObject_GetItem(self->child_messages, slice);
-}
-
-int AssignSubscript(RepeatedCompositeContainer* self,
- PyObject* slice,
- PyObject* value) {
- if (UpdateChildMessages(self) < 0) {
- return -1;
- }
- if (value != NULL) {
- PyErr_SetString(PyExc_TypeError, "does not support assignment");
- return -1;
- }
-
- // Delete from the underlying Message, if any.
- if (self->parent != NULL) {
- if (cmessage::InternalDeleteRepeatedField(self->parent,
- self->parent_field_descriptor,
- slice,
- self->child_messages) < 0) {
- return -1;
- }
- } else {
- Py_ssize_t from;
- Py_ssize_t to;
- Py_ssize_t step;
- Py_ssize_t length = Length(self);
- Py_ssize_t slicelength;
- if (PySlice_Check(slice)) {
-#if PY_MAJOR_VERSION >= 3
- if (PySlice_GetIndicesEx(slice,
-#else
- if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
-#endif
- length, &from, &to, &step, &slicelength) == -1) {
- return -1;
- }
- return PySequence_DelSlice(self->child_messages, from, to);
- } else if (PyInt_Check(slice) || PyLong_Check(slice)) {
- from = to = PyLong_AsLong(slice);
- if (from < 0) {
- from = to = length + from;
- }
- return PySequence_DelItem(self->child_messages, from);
- }
- }
-
- return 0;
-}
-
-static PyObject* Remove(RepeatedCompositeContainer* self, PyObject* value) {
- if (UpdateChildMessages(self) < 0) {
- return NULL;
- }
- Py_ssize_t index = PySequence_Index(self->child_messages, value);
- if (index == -1) {
- return NULL;
- }
- ScopedPyObjectPtr py_index(PyLong_FromLong(index));
- if (AssignSubscript(self, py_index.get(), NULL) < 0) {
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-static PyObject* RichCompare(RepeatedCompositeContainer* self,
- PyObject* other,
- int opid) {
- if (UpdateChildMessages(self) < 0) {
- return NULL;
- }
- if (!PyObject_TypeCheck(other, &RepeatedCompositeContainer_Type)) {
- PyErr_SetString(PyExc_TypeError,
- "Can only compare repeated composite fields "
- "against other repeated composite fields.");
- return NULL;
- }
- if (opid == Py_EQ || opid == Py_NE) {
- // TODO(anuraag): Don't make new lists just for this...
- ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
- if (full_slice == NULL) {
- return NULL;
- }
- ScopedPyObjectPtr list(Subscript(self, full_slice.get()));
- if (list == NULL) {
- return NULL;
- }
- ScopedPyObjectPtr other_list(
- Subscript(reinterpret_cast<RepeatedCompositeContainer*>(other),
- full_slice.get()));
- if (other_list == NULL) {
- return NULL;
- }
- return PyObject_RichCompare(list.get(), other_list.get(), opid);
- } else {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-}
-
-// ---------------------------------------------------------------------
-// sort()
-
-static void ReorderAttached(RepeatedCompositeContainer* self) {
- Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
- const FieldDescriptor* descriptor = self->parent_field_descriptor;
- const Py_ssize_t length = Length(self);
-
- // Since Python protobuf objects are never arena-allocated, adding and
- // removing message pointers to the underlying array is just updating
- // pointers.
- for (Py_ssize_t i = 0; i < length; ++i)
- reflection->ReleaseLast(message, descriptor);
-
- for (Py_ssize_t i = 0; i < length; ++i) {
- CMessage* py_cmsg = reinterpret_cast<CMessage*>(
- PyList_GET_ITEM(self->child_messages, i));
- reflection->AddAllocatedMessage(message, descriptor, py_cmsg->message);
- }
-}
-
-// Returns 0 if successful; returns -1 and sets an exception if
-// unsuccessful.
-static int SortPythonMessages(RepeatedCompositeContainer* self,
- PyObject* args,
- PyObject* kwds) {
- ScopedPyObjectPtr m(PyObject_GetAttrString(self->child_messages, "sort"));
- if (m == NULL)
- return -1;
- if (PyObject_Call(m.get(), args, kwds) == NULL)
- return -1;
- if (self->message != NULL) {
- ReorderAttached(self);
- }
- return 0;
-}
-
-static PyObject* Sort(RepeatedCompositeContainer* self,
- PyObject* args,
- PyObject* kwds) {
- // Support the old sort_function argument for backwards
- // compatibility.
- if (kwds != NULL) {
- PyObject* sort_func = PyDict_GetItemString(kwds, "sort_function");
- if (sort_func != NULL) {
- // Must set before deleting as sort_func is a borrowed reference
- // and kwds might be the only thing keeping it alive.
- PyDict_SetItemString(kwds, "cmp", sort_func);
- PyDict_DelItemString(kwds, "sort_function");
- }
- }
-
- if (UpdateChildMessages(self) < 0) {
- return NULL;
- }
- if (SortPythonMessages(self, args, kwds) < 0) {
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-// ---------------------------------------------------------------------
-
-static PyObject* Item(RepeatedCompositeContainer* self, Py_ssize_t index) {
- if (UpdateChildMessages(self) < 0) {
- return NULL;
- }
- Py_ssize_t length = Length(self);
- if (index < 0) {
- index = length + index;
- }
- PyObject* item = PyList_GetItem(self->child_messages, index);
- if (item == NULL) {
- return NULL;
- }
- Py_INCREF(item);
- return item;
-}
-
-static PyObject* Pop(RepeatedCompositeContainer* self,
- PyObject* args) {
- Py_ssize_t index = -1;
- if (!PyArg_ParseTuple(args, "|n", &index)) {
- return NULL;
- }
- PyObject* item = Item(self, index);
- if (item == NULL) {
- PyErr_Format(PyExc_IndexError,
- "list index (%zd) out of range",
- index);
- return NULL;
- }
- ScopedPyObjectPtr py_index(PyLong_FromSsize_t(index));
- if (AssignSubscript(self, py_index.get(), NULL) < 0) {
- return NULL;
- }
- return item;
-}
-
-// Release field of parent message and transfer the ownership to target.
-void ReleaseLastTo(CMessage* parent,
- const FieldDescriptor* field,
- CMessage* target) {
- GOOGLE_CHECK_NOTNULL(parent);
- GOOGLE_CHECK_NOTNULL(field);
- GOOGLE_CHECK_NOTNULL(target);
-
- shared_ptr<Message> released_message(
- parent->message->GetReflection()->ReleaseLast(parent->message, field));
- // TODO(tibell): Deal with proto1.
-
- target->parent = NULL;
- target->parent_field_descriptor = NULL;
- target->message = released_message.get();
- target->read_only = false;
- cmessage::SetOwner(target, released_message);
-}
-
-// Called to release a container using
-// ClearField('container_field_name') on the parent.
-int Release(RepeatedCompositeContainer* self) {
- if (UpdateChildMessages(self) < 0) {
- PyErr_WriteUnraisable(PyBytes_FromString("Failed to update released "
- "messages"));
- return -1;
- }
-
- Message* message = self->message;
- const FieldDescriptor* field = self->parent_field_descriptor;
-
- // The reflection API only lets us release the last message in a
- // repeated field. Therefore we iterate through the children
- // starting with the last one.
- const Py_ssize_t size = PyList_GET_SIZE(self->child_messages);
- GOOGLE_DCHECK_EQ(size, message->GetReflection()->FieldSize(*message, field));
- for (Py_ssize_t i = size - 1; i >= 0; --i) {
- CMessage* child_cmessage = reinterpret_cast<CMessage*>(
- PyList_GET_ITEM(self->child_messages, i));
- ReleaseLastTo(self->parent, field, child_cmessage);
- }
-
- // Detach from containing message.
- self->parent = NULL;
- self->parent_field_descriptor = NULL;
- self->message = NULL;
- self->owner.reset();
-
- return 0;
-}
-
-int SetOwner(RepeatedCompositeContainer* self,
- const shared_ptr<Message>& new_owner) {
- GOOGLE_CHECK_ATTACHED(self);
-
- self->owner = new_owner;
- const Py_ssize_t n = PyList_GET_SIZE(self->child_messages);
- for (Py_ssize_t i = 0; i < n; ++i) {
- PyObject* msg = PyList_GET_ITEM(self->child_messages, i);
- if (cmessage::SetOwner(reinterpret_cast<CMessage*>(msg), new_owner) == -1) {
- return -1;
- }
- }
- return 0;
-}
-
-// The private constructor of RepeatedCompositeContainer objects.
-PyObject *NewContainer(
- CMessage* parent,
- const FieldDescriptor* parent_field_descriptor,
- CMessageClass* concrete_class) {
- if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) {
- return NULL;
- }
-
- RepeatedCompositeContainer* self =
- reinterpret_cast<RepeatedCompositeContainer*>(
- PyType_GenericAlloc(&RepeatedCompositeContainer_Type, 0));
- if (self == NULL) {
- return NULL;
- }
-
- self->message = parent->message;
- self->parent = parent;
- self->parent_field_descriptor = parent_field_descriptor;
- self->owner = parent->owner;
- Py_INCREF(concrete_class);
- self->child_message_class = concrete_class;
- self->child_messages = PyList_New(0);
-
- return reinterpret_cast<PyObject*>(self);
-}
-
-static void Dealloc(RepeatedCompositeContainer* self) {
- Py_CLEAR(self->child_messages);
- Py_CLEAR(self->child_message_class);
- // TODO(tibell): Do we need to call delete on these objects to make
- // sure their destructors are called?
- self->owner.reset();
-
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
-}
-
-static PySequenceMethods SqMethods = {
- (lenfunc)Length, /* sq_length */
- 0, /* sq_concat */
- 0, /* sq_repeat */
- (ssizeargfunc)Item /* sq_item */
-};
-
-static PyMappingMethods MpMethods = {
- (lenfunc)Length, /* mp_length */
- (binaryfunc)Subscript, /* mp_subscript */
- (objobjargproc)AssignSubscript,/* mp_ass_subscript */
-};
-
-static PyMethodDef Methods[] = {
- { "add", (PyCFunction) Add, METH_VARARGS | METH_KEYWORDS,
- "Adds an object to the repeated container." },
- { "extend", (PyCFunction) Extend, METH_O,
- "Adds objects to the repeated container." },
- { "pop", (PyCFunction)Pop, METH_VARARGS,
- "Removes an object from the repeated container and returns it." },
- { "remove", (PyCFunction) Remove, METH_O,
- "Removes an object from the repeated container." },
- { "sort", (PyCFunction) Sort, METH_VARARGS | METH_KEYWORDS,
- "Sorts the repeated container." },
- { "MergeFrom", (PyCFunction) MergeFrom, METH_O,
- "Adds objects to the repeated container." },
- { NULL, NULL }
-};
-
-} // namespace repeated_composite_container
-
-PyTypeObject RepeatedCompositeContainer_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".RepeatedCompositeContainer", // tp_name
- sizeof(RepeatedCompositeContainer), // tp_basicsize
- 0, // tp_itemsize
- (destructor)repeated_composite_container::Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- &repeated_composite_container::SqMethods, // tp_as_sequence
- &repeated_composite_container::MpMethods, // tp_as_mapping
- PyObject_HashNotImplemented, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A Repeated scalar container", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- (richcmpfunc)repeated_composite_container::RichCompare, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- repeated_composite_container::Methods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
-};
-
-} // namespace python
-} // namespace protobuf
-} // namespace google
diff --git a/python/google/protobuf/pyext/repeated_composite_container.h b/python/google/protobuf/pyext/repeated_composite_container.h
deleted file mode 100644
index a7b56b61..00000000
--- a/python/google/protobuf/pyext/repeated_composite_container.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: anuraag@google.com (Anuraag Agrawal)
-// Author: tibell@google.com (Johan Tibell)
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
-#define GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
-
-#include <Python.h>
-
-#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
-#include <string>
-#include <vector>
-
-namespace google {
-namespace protobuf {
-
-class FieldDescriptor;
-class Message;
-
-#ifdef _SHARED_PTR_H
-using std::shared_ptr;
-#else
-using internal::shared_ptr;
-#endif
-
-namespace python {
-
-struct CMessage;
-struct CMessageClass;
-
-// A RepeatedCompositeContainer can be in one of two states: attached
-// or released.
-//
-// When in the attached state all modifications to the container are
-// done both on the 'message' and on the 'child_messages'
-// list. In this state all Messages referred to by the children in
-// 'child_messages' are owner by the 'owner'.
-//
-// When in the released state 'message', 'owner', 'parent', and
-// 'parent_field_descriptor' are NULL.
-typedef struct RepeatedCompositeContainer {
- PyObject_HEAD;
-
- // This is the top-level C++ Message object that owns the whole
- // proto tree. Every Python RepeatedCompositeContainer holds a
- // reference to it in order to keep it alive as long as there's a
- // Python object that references any part of the tree.
- shared_ptr<Message> owner;
-
- // Weak reference to parent object. May be NULL. Used to make sure
- // the parent is writable before modifying the
- // RepeatedCompositeContainer.
- CMessage* parent;
-
- // A descriptor used to modify the underlying 'message'.
- // The pointer is owned by the global DescriptorPool.
- const FieldDescriptor* parent_field_descriptor;
-
- // Pointer to the C++ Message that contains this container. The
- // RepeatedCompositeContainer does not own this pointer.
- //
- // If NULL, this message has been released from its parent (by
- // calling Clear() or ClearField() on the parent.
- Message* message;
-
- // The type used to create new child messages.
- CMessageClass* child_message_class;
-
- // A list of child messages.
- PyObject* child_messages;
-} RepeatedCompositeContainer;
-
-extern PyTypeObject RepeatedCompositeContainer_Type;
-
-namespace repeated_composite_container {
-
-// Builds a RepeatedCompositeContainer object, from a parent message and a
-// field descriptor.
-PyObject *NewContainer(
- CMessage* parent,
- const FieldDescriptor* parent_field_descriptor,
- CMessageClass *child_message_class);
-
-// Appends a new CMessage to the container and returns it. The
-// CMessage is initialized using the content of kwargs.
-//
-// Returns a new reference if successful; returns NULL and sets an
-// exception if unsuccessful.
-PyObject* Add(RepeatedCompositeContainer* self,
- PyObject* args,
- PyObject* kwargs);
-
-// Appends all the CMessages in the input iterator to the container.
-//
-// Returns None if successful; returns NULL and sets an exception if
-// unsuccessful.
-PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value);
-
-// Appends a new message to the container for each message in the
-// input iterator, merging each data element in. Equivalent to extend.
-//
-// Returns None if successful; returns NULL and sets an exception if
-// unsuccessful.
-PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other);
-
-// Accesses messages in the container.
-//
-// Returns a new reference to the message for an integer parameter.
-// Returns a new reference to a list of messages for a slice.
-PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice);
-
-// Deletes items from the container (cannot be used for assignment).
-//
-// Returns 0 on success, -1 on failure.
-int AssignSubscript(RepeatedCompositeContainer* self,
- PyObject* slice,
- PyObject* value);
-
-// Releases the messages in the container to the given message.
-//
-// Returns 0 on success, -1 on failure.
-int ReleaseToMessage(RepeatedCompositeContainer* self, Message* new_message);
-
-// Releases the messages in the container to a new message.
-//
-// Returns 0 on success, -1 on failure.
-int Release(RepeatedCompositeContainer* self);
-
-// Returns 0 on success, -1 on failure.
-int SetOwner(RepeatedCompositeContainer* self,
- const shared_ptr<Message>& new_owner);
-
-// Removes the last element of the repeated message field 'field' on
-// the Message 'parent', and transfers the ownership of the released
-// Message to 'target'.
-//
-// Corresponds to reflection api method ReleaseMessage.
-void ReleaseLastTo(CMessage* parent,
- const FieldDescriptor* field,
- CMessage* target);
-
-} // namespace repeated_composite_container
-} // namespace python
-} // namespace protobuf
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc
deleted file mode 100644
index 95da85f8..00000000
--- a/python/google/protobuf/pyext/repeated_scalar_container.cc
+++ /dev/null
@@ -1,812 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: anuraag@google.com (Anuraag Agrawal)
-// Author: tibell@google.com (Johan Tibell)
-
-#include <google/protobuf/pyext/repeated_scalar_container.h>
-
-#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
-
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/dynamic_message.h>
-#include <google/protobuf/message.h>
-#include <google/protobuf/pyext/descriptor.h>
-#include <google/protobuf/pyext/descriptor_pool.h>
-#include <google/protobuf/pyext/message.h>
-#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
-
-#if PY_MAJOR_VERSION >= 3
- #define PyInt_FromLong PyLong_FromLong
- #if PY_VERSION_HEX < 0x03030000
- #error "Python 3.0 - 3.2 are not supported."
- #else
- #define PyString_AsString(ob) \
- (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AsString(ob))
- #endif
-#endif
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-namespace repeated_scalar_container {
-
-static int InternalAssignRepeatedField(
- RepeatedScalarContainer* self, PyObject* list) {
- self->message->GetReflection()->ClearField(self->message,
- self->parent_field_descriptor);
- for (Py_ssize_t i = 0; i < PyList_GET_SIZE(list); ++i) {
- PyObject* value = PyList_GET_ITEM(list, i);
- if (ScopedPyObjectPtr(Append(self, value)) == NULL) {
- return -1;
- }
- }
- return 0;
-}
-
-static Py_ssize_t Len(RepeatedScalarContainer* self) {
- Message* message = self->message;
- return message->GetReflection()->FieldSize(*message,
- self->parent_field_descriptor);
-}
-
-static int AssignItem(RepeatedScalarContainer* self,
- Py_ssize_t index,
- PyObject* arg) {
- cmessage::AssureWritable(self->parent);
- Message* message = self->message;
- const FieldDescriptor* field_descriptor = self->parent_field_descriptor;
-
- const Reflection* reflection = message->GetReflection();
- int field_size = reflection->FieldSize(*message, field_descriptor);
- if (index < 0) {
- index = field_size + index;
- }
- if (index < 0 || index >= field_size) {
- PyErr_Format(PyExc_IndexError,
- "list assignment index (%d) out of range",
- static_cast<int>(index));
- return -1;
- }
-
- if (arg == NULL) {
- ScopedPyObjectPtr py_index(PyLong_FromLong(index));
- return cmessage::InternalDeleteRepeatedField(self->parent, field_descriptor,
- py_index.get(), NULL);
- }
-
- if (PySequence_Check(arg) && !(PyBytes_Check(arg) || PyUnicode_Check(arg))) {
- PyErr_SetString(PyExc_TypeError, "Value must be scalar");
- return -1;
- }
-
- switch (field_descriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32: {
- GOOGLE_CHECK_GET_INT32(arg, value, -1);
- reflection->SetRepeatedInt32(message, field_descriptor, index, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_INT64: {
- GOOGLE_CHECK_GET_INT64(arg, value, -1);
- reflection->SetRepeatedInt64(message, field_descriptor, index, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT32: {
- GOOGLE_CHECK_GET_UINT32(arg, value, -1);
- reflection->SetRepeatedUInt32(message, field_descriptor, index, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT64: {
- GOOGLE_CHECK_GET_UINT64(arg, value, -1);
- reflection->SetRepeatedUInt64(message, field_descriptor, index, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_FLOAT: {
- GOOGLE_CHECK_GET_FLOAT(arg, value, -1);
- reflection->SetRepeatedFloat(message, field_descriptor, index, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_DOUBLE: {
- GOOGLE_CHECK_GET_DOUBLE(arg, value, -1);
- reflection->SetRepeatedDouble(message, field_descriptor, index, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_BOOL: {
- GOOGLE_CHECK_GET_BOOL(arg, value, -1);
- reflection->SetRepeatedBool(message, field_descriptor, index, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- if (!CheckAndSetString(
- arg, message, field_descriptor, reflection, false, index)) {
- return -1;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_ENUM: {
- GOOGLE_CHECK_GET_INT32(arg, value, -1);
- if (reflection->SupportsUnknownEnumValues()) {
- reflection->SetRepeatedEnumValue(message, field_descriptor, index,
- value);
- } else {
- const EnumDescriptor* enum_descriptor = field_descriptor->enum_type();
- const EnumValueDescriptor* enum_value =
- enum_descriptor->FindValueByNumber(value);
- if (enum_value != NULL) {
- reflection->SetRepeatedEnum(message, field_descriptor, index,
- enum_value);
- } else {
- ScopedPyObjectPtr s(PyObject_Str(arg));
- if (s != NULL) {
- PyErr_Format(PyExc_ValueError, "Unknown enum value: %s",
- PyString_AsString(s.get()));
- }
- return -1;
- }
- }
- break;
- }
- default:
- PyErr_Format(
- PyExc_SystemError, "Adding value to a field of unknown type %d",
- field_descriptor->cpp_type());
- return -1;
- }
- return 0;
-}
-
-static PyObject* Item(RepeatedScalarContainer* self, Py_ssize_t index) {
- Message* message = self->message;
- const FieldDescriptor* field_descriptor = self->parent_field_descriptor;
- const Reflection* reflection = message->GetReflection();
-
- int field_size = reflection->FieldSize(*message, field_descriptor);
- if (index < 0) {
- index = field_size + index;
- }
- if (index < 0 || index >= field_size) {
- PyErr_Format(PyExc_IndexError,
- "list index (%zd) out of range",
- index);
- return NULL;
- }
-
- PyObject* result = NULL;
- switch (field_descriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32: {
- int32 value = reflection->GetRepeatedInt32(
- *message, field_descriptor, index);
- result = PyInt_FromLong(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_INT64: {
- int64 value = reflection->GetRepeatedInt64(
- *message, field_descriptor, index);
- result = PyLong_FromLongLong(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT32: {
- uint32 value = reflection->GetRepeatedUInt32(
- *message, field_descriptor, index);
- result = PyLong_FromLongLong(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT64: {
- uint64 value = reflection->GetRepeatedUInt64(
- *message, field_descriptor, index);
- result = PyLong_FromUnsignedLongLong(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_FLOAT: {
- float value = reflection->GetRepeatedFloat(
- *message, field_descriptor, index);
- result = PyFloat_FromDouble(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_DOUBLE: {
- double value = reflection->GetRepeatedDouble(
- *message, field_descriptor, index);
- result = PyFloat_FromDouble(value);
- break;
- }
- case FieldDescriptor::CPPTYPE_BOOL: {
- bool value = reflection->GetRepeatedBool(
- *message, field_descriptor, index);
- result = PyBool_FromLong(value ? 1 : 0);
- break;
- }
- case FieldDescriptor::CPPTYPE_ENUM: {
- const EnumValueDescriptor* enum_value =
- message->GetReflection()->GetRepeatedEnum(
- *message, field_descriptor, index);
- result = PyInt_FromLong(enum_value->number());
- break;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- string value = reflection->GetRepeatedString(
- *message, field_descriptor, index);
- result = ToStringObject(field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_MESSAGE: {
- PyObject* py_cmsg = PyObject_CallObject(reinterpret_cast<PyObject*>(
- &CMessage_Type), NULL);
- if (py_cmsg == NULL) {
- return NULL;
- }
- CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
- const Message& msg = reflection->GetRepeatedMessage(
- *message, field_descriptor, index);
- cmsg->owner = self->owner;
- cmsg->parent = self->parent;
- cmsg->message = const_cast<Message*>(&msg);
- cmsg->read_only = false;
- result = reinterpret_cast<PyObject*>(py_cmsg);
- break;
- }
- default:
- PyErr_Format(
- PyExc_SystemError,
- "Getting value from a repeated field of unknown type %d",
- field_descriptor->cpp_type());
- }
-
- return result;
-}
-
-static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) {
- Py_ssize_t from;
- Py_ssize_t to;
- Py_ssize_t step;
- Py_ssize_t length;
- Py_ssize_t slicelength;
- bool return_list = false;
-#if PY_MAJOR_VERSION < 3
- if (PyInt_Check(slice)) {
- from = to = PyInt_AsLong(slice);
- } else // NOLINT
-#endif
- if (PyLong_Check(slice)) {
- from = to = PyLong_AsLong(slice);
- } else if (PySlice_Check(slice)) {
- length = Len(self);
-#if PY_MAJOR_VERSION >= 3
- if (PySlice_GetIndicesEx(slice,
-#else
- if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
-#endif
- length, &from, &to, &step, &slicelength) == -1) {
- return NULL;
- }
- return_list = true;
- } else {
- PyErr_SetString(PyExc_TypeError, "list indices must be integers");
- return NULL;
- }
-
- if (!return_list) {
- return Item(self, from);
- }
-
- PyObject* list = PyList_New(0);
- if (list == NULL) {
- return NULL;
- }
- if (from <= to) {
- if (step < 0) {
- return list;
- }
- for (Py_ssize_t index = from; index < to; index += step) {
- if (index < 0 || index >= length) {
- break;
- }
- ScopedPyObjectPtr s(Item(self, index));
- PyList_Append(list, s.get());
- }
- } else {
- if (step > 0) {
- return list;
- }
- for (Py_ssize_t index = from; index > to; index += step) {
- if (index < 0 || index >= length) {
- break;
- }
- ScopedPyObjectPtr s(Item(self, index));
- PyList_Append(list, s.get());
- }
- }
- return list;
-}
-
-PyObject* Append(RepeatedScalarContainer* self, PyObject* item) {
- cmessage::AssureWritable(self->parent);
- Message* message = self->message;
- const FieldDescriptor* field_descriptor = self->parent_field_descriptor;
-
- const Reflection* reflection = message->GetReflection();
- switch (field_descriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32: {
- GOOGLE_CHECK_GET_INT32(item, value, NULL);
- reflection->AddInt32(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_INT64: {
- GOOGLE_CHECK_GET_INT64(item, value, NULL);
- reflection->AddInt64(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT32: {
- GOOGLE_CHECK_GET_UINT32(item, value, NULL);
- reflection->AddUInt32(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT64: {
- GOOGLE_CHECK_GET_UINT64(item, value, NULL);
- reflection->AddUInt64(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_FLOAT: {
- GOOGLE_CHECK_GET_FLOAT(item, value, NULL);
- reflection->AddFloat(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_DOUBLE: {
- GOOGLE_CHECK_GET_DOUBLE(item, value, NULL);
- reflection->AddDouble(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_BOOL: {
- GOOGLE_CHECK_GET_BOOL(item, value, NULL);
- reflection->AddBool(message, field_descriptor, value);
- break;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- if (!CheckAndSetString(
- item, message, field_descriptor, reflection, true, -1)) {
- return NULL;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_ENUM: {
- GOOGLE_CHECK_GET_INT32(item, value, NULL);
- if (reflection->SupportsUnknownEnumValues()) {
- reflection->AddEnumValue(message, field_descriptor, value);
- } else {
- const EnumDescriptor* enum_descriptor = field_descriptor->enum_type();
- const EnumValueDescriptor* enum_value =
- enum_descriptor->FindValueByNumber(value);
- if (enum_value != NULL) {
- reflection->AddEnum(message, field_descriptor, enum_value);
- } else {
- ScopedPyObjectPtr s(PyObject_Str(item));
- if (s != NULL) {
- PyErr_Format(PyExc_ValueError, "Unknown enum value: %s",
- PyString_AsString(s.get()));
- }
- return NULL;
- }
- }
- break;
- }
- default:
- PyErr_Format(
- PyExc_SystemError, "Adding value to a field of unknown type %d",
- field_descriptor->cpp_type());
- return NULL;
- }
-
- Py_RETURN_NONE;
-}
-
-static int AssSubscript(RepeatedScalarContainer* self,
- PyObject* slice,
- PyObject* value) {
- Py_ssize_t from;
- Py_ssize_t to;
- Py_ssize_t step;
- Py_ssize_t length;
- Py_ssize_t slicelength;
- bool create_list = false;
-
- cmessage::AssureWritable(self->parent);
- Message* message = self->message;
- const FieldDescriptor* field_descriptor =
- self->parent_field_descriptor;
-
-#if PY_MAJOR_VERSION < 3
- if (PyInt_Check(slice)) {
- from = to = PyInt_AsLong(slice);
- } else
-#endif
- if (PyLong_Check(slice)) {
- from = to = PyLong_AsLong(slice);
- } else if (PySlice_Check(slice)) {
- const Reflection* reflection = message->GetReflection();
- length = reflection->FieldSize(*message, field_descriptor);
-#if PY_MAJOR_VERSION >= 3
- if (PySlice_GetIndicesEx(slice,
-#else
- if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
-#endif
- length, &from, &to, &step, &slicelength) == -1) {
- return -1;
- }
- create_list = true;
- } else {
- PyErr_SetString(PyExc_TypeError, "list indices must be integers");
- return -1;
- }
-
- if (value == NULL) {
- return cmessage::InternalDeleteRepeatedField(
- self->parent, field_descriptor, slice, NULL);
- }
-
- if (!create_list) {
- return AssignItem(self, from, value);
- }
-
- ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
- if (full_slice == NULL) {
- return -1;
- }
- ScopedPyObjectPtr new_list(Subscript(self, full_slice.get()));
- if (new_list == NULL) {
- return -1;
- }
- if (PySequence_SetSlice(new_list.get(), from, to, value) < 0) {
- return -1;
- }
-
- return InternalAssignRepeatedField(self, new_list.get());
-}
-
-PyObject* Extend(RepeatedScalarContainer* self, PyObject* value) {
- cmessage::AssureWritable(self->parent);
-
- // TODO(ptucker): Deprecate this behavior. b/18413862
- if (value == Py_None) {
- Py_RETURN_NONE;
- }
- if ((Py_TYPE(value)->tp_as_sequence == NULL) && PyObject_Not(value)) {
- Py_RETURN_NONE;
- }
-
- ScopedPyObjectPtr iter(PyObject_GetIter(value));
- if (iter == NULL) {
- PyErr_SetString(PyExc_TypeError, "Value must be iterable");
- return NULL;
- }
- ScopedPyObjectPtr next;
- while ((next.reset(PyIter_Next(iter.get()))) != NULL) {
- if (ScopedPyObjectPtr(Append(self, next.get())) == NULL) {
- return NULL;
- }
- }
- if (PyErr_Occurred()) {
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-static PyObject* Insert(RepeatedScalarContainer* self, PyObject* args) {
- Py_ssize_t index;
- PyObject* value;
- if (!PyArg_ParseTuple(args, "lO", &index, &value)) {
- return NULL;
- }
- ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
- ScopedPyObjectPtr new_list(Subscript(self, full_slice.get()));
- if (PyList_Insert(new_list.get(), index, value) < 0) {
- return NULL;
- }
- int ret = InternalAssignRepeatedField(self, new_list.get());
- if (ret < 0) {
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-static PyObject* Remove(RepeatedScalarContainer* self, PyObject* value) {
- Py_ssize_t match_index = -1;
- for (Py_ssize_t i = 0; i < Len(self); ++i) {
- ScopedPyObjectPtr elem(Item(self, i));
- if (PyObject_RichCompareBool(elem.get(), value, Py_EQ)) {
- match_index = i;
- break;
- }
- }
- if (match_index == -1) {
- PyErr_SetString(PyExc_ValueError, "remove(x): x not in container");
- return NULL;
- }
- if (AssignItem(self, match_index, NULL) < 0) {
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-static PyObject* RichCompare(RepeatedScalarContainer* self,
- PyObject* other,
- int opid) {
- if (opid != Py_EQ && opid != Py_NE) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- // Copy the contents of this repeated scalar container, and other if it is
- // also a repeated scalar container, into Python lists so we can delegate
- // to the list's compare method.
-
- ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
- if (full_slice == NULL) {
- return NULL;
- }
-
- ScopedPyObjectPtr other_list_deleter;
- if (PyObject_TypeCheck(other, &RepeatedScalarContainer_Type)) {
- other_list_deleter.reset(Subscript(
- reinterpret_cast<RepeatedScalarContainer*>(other), full_slice.get()));
- other = other_list_deleter.get();
- }
-
- ScopedPyObjectPtr list(Subscript(self, full_slice.get()));
- if (list == NULL) {
- return NULL;
- }
- return PyObject_RichCompare(list.get(), other, opid);
-}
-
-PyObject* Reduce(RepeatedScalarContainer* unused_self) {
- PyErr_Format(
- PickleError_class,
- "can't pickle repeated message fields, convert to list first");
- return NULL;
-}
-
-static PyObject* Sort(RepeatedScalarContainer* self,
- PyObject* args,
- PyObject* kwds) {
- // Support the old sort_function argument for backwards
- // compatibility.
- if (kwds != NULL) {
- PyObject* sort_func = PyDict_GetItemString(kwds, "sort_function");
- if (sort_func != NULL) {
- // Must set before deleting as sort_func is a borrowed reference
- // and kwds might be the only thing keeping it alive.
- if (PyDict_SetItemString(kwds, "cmp", sort_func) == -1)
- return NULL;
- if (PyDict_DelItemString(kwds, "sort_function") == -1)
- return NULL;
- }
- }
-
- ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
- if (full_slice == NULL) {
- return NULL;
- }
- ScopedPyObjectPtr list(Subscript(self, full_slice.get()));
- if (list == NULL) {
- return NULL;
- }
- ScopedPyObjectPtr m(PyObject_GetAttrString(list.get(), "sort"));
- if (m == NULL) {
- return NULL;
- }
- ScopedPyObjectPtr res(PyObject_Call(m.get(), args, kwds));
- if (res == NULL) {
- return NULL;
- }
- int ret = InternalAssignRepeatedField(self, list.get());
- if (ret < 0) {
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-static PyObject* Pop(RepeatedScalarContainer* self,
- PyObject* args) {
- Py_ssize_t index = -1;
- if (!PyArg_ParseTuple(args, "|n", &index)) {
- return NULL;
- }
- PyObject* item = Item(self, index);
- if (item == NULL) {
- PyErr_Format(PyExc_IndexError,
- "list index (%zd) out of range",
- index);
- return NULL;
- }
- if (AssignItem(self, index, NULL) < 0) {
- return NULL;
- }
- return item;
-}
-
-// The private constructor of RepeatedScalarContainer objects.
-PyObject *NewContainer(
- CMessage* parent, const FieldDescriptor* parent_field_descriptor) {
- if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) {
- return NULL;
- }
-
- RepeatedScalarContainer* self = reinterpret_cast<RepeatedScalarContainer*>(
- PyType_GenericAlloc(&RepeatedScalarContainer_Type, 0));
- if (self == NULL) {
- return NULL;
- }
-
- self->message = parent->message;
- self->parent = parent;
- self->parent_field_descriptor = parent_field_descriptor;
- self->owner = parent->owner;
-
- return reinterpret_cast<PyObject*>(self);
-}
-
-// Initializes the underlying Message object of "to" so it becomes a new parent
-// repeated scalar, and copies all the values from "from" to it. A child scalar
-// container can be released by passing it as both from and to (e.g. making it
-// the recipient of the new parent message and copying the values from itself).
-static int InitializeAndCopyToParentContainer(
- RepeatedScalarContainer* from,
- RepeatedScalarContainer* to) {
- ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
- if (full_slice == NULL) {
- return -1;
- }
- ScopedPyObjectPtr values(Subscript(from, full_slice.get()));
- if (values == NULL) {
- return -1;
- }
- Message* new_message = from->message->New();
- to->parent = NULL;
- to->parent_field_descriptor = from->parent_field_descriptor;
- to->message = new_message;
- to->owner.reset(new_message);
- if (InternalAssignRepeatedField(to, values.get()) < 0) {
- return -1;
- }
- return 0;
-}
-
-int Release(RepeatedScalarContainer* self) {
- return InitializeAndCopyToParentContainer(self, self);
-}
-
-PyObject* DeepCopy(RepeatedScalarContainer* self, PyObject* arg) {
- RepeatedScalarContainer* clone = reinterpret_cast<RepeatedScalarContainer*>(
- PyType_GenericAlloc(&RepeatedScalarContainer_Type, 0));
- if (clone == NULL) {
- return NULL;
- }
-
- if (InitializeAndCopyToParentContainer(self, clone) < 0) {
- Py_DECREF(clone);
- return NULL;
- }
- return reinterpret_cast<PyObject*>(clone);
-}
-
-static void Dealloc(RepeatedScalarContainer* self) {
- self->owner.reset();
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
-}
-
-void SetOwner(RepeatedScalarContainer* self,
- const shared_ptr<Message>& new_owner) {
- self->owner = new_owner;
-}
-
-static PySequenceMethods SqMethods = {
- (lenfunc)Len, /* sq_length */
- 0, /* sq_concat */
- 0, /* sq_repeat */
- (ssizeargfunc)Item, /* sq_item */
- 0, /* sq_slice */
- (ssizeobjargproc)AssignItem /* sq_ass_item */
-};
-
-static PyMappingMethods MpMethods = {
- (lenfunc)Len, /* mp_length */
- (binaryfunc)Subscript, /* mp_subscript */
- (objobjargproc)AssSubscript, /* mp_ass_subscript */
-};
-
-static PyMethodDef Methods[] = {
- { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
- "Makes a deep copy of the class." },
- { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
- "Outputs picklable representation of the repeated field." },
- { "append", (PyCFunction)Append, METH_O,
- "Appends an object to the repeated container." },
- { "extend", (PyCFunction)Extend, METH_O,
- "Appends objects to the repeated container." },
- { "insert", (PyCFunction)Insert, METH_VARARGS,
- "Appends objects to the repeated container." },
- { "pop", (PyCFunction)Pop, METH_VARARGS,
- "Removes an object from the repeated container and returns it." },
- { "remove", (PyCFunction)Remove, METH_O,
- "Removes an object from the repeated container." },
- { "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS,
- "Sorts the repeated container."},
- { NULL, NULL }
-};
-
-} // namespace repeated_scalar_container
-
-PyTypeObject RepeatedScalarContainer_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".RepeatedScalarContainer", // tp_name
- sizeof(RepeatedScalarContainer), // tp_basicsize
- 0, // tp_itemsize
- (destructor)repeated_scalar_container::Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- &repeated_scalar_container::SqMethods, // tp_as_sequence
- &repeated_scalar_container::MpMethods, // tp_as_mapping
- PyObject_HashNotImplemented, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A Repeated scalar container", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- (richcmpfunc)repeated_scalar_container::RichCompare, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- repeated_scalar_container::Methods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
-};
-
-} // namespace python
-} // namespace protobuf
-} // namespace google
diff --git a/python/google/protobuf/pyext/repeated_scalar_container.h b/python/google/protobuf/pyext/repeated_scalar_container.h
deleted file mode 100644
index 555e621c..00000000
--- a/python/google/protobuf/pyext/repeated_scalar_container.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: anuraag@google.com (Anuraag Agrawal)
-// Author: tibell@google.com (Johan Tibell)
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_SCALAR_CONTAINER_H__
-#define GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_SCALAR_CONTAINER_H__
-
-#include <Python.h>
-
-#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
-
-#include <google/protobuf/descriptor.h>
-
-namespace google {
-namespace protobuf {
-
-class Message;
-
-#ifdef _SHARED_PTR_H
-using std::shared_ptr;
-#else
-using internal::shared_ptr;
-#endif
-
-namespace python {
-
-struct CMessage;
-
-typedef struct RepeatedScalarContainer {
- PyObject_HEAD;
-
- // This is the top-level C++ Message object that owns the whole
- // proto tree. Every Python RepeatedScalarContainer holds a
- // reference to it in order to keep it alive as long as there's a
- // Python object that references any part of the tree.
- shared_ptr<Message> owner;
-
- // Pointer to the C++ Message that contains this container. The
- // RepeatedScalarContainer does not own this pointer.
- Message* message;
-
- // Weak reference to a parent CMessage object (i.e. may be NULL.)
- //
- // Used to make sure all ancestors are also mutable when first
- // modifying the container.
- CMessage* parent;
-
- // Pointer to the parent's descriptor that describes this
- // field. Used together with the parent's message when making a
- // default message instance mutable.
- // The pointer is owned by the global DescriptorPool.
- const FieldDescriptor* parent_field_descriptor;
-} RepeatedScalarContainer;
-
-extern PyTypeObject RepeatedScalarContainer_Type;
-
-namespace repeated_scalar_container {
-
-// Builds a RepeatedScalarContainer object, from a parent message and a
-// field descriptor.
-extern PyObject *NewContainer(
- CMessage* parent, const FieldDescriptor* parent_field_descriptor);
-
-// Appends the scalar 'item' to the end of the container 'self'.
-//
-// Returns None if successful; returns NULL and sets an exception if
-// unsuccessful.
-PyObject* Append(RepeatedScalarContainer* self, PyObject* item);
-
-// Releases the messages in the container to a new message.
-//
-// Returns 0 on success, -1 on failure.
-int Release(RepeatedScalarContainer* self);
-
-// Appends all the elements in the input iterator to the container.
-//
-// Returns None if successful; returns NULL and sets an exception if
-// unsuccessful.
-PyObject* Extend(RepeatedScalarContainer* self, PyObject* value);
-
-// Set the owner field of self and any children of self.
-void SetOwner(RepeatedScalarContainer* self,
- const shared_ptr<Message>& new_owner);
-
-} // namespace repeated_scalar_container
-} // namespace python
-} // namespace protobuf
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_SCALAR_CONTAINER_H__
diff --git a/python/google/protobuf/pyext/scoped_pyobject_ptr.h b/python/google/protobuf/pyext/scoped_pyobject_ptr.h
deleted file mode 100644
index a128cd4c..00000000
--- a/python/google/protobuf/pyext/scoped_pyobject_ptr.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: tibell@google.com (Johan Tibell)
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__
-#define GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__
-
-#include <google/protobuf/stubs/common.h>
-
-#include <Python.h>
-
-namespace google {
-class ScopedPyObjectPtr {
- public:
- // Constructor. Defaults to initializing with NULL.
- // There is no way to create an uninitialized ScopedPyObjectPtr.
- explicit ScopedPyObjectPtr(PyObject* p = NULL) : ptr_(p) { }
-
- // Destructor. If there is a PyObject object, delete it.
- ~ScopedPyObjectPtr() {
- Py_XDECREF(ptr_);
- }
-
- // Reset. Deletes the current owned object, if any.
- // Then takes ownership of a new object, if given.
- // This function must be called with a reference that you own.
- // this->reset(this->get()) is wrong!
- // this->reset(this->release()) is OK.
- PyObject* reset(PyObject* p = NULL) {
- Py_XDECREF(ptr_);
- ptr_ = p;
- return ptr_;
- }
-
- // Releases ownership of the object.
- // The caller now owns the returned reference.
- PyObject* release() {
- PyObject* p = ptr_;
- ptr_ = NULL;
- return p;
- }
-
- PyObject* operator->() const {
- assert(ptr_ != NULL);
- return ptr_;
- }
-
- PyObject* get() const { return ptr_; }
-
- Py_ssize_t refcnt() const { return Py_REFCNT(ptr_); }
-
- void inc() const { Py_INCREF(ptr_); }
-
- // Comparison operators.
- // These return whether a ScopedPyObjectPtr and a raw pointer
- // refer to the same object, not just to two different but equal
- // objects.
- bool operator==(const PyObject* p) const { return ptr_ == p; }
- bool operator!=(const PyObject* p) const { return ptr_ != p; }
-
- private:
- PyObject* ptr_;
-
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedPyObjectPtr);
-};
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__