34 #include <google/protobuf/pyext/extension_dict.h>
39 #include <google/protobuf/stubs/logging.h>
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/descriptor.pb.h>
42 #include <google/protobuf/descriptor.h>
43 #include <google/protobuf/dynamic_message.h>
44 #include <google/protobuf/message.h>
45 #include <google/protobuf/pyext/descriptor.h>
46 #include <google/protobuf/pyext/message.h>
47 #include <google/protobuf/pyext/message_factory.h>
48 #include <google/protobuf/pyext/repeated_composite_container.h>
49 #include <google/protobuf/pyext/repeated_scalar_container.h>
50 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
52 #define PyString_AsStringAndSize(ob, charpp, sizep) \
53 (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>( \
54 PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
57 : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
63 namespace extension_dict {
67 std::vector<const FieldDescriptor*>
fields;
68 self->parent->message->GetReflection()->ListFields(*
self->parent->message,
71 for (
size_t i = 0;
i <
fields.size(); ++
i) {
72 if (
fields[
i]->is_extension()) {
80 fields[
i]->message_type()) ==
nullptr) {
90 struct ExtensionIterator {
93 std::vector<const FieldDescriptor*>
fields;
99 PyObject*
GetIter(PyObject* _self) {
103 if (
obj ==
nullptr) {
104 return PyErr_Format(PyExc_MemoryError,
105 "Could not allocate extension iterator");
108 ExtensionIterator*
iter =
reinterpret_cast<ExtensionIterator*
>(
obj.get());
112 new (
iter) ExtensionIterator;
114 self->parent->message->GetReflection()->ListFields(*
self->parent->message,
118 iter->extension_dict =
self;
120 return obj.release();
126 Py_XDECREF(
self->extension_dict);
127 self->~ExtensionIterator();
128 Py_TYPE(_self)->tp_free(_self);
146 self->parent->composite_fields->find(
descriptor);
147 if (
iterator !=
self->parent->composite_fields->end()) {
149 return iterator->second->AsPyObject();
157 if (sub_message == NULL) {
160 (*
self->parent->composite_fields)[
descriptor] = sub_message;
161 return sub_message->AsPyObject();
180 reinterpret_cast<PyObject*
>(message_class));
181 if (message_class == NULL) {
186 if (py_container == NULL) {
189 (*
self->parent->composite_fields)[
descriptor] = py_container;
190 return py_container->AsPyObject();
194 if (py_container == NULL) {
197 (*
self->parent->composite_fields)[
descriptor] = py_container;
198 return py_container->AsPyObject();
201 PyErr_SetString(PyExc_ValueError,
"control reached unexpected line");
214 if (
value ==
nullptr) {
220 PyErr_SetString(PyExc_TypeError,
"Extension is repeated and/or composite "
233 Py_ssize_t name_size;
241 if (message_extension == NULL) {
245 if (message_descriptor && message_descriptor->extension_count() > 0) {
255 if (message_extension == NULL) {
264 if (
number == -1 && PyErr_Occurred()) {
270 self->parent->message->GetDescriptor(),
number);
271 if (message_extension == NULL) {
282 if (field_descriptor ==
nullptr) {
287 PyErr_Format(PyExc_KeyError,
"%s is not an extension",
315 self->parent = parent;
319 void dealloc(PyObject* pself) {
321 Py_CLEAR(
self->parent);
322 Py_TYPE(
self)->tp_free(
reinterpret_cast<PyObject*
>(
self));
327 if (opid != Py_EQ && opid != Py_NE) {
328 Py_INCREF(Py_NotImplemented);
329 return Py_NotImplemented;
333 equals =
self->parent ==
reinterpret_cast<ExtensionDict*
>(other)->parent;;
335 if (equals ^ (opid == Py_EQ)) {
358 #define EDMETHOD(name, args, doc) { #name, (PyCFunction)name, args, doc }
362 "Finds an extension by field number."),
373 (destructor)extension_dict::
dealloc,
382 PyObject_HashNotImplemented,
407 PyObject*
IterNext(PyObject* _self) {
408 extension_dict::ExtensionIterator*
self =
409 reinterpret_cast<extension_dict::ExtensionIterator*
>(_self);
410 Py_ssize_t total_size =
self->fields.size();
411 Py_ssize_t
index =
self->index;
412 while (
self->index < total_size) {
415 if (
self->fields[
index]->is_extension()) {
420 if (
self->fields[
index]->message_type() !=
nullptr &&
423 self->fields[
index]->message_type()) ==
nullptr) {
438 sizeof(extension_dict::ExtensionIterator),