31 #include <unordered_map>
33 #define PY_SSIZE_T_CLEAN
36 #include <google/protobuf/dynamic_message.h>
37 #include <google/protobuf/pyext/descriptor.h>
38 #include <google/protobuf/pyext/message.h>
39 #include <google/protobuf/pyext/message_factory.h>
40 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
42 #define PyString_AsStringAndSize(ob, charpp, sizep) \
43 (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>( \
44 PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
47 : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
53 namespace message_factory {
56 PyMessageFactory* factory =
reinterpret_cast<PyMessageFactory*
>(
57 PyType_GenericAlloc(
type, 0));
58 if (factory == NULL) {
64 message_factory->SetDelegateToGeneratedFactory(
true);
65 factory->message_factory = message_factory;
75 PyObject*
New(PyTypeObject*
type, PyObject*
args, PyObject* kwargs) {
76 static const char* kwlist[] = {
"pool", 0};
77 PyObject*
pool = NULL;
78 if (!PyArg_ParseTupleAndKeywords(
args, kwargs,
"|O",
79 const_cast<char**
>(kwlist), &
pool)) {
83 if (
pool == NULL ||
pool == Py_None) {
84 owned_pool.reset(PyObject_CallFunction(
86 if (owned_pool == NULL) {
89 pool = owned_pool.get();
92 PyErr_Format(PyExc_TypeError,
"Expected a DescriptorPool, got %s",
93 pool->ob_type->tp_name);
98 return reinterpret_cast<PyObject*
>(
107 it !=
self->classes_by_descriptor->end(); ++
it) {
108 Py_CLEAR(
it->second);
110 delete self->classes_by_descriptor;
111 delete self->message_factory;
112 Py_CLEAR(
self->pool);
118 Py_VISIT(
self->pool);
119 for (
const auto& desc_and_class : *
self->classes_by_descriptor) {
120 Py_VISIT(desc_and_class.second);
129 for (
auto& desc_and_class : *
self->classes_by_descriptor) {
130 Py_CLEAR(desc_and_class.second);
140 Py_INCREF(message_class);
142 std::pair<iterator, bool>
ret =
self->classes_by_descriptor->insert(
143 std::make_pair(message_descriptor, message_class));
146 Py_DECREF(
ret.first->second);
147 ret.first->second = message_class;
158 self->classes_by_descriptor->find(
descriptor);
159 if (
it !=
self->classes_by_descriptor->end()) {
160 Py_INCREF(
it->second);
165 if (py_descriptor == NULL) {
171 "DESCRIPTOR", py_descriptor.get(),
172 "__module__", Py_None,
173 "message_factory",
self));
179 if (message_class == NULL) {
184 for (
int field_idx = 0; field_idx <
descriptor->field_count(); field_idx++) {
188 if (sub_descriptor != NULL) {
198 for (
int ext_idx = 0 ; ext_idx <
descriptor->extension_count() ; ext_idx++) {
203 if (py_extended_class == NULL) {
207 if (py_extension == NULL) {
211 py_extended_class.get(), py_extension.get()));
216 return reinterpret_cast<CMessageClass*
>(message_class.release());
223 iterator ret =
self->classes_by_descriptor->find(message_descriptor);
224 if (
ret ==
self->classes_by_descriptor->end()) {
225 PyErr_Format(PyExc_TypeError,
"No message class registered for '%s'",
226 message_descriptor->full_name().c_str());
237 Py_INCREF(
self->pool);
238 return reinterpret_cast<PyObject*
>(
self->pool);
242 {
"pool", (getter)
GetPool, NULL,
"DescriptorPool"},
251 sizeof(PyMessageFactory),
268 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
286 message_factory::
New,