upb/python/message.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009-2021, Google LLC
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of Google LLC nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "python/message.h"
29 
30 #include "python/convert.h"
31 #include "python/descriptor.h"
32 #include "python/extension_dict.h"
33 #include "python/map.h"
34 #include "python/repeated.h"
35 #include "upb/def.h"
36 #include "upb/reflection.h"
37 #include "upb/text_encode.h"
39 
40 static const upb_MessageDef* PyUpb_MessageMeta_GetMsgdef(PyObject* cls);
41 static PyObject* PyUpb_MessageMeta_GetAttr(PyObject* self, PyObject* name);
42 
43 // -----------------------------------------------------------------------------
44 // CPythonBits
45 // -----------------------------------------------------------------------------
46 
47 // This struct contains a few things that are not exposed directly through the
48 // limited API, but that we can get at in somewhat more roundabout ways. The
49 // roundabout ways are slower, so we cache the values here.
50 //
51 // These values are valid to cache in a global, even across sub-interpreters,
52 // because they are not pointers to interpreter state. They are process
53 // globals that will be the same for any interpreter in this process.
54 typedef struct {
55  // For each member, we note the equivalent expression that we could use in the
56  // full (non-limited) API.
57  newfunc type_new; // PyTypeObject.tp_new
58  destructor type_dealloc; // PyTypeObject.tp_dealloc
59  getattrofunc type_getattro; // PyTypeObject.tp_getattro
60  setattrofunc type_setattro; // PyTypeObject.tp_setattro
61  size_t type_basicsize; // sizeof(PyHeapTypeObject)
62 
63  // While we can refer to PY_VERSION_HEX in the limited API, this will give us
64  // the version of Python we were compiled against, which may be different
65  // than the version we are dynamically linked against. Here we want the
66  // version that is actually running in this process.
67  long python_version_hex; // PY_VERSION_HEX
69 
70 // A global containing the values for this process.
72 
73 destructor upb_Pre310_PyType_GetDeallocSlot(PyTypeObject* type_subclass) {
74  // This is a bit desperate. We need type_dealloc(), but PyType_GetSlot(type,
75  // Py_tp_dealloc) will return subtype_dealloc(). There appears to be no way
76  // whatsoever to fetch type_dealloc() through the limited API until Python
77  // 3.10.
78  //
79  // To work around this so we attempt to find it by looking for the offset of
80  // tp_dealloc in PyTypeObject, then memcpy() it directly. This should always
81  // work in practice.
82  //
83  // Starting with Python 3.10 on you can call PyType_GetSlot() on non-heap
84  // types. We will be able to replace all this hack with just:
85  //
86  // PyType_GetSlot(&PyType_Type, Py_tp_dealloc)
87  //
88  destructor subtype_dealloc = PyType_GetSlot(type_subclass, Py_tp_dealloc);
89  for (size_t i = 0; i < 2000; i += sizeof(uintptr_t)) {
90  destructor maybe_subtype_dealloc;
91  memcpy(&maybe_subtype_dealloc, (char*)type_subclass + i,
92  sizeof(destructor));
93  if (maybe_subtype_dealloc == subtype_dealloc) {
94  destructor type_dealloc;
95  memcpy(&type_dealloc, (char*)&PyType_Type + i, sizeof(destructor));
96  return type_dealloc;
97  }
98  }
99  assert(false);
100  return NULL;
101 }
102 
104  PyObject* bases = NULL;
105  PyTypeObject* type = NULL;
106  PyObject* size = NULL;
107  PyObject* sys = NULL;
108  PyObject* hex_version = NULL;
109  bool ret = false;
110 
111  // PyType_GetSlot() only works on heap types, so we cannot use it on
112  // &PyType_Type directly. Instead we create our own (temporary) type derived
113  // from PyType_Type: this will inherit all of the slots from PyType_Type, but
114  // as a heap type it can be queried with PyType_GetSlot().
115  static PyType_Slot dummy_slots[] = {{0, NULL}};
116 
117  static PyType_Spec dummy_spec = {
118  "module.DummyClass", // tp_name
119  0, // To be filled in by size of base // tp_basicsize
120  0, // tp_itemsize
121  Py_TPFLAGS_DEFAULT, // tp_flags
122  dummy_slots,
123  };
124 
125  bases = Py_BuildValue("(O)", &PyType_Type);
126  if (!bases) goto err;
127  type = (PyTypeObject*)PyType_FromSpecWithBases(&dummy_spec, bases);
128  if (!type) goto err;
129 
130  bits->type_new = PyType_GetSlot(type, Py_tp_new);
131  bits->type_dealloc = upb_Pre310_PyType_GetDeallocSlot(type);
132  bits->type_getattro = PyType_GetSlot(type, Py_tp_getattro);
133  bits->type_setattro = PyType_GetSlot(type, Py_tp_setattro);
134 
135  size = PyObject_GetAttrString((PyObject*)&PyType_Type, "__basicsize__");
136  if (!size) goto err;
137  bits->type_basicsize = PyLong_AsLong(size);
138  if (bits->type_basicsize == -1) goto err;
139 
140  assert(bits->type_new);
141  assert(bits->type_dealloc);
142  assert(bits->type_getattro);
143  assert(bits->type_setattro);
144 
145 #ifndef Py_LIMITED_API
146  assert(bits->type_new == PyType_Type.tp_new);
147  assert(bits->type_dealloc == PyType_Type.tp_dealloc);
148  assert(bits->type_getattro == PyType_Type.tp_getattro);
149  assert(bits->type_setattro == PyType_Type.tp_setattro);
150  assert(bits->type_basicsize == sizeof(PyHeapTypeObject));
151 #endif
152 
153  sys = PyImport_ImportModule("sys");
154  hex_version = PyObject_GetAttrString(sys, "hexversion");
155  bits->python_version_hex = PyLong_AsLong(hex_version);
156  ret = true;
157 
158 err:
159  Py_XDECREF(bases);
160  Py_XDECREF(type);
161  Py_XDECREF(size);
162  Py_XDECREF(sys);
163  Py_XDECREF(hex_version);
164  return ret;
165 }
166 
167 // -----------------------------------------------------------------------------
168 // CMessage
169 // -----------------------------------------------------------------------------
170 
171 // The main message object. The type of the object (PyUpb_CMessage.ob_type)
172 // will be an instance of the PyUpb_MessageMeta type (defined below). So the
173 // chain is:
174 // FooMessage = MessageMeta(...)
175 // foo = FooMessage()
176 //
177 // Which becomes:
178 // Object C Struct Type Python type (ob_type)
179 // ----------------- ----------------- ---------------------
180 // foo PyUpb_CMessage FooMessage
181 // FooMessage PyUpb_MessageMeta message_meta_type
182 // message_meta_type PyTypeObject 'type' in Python
183 //
184 // A message object can be in one of two states: present or non-present. When
185 // a message is non-present, it stores a reference to its parent, and a write
186 // to any attribute will trigger the message to become present in its parent.
187 // The parent may also be non-present, in which case a mutation will trigger a
188 // chain reaction.
189 typedef struct PyUpb_CMessage {
191  PyObject* arena;
192  uintptr_t def; // Tagged, low bit 1 == upb_FieldDef*, else upb_MessageDef*
193  union {
194  // when def is msgdef, the data for this msg.
196  // when def is fielddef, owning pointer to parent
198  } ptr;
199  PyObject* ext_dict; // Weak pointer to extension dict, if any.
200  // name->obj dict for non-present msg/map/repeated, NULL if none.
202  int version;
204 
205 static PyObject* PyUpb_CMessage_GetAttr(PyObject* _self, PyObject* attr);
206 
207 bool PyUpb_CMessage_IsStub(PyUpb_CMessage* msg) { return msg->def & 1; }
208 
210  assert(PyUpb_CMessage_IsStub(msg));
211  return (void*)(msg->def & ~(uintptr_t)1);
212 }
213 
215  return PyUpb_CMessage_IsStub(msg)
217  : (void*)msg->def;
218 }
219 
220 const upb_MessageDef* PyUpb_CMessage_GetMsgdef(PyObject* self) {
222 }
223 
225  assert(!PyUpb_CMessage_IsStub(self));
226  return self->ptr.msg;
227 }
228 
229 bool PyUpb_CMessage_TryCheck(PyObject* self) {
231  PyObject* type = (PyObject*)Py_TYPE(self);
232  return Py_TYPE(type) == state->message_meta_type;
233 }
234 
235 bool PyUpb_CMessage_Verify(PyObject* self) {
236  if (!PyUpb_CMessage_TryCheck(self)) {
237  PyErr_Format(PyExc_TypeError, "Expected a message object, but got %R.",
238  self);
239  return false;
240  }
241  return true;
242 }
243 
244 // If the message is reified, returns it. Otherwise, returns NULL.
245 // If NULL is returned, the object is empty and has no underlying data.
247  PyUpb_CMessage* self = (void*)_self;
248  return PyUpb_CMessage_IsStub(self) ? NULL : self->ptr.msg;
249 }
250 
251 static PyObject* PyUpb_CMessage_New(PyObject* cls, PyObject* unused_args,
252  PyObject* unused_kwargs) {
254  PyUpb_CMessage* msg = (void*)PyType_GenericAlloc((PyTypeObject*)cls, 0);
255  msg->def = (uintptr_t)msgdef;
256  msg->arena = PyUpb_Arena_New();
257  msg->ptr.msg = upb_Message_New(msgdef, PyUpb_Arena_Get(msg->arena));
258  msg->unset_subobj_map = NULL;
259  msg->ext_dict = NULL;
260  msg->version = 0;
261 
262  PyObject* ret = &msg->ob_base;
263  PyUpb_ObjCache_Add(msg->ptr.msg, ret);
264  return ret;
265 }
266 
267 /*
268  * PyUpb_CMessage_LookupName()
269  *
270  * Tries to find a field or oneof named `py_name` in the message object `self`.
271  * The user must pass `f` and/or `o` to indicate whether a field or a oneof name
272  * is expected. If the name is found and it has an expected type, the function
273  * sets `*f` or `*o` respectively and returns true. Otherwise returns false
274  * and sets an exception of type `exc_type` if provided.
275  */
276 static bool PyUpb_CMessage_LookupName(PyUpb_CMessage* self, PyObject* py_name,
277  const upb_FieldDef** f,
278  const upb_OneofDef** o,
279  PyObject* exc_type) {
280  assert(f || o);
281  Py_ssize_t size;
282  const char* name = NULL;
283  if (PyUnicode_Check(py_name)) {
284  name = PyUnicode_AsUTF8AndSize(py_name, &size);
285  } else if (PyBytes_Check(py_name)) {
286  PyBytes_AsStringAndSize(py_name, (char**)&name, &size);
287  }
288  if (!name) {
289  PyErr_Format(exc_type,
290  "Expected a field name, but got non-string argument %S.",
291  py_name);
292  return false;
293  }
295 
297  if (exc_type) {
298  PyErr_Format(exc_type, "Protocol message %s has no \"%s\" field.",
300  }
301  return false;
302  }
303 
304  if (!o && !*f) {
305  if (exc_type) {
306  PyErr_Format(exc_type, "Expected a field name, but got oneof name %s.",
307  name);
308  }
309  return false;
310  }
311 
312  if (!f && !*o) {
313  if (exc_type) {
314  PyErr_Format(exc_type, "Expected a oneof name, but got field name %s.",
315  name);
316  }
317  return false;
318  }
319 
320  return true;
321 }
322 
323 static bool PyUpb_CMessage_InitMessageMapEntry(PyObject* dst, PyObject* src) {
324  if (!src || !dst) return false;
325 
326  // TODO(haberman): Currently we are doing Clear()+MergeFrom(). Replace with
327  // CopyFrom() once that is implemented.
328  PyObject* ok = PyObject_CallMethod(dst, "Clear", NULL);
329  if (!ok) return false;
330  Py_DECREF(ok);
331  ok = PyObject_CallMethod(dst, "MergeFrom", "O", src);
332  if (!ok) return false;
333  Py_DECREF(ok);
334 
335  return true;
336 }
337 
338 int PyUpb_CMessage_InitMapAttributes(PyObject* map, PyObject* value,
339  const upb_FieldDef* f) {
340  const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
341  const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
342  PyObject* it = NULL;
343  PyObject* tmp = NULL;
344  int ret = -1;
345  if (upb_FieldDef_IsSubMessage(val_f)) {
346  it = PyObject_GetIter(value);
347  if (it == NULL) {
348  PyErr_Format(PyExc_TypeError, "Argument for field %s is not iterable",
350  goto err;
351  }
352  PyObject* e;
353  while ((e = PyIter_Next(it)) != NULL) {
354  PyObject* src = PyObject_GetItem(value, e);
355  PyObject* dst = PyObject_GetItem(map, e);
356  Py_DECREF(e);
358  Py_XDECREF(src);
359  Py_XDECREF(dst);
360  if (!ok) goto err;
361  }
362  } else {
363  tmp = PyObject_CallMethod(map, "update", "O", value);
364  if (!tmp) goto err;
365  }
366  ret = 0;
367 
368 err:
369  Py_XDECREF(it);
370  Py_XDECREF(tmp);
371  return ret;
372 }
373 
375 
376 static bool PyUpb_CMessage_InitMapAttribute(PyObject* _self, PyObject* name,
377  const upb_FieldDef* f,
378  PyObject* value) {
379  PyObject* map = PyUpb_CMessage_GetAttr(_self, name);
381  Py_DECREF(map);
382  return ok >= 0;
383 }
384 
385 static bool PyUpb_CMessage_InitRepeatedAttribute(PyObject* _self,
386  PyObject* name,
387  PyObject* value) {
388  bool ok = false;
389  PyObject* tmp = NULL;
390  PyObject* repeated = PyUpb_CMessage_GetAttr(_self, name);
391  if (!repeated) goto err;
393  if (!tmp) goto err;
394  ok = true;
395 
396 err:
397  Py_XDECREF(repeated);
398  Py_XDECREF(tmp);
399  return ok;
400 }
401 
402 static bool PyUpb_CMessage_InitMessageAttribute(PyObject* _self, PyObject* name,
403  PyObject* value) {
404  PyObject* submsg = PyUpb_CMessage_GetAttr(_self, name);
405  if (!submsg) return -1;
406  assert(!PyErr_Occurred());
407  bool ok;
409  PyObject* tmp = PyUpb_CMessage_MergeFrom(submsg, value);
410  ok = tmp != NULL;
411  Py_DECREF(tmp);
412  } else if (PyDict_Check(value)) {
413  assert(!PyErr_Occurred());
414  ok = PyUpb_CMessage_InitAttributes(submsg, NULL, value) >= 0;
415  } else {
416  const upb_MessageDef* m = PyUpb_CMessage_GetMsgdef(_self);
417  PyErr_Format(PyExc_TypeError, "Message must be initialized with a dict: %s",
419  ok = false;
420  }
421  Py_DECREF(submsg);
422  return ok;
423 }
424 
426  const upb_FieldDef* f,
427  PyObject* value,
428  upb_Arena* arena) {
429  upb_MessageValue msgval;
430  assert(!PyErr_Occurred());
431  if (!PyUpb_PyToUpb(value, f, &msgval, arena)) return false;
432  upb_Message_Set(msg, f, msgval, arena);
433  return true;
434 }
435 
436 int PyUpb_CMessage_InitAttributes(PyObject* _self, PyObject* args,
437  PyObject* kwargs) {
438  assert(!PyErr_Occurred());
439 
440  if (args != NULL && PyTuple_Size(args) != 0) {
441  PyErr_SetString(PyExc_TypeError, "No positional arguments allowed");
442  return -1;
443  }
444 
445  if (kwargs == NULL) return 0;
446 
447  PyUpb_CMessage* self = (void*)_self;
448  Py_ssize_t pos = 0;
449  PyObject* name;
450  PyObject* value;
453  upb_Arena* arena = PyUpb_Arena_Get(self->arena);
454 
455  while (PyDict_Next(kwargs, &pos, &name, &value)) {
456  assert(!PyErr_Occurred());
457  const upb_FieldDef* f;
458  assert(!PyErr_Occurred());
459  if (!PyUpb_CMessage_LookupName(self, name, &f, NULL, PyExc_ValueError)) {
460  return -1;
461  }
462 
463  if (value == Py_None) continue; // Ignored.
464 
465  assert(!PyErr_Occurred());
466 
467  if (upb_FieldDef_IsMap(f)) {
468  if (!PyUpb_CMessage_InitMapAttribute(_self, name, f, value)) return -1;
469  } else if (upb_FieldDef_IsRepeated(f)) {
470  if (!PyUpb_CMessage_InitRepeatedAttribute(_self, name, value)) return -1;
471  } else if (upb_FieldDef_IsSubMessage(f)) {
472  if (!PyUpb_CMessage_InitMessageAttribute(_self, name, value)) return -1;
473  } else {
474  if (!PyUpb_CMessage_InitScalarAttribute(msg, f, value, arena)) return -1;
475  }
476  if (PyErr_Occurred()) return -1;
477  }
478 
479  if (PyErr_Occurred()) return -1;
480  return 0;
481 }
482 
483 static int PyUpb_CMessage_Init(PyObject* _self, PyObject* args,
484  PyObject* kwargs) {
485  if (args != NULL && PyTuple_Size(args) != 0) {
486  PyErr_SetString(PyExc_TypeError, "No positional arguments allowed");
487  return -1;
488  }
489 
490  return PyUpb_CMessage_InitAttributes(_self, args, kwargs);
491 }
492 
493 static PyObject* PyUpb_CMessage_NewStub(PyObject* parent, const upb_FieldDef* f,
494  PyObject* arena) {
496  PyObject* cls = PyUpb_Descriptor_GetClass(sub_m);
497 
498  PyUpb_CMessage* msg = (void*)PyType_GenericAlloc((PyTypeObject*)cls, 0);
499  msg->def = (uintptr_t)f | 1;
500  msg->arena = arena;
501  msg->ptr.parent = (PyUpb_CMessage*)parent;
502  msg->unset_subobj_map = NULL;
503  msg->ext_dict = NULL;
504  msg->version = 0;
505 
506  Py_DECREF(cls);
507  Py_INCREF(parent);
508  Py_INCREF(arena);
509  return &msg->ob_base;
510 }
511 
512 static bool PyUpb_CMessage_IsEqual(PyUpb_CMessage* m1, PyObject* _m2) {
513  PyUpb_CMessage* m2 = (void*)_m2;
514  if (m1 == m2) return true;
515  if (!PyObject_TypeCheck(_m2, m1->ob_base.ob_type)) {
516  return false;
517  }
518  const upb_MessageDef* m1_msgdef = _PyUpb_CMessage_GetMsgdef(m1);
519 #ifndef NDEBUG
520  const upb_MessageDef* m2_msgdef = _PyUpb_CMessage_GetMsgdef(m2);
521  assert(m1_msgdef == m2_msgdef);
522 #endif
523  const upb_Message* m1_msg = PyUpb_CMessage_GetIfReified((PyObject*)m1);
524  const upb_Message* m2_msg = PyUpb_CMessage_GetIfReified(_m2);
525  return PyUpb_Message_IsEqual(m1_msg, m2_msg, m1_msgdef);
526 }
527 
529  upb_Arena* arena) {
533  PyUpb_ObjCache_Add(m->ptr.msg, &m->ob_base);
534  return f;
535 }
536 
538  const upb_FieldDef* f,
543  // Releases a ref previously owned by child->ptr.parent of our child.
544  Py_DECREF(child);
545 }
546 
547 /*
548  * PyUpb_CMessage_EnsureReified()
549  *
550  * This implements the "expando" behavior of Python protos:
551  * foo = FooProto()
552  *
553  * # The intermediate messages don't really exist, and won't be serialized.
554  * x = foo.bar.bar.bar.bar.bar.baz
555  *
556  * # Now all the intermediate objects are created.
557  * foo.bar.bar.bar.bar.bar.baz = 5
558  *
559  * This function should be called before performing any mutation of a protobuf
560  * object.
561  *
562  * Post-condition:
563  * PyUpb_CMessage_IsStub(self) is false
564  */
566  if (!PyUpb_CMessage_IsStub(self)) return;
567  upb_Arena* arena = PyUpb_Arena_Get(self->arena);
568 
569  // This is a non-present message. We need to create a real upb_Message for
570  // this object and every parent until we reach a present message.
571  PyUpb_CMessage* child = self;
572  PyUpb_CMessage* parent = self->ptr.parent;
574  Py_INCREF(child); // To avoid a special-case in PyUpb_CMessage_SetField().
575 
576  do {
577  PyUpb_CMessage* next_parent = parent->ptr.parent;
578  const upb_FieldDef* parent_f = NULL;
581  }
583  child = parent;
584  child_f = parent_f;
585  parent = next_parent;
586  } while (child_f);
587 
588  // Releases ref previously owned by child->ptr.parent of our child.
589  Py_DECREF(child);
590  self->version++;
591 }
592 
593 static void PyUpb_CMessage_SyncSubobjs(PyUpb_CMessage* self);
594 
595 /*
596  * PyUpb_CMessage_Reify()
597  *
598  * The message equivalent of PyUpb_*Container_Reify(), this transitions
599  * the wrapper from the unset state (owning a reference on self->ptr.parent) to
600  * the set state (having a non-owning pointer to self->ptr.msg).
601  */
603  upb_Message* msg) {
604  assert(f == PyUpb_CMessage_GetFieldDef(self));
605  if (!msg) {
606  const upb_MessageDef* msgdef = PyUpb_CMessage_GetMsgdef((PyObject*)self);
608  }
609  PyUpb_ObjCache_Add(msg, &self->ob_base);
610  Py_DECREF(&self->ptr.parent->ob_base);
611  self->ptr.msg = msg; // Overwrites self->ptr.parent
612  self->def = (uintptr_t)upb_FieldDef_MessageSubDef(f);
614 }
615 
616 /*
617  * PyUpb_CMessage_SyncSubobjs()
618  *
619  * This operation must be invoked whenever the underlying upb_Message has been
620  * mutated directly in C. This will attach any newly-present field data
621  * to previously returned stub wrapper objects.
622  *
623  * For example:
624  * foo = FooMessage()
625  * sub = foo.submsg # Empty, unset sub-message
626  *
627  * # SyncSubobjs() is required to connect our existing 'sub' wrapper to the
628  * # newly created foo.submsg data in C.
629  * foo.MergeFrom(FooMessage(submsg={}))
630  *
631  * This requires that all of the new sub-objects that have appeared are owned
632  * by `self`'s arena.
633  */
635  PyUpb_WeakMap* subobj_map = self->unset_subobj_map;
636  if (!subobj_map) return;
637 
640  const void* key;
641  PyObject* obj;
642 
643  // The last ref to this message could disappear during iteration.
644  // When we call PyUpb_*Container_Reify() below, the container will drop
645  // its ref on `self`. If that was the last ref on self, the object will be
646  // deleted, and `subobj_map` along with it. We need it to live until we are
647  // done iterating.
648  Py_INCREF(&self->ob_base);
649 
650  while (PyUpb_WeakMap_Next(subobj_map, &key, &obj, &iter)) {
651  const upb_FieldDef* f = key;
652  if (upb_FieldDef_HasPresence(f) && !upb_Message_Has(msg, f)) continue;
654  PyUpb_WeakMap_DeleteIter(subobj_map, &iter);
655  if (upb_FieldDef_IsMap(f)) {
656  if (!msgval.map_val) continue;
658  } else if (upb_FieldDef_IsRepeated(f)) {
659  if (!msgval.array_val) continue;
661  } else {
662  PyUpb_CMessage* sub = (void*)obj;
663  assert(self == sub->ptr.parent);
664  PyUpb_CMessage_Reify(sub, f, (upb_Message*)msgval.msg_val);
665  }
666  }
667 
668  Py_DECREF(&self->ob_base);
669 
670  // TODO(haberman): present fields need to be iterated too if they can reach
671  // a WeakMap.
672 }
673 
674 static PyObject* PyUpb_CMessage_ToString(PyUpb_CMessage* self) {
675  if (PyUpb_CMessage_IsStub(self)) {
676  return PyUnicode_FromStringAndSize(NULL, 0);
677  }
681  char buf[1024];
683  size_t size = upb_TextEncode(msg, msgdef, symtab, options, buf, sizeof(buf));
684  if (size < sizeof(buf)) {
685  return PyUnicode_FromStringAndSize(buf, size);
686  } else {
687  char* buf2 = malloc(size + 1);
688  size_t size2 = upb_TextEncode(msg, msgdef, symtab, options, buf2, size + 1);
689  assert(size == size2);
690  PyObject* ret = PyUnicode_FromStringAndSize(buf2, size2);
691  free(buf2);
692  return ret;
693  }
694 }
695 
696 static PyObject* PyUpb_CMessage_RichCompare(PyObject* _self, PyObject* other,
697  int opid) {
698  PyUpb_CMessage* self = (void*)_self;
699  if (opid != Py_EQ && opid != Py_NE) {
700  Py_INCREF(Py_NotImplemented);
701  return Py_NotImplemented;
702  }
703  bool ret = PyUpb_CMessage_IsEqual(self, other);
704  if (opid == Py_NE) ret = !ret;
705  return PyBool_FromLong(ret);
706 }
707 
708 void PyUpb_CMessage_CacheDelete(PyObject* _self, const upb_FieldDef* f) {
709  PyUpb_CMessage* self = (void*)_self;
710  PyUpb_WeakMap_Delete(self->unset_subobj_map, f);
711 }
712 
713 void PyUpb_CMessage_SetConcreteSubobj(PyObject* _self, const upb_FieldDef* f,
714  upb_MessageValue subobj) {
715  PyUpb_CMessage* self = (void*)_self;
718  upb_Message_Set(self->ptr.msg, f, subobj, PyUpb_Arena_Get(self->arena));
719 }
720 
721 static void PyUpb_CMessage_Dealloc(PyObject* _self) {
722  PyUpb_CMessage* self = (void*)_self;
723 
724  if (PyUpb_CMessage_IsStub(self)) {
725  PyUpb_CMessage_CacheDelete((PyObject*)self->ptr.parent,
727  Py_DECREF(self->ptr.parent);
728  } else {
729  PyUpb_ObjCache_Delete(self->ptr.msg);
730  }
731 
732  if (self->unset_subobj_map) {
733  PyUpb_WeakMap_Free(self->unset_subobj_map);
734  }
735 
736  Py_DECREF(self->arena);
737 
738  // We do not use PyUpb_Dealloc() here because CMessage is a base type and for
739  // base types there is a bug we have to work around in this case (see below).
740  PyTypeObject* tp = Py_TYPE(self);
741  freefunc tp_free = PyType_GetSlot(tp, Py_tp_free);
742  tp_free(self);
743 
744  if (cpython_bits.python_version_hex >= 0x03080000) {
745  // Prior to Python 3.8 there is a bug where deallocating the type here would
746  // lead to a double-decref: https://bugs.python.org/issue37879
747  Py_DECREF(tp);
748  }
749 }
750 
752  PyObject* arena) {
753  PyObject* ret = PyUpb_ObjCache_Get(u_msg);
754  if (ret) return ret;
755 
756  PyObject* cls = PyUpb_Descriptor_GetClass(m);
757  // It is not safe to use PyObject_{,GC}_New() due to:
758  // https://bugs.python.org/issue35810
759  PyUpb_CMessage* py_msg = (void*)PyType_GenericAlloc((PyTypeObject*)cls, 0);
760  py_msg->arena = arena;
761  py_msg->def = (uintptr_t)m;
762  py_msg->ptr.msg = u_msg;
763  py_msg->unset_subobj_map = NULL;
764  py_msg->ext_dict = NULL;
765  py_msg->version = 0;
766  ret = &py_msg->ob_base;
767  Py_DECREF(cls);
768  Py_INCREF(arena);
769  PyUpb_ObjCache_Add(u_msg, ret);
770  return ret;
771 }
772 
773 /* PyUpb_CMessage_GetStub()
774  *
775  * Non-present messages return "stub" objects that point to their parent, but
776  * will materialize into real upb objects if they are mutated.
777  *
778  * Note: we do *not* create stubs for repeated/map fields unless the parent
779  * is a stub:
780  *
781  * msg = TestMessage()
782  * msg.submessage # (A) Creates a stub
783  * msg.repeated_foo # (B) Does *not* create a stub
784  * msg.submessage.repeated_bar # (C) Creates a stub
785  *
786  * In case (B) we have some freedom: we could either create a stub, or create
787  * a reified object with underlying data. It appears that either could work
788  * equally well, with no observable change to users. There isn't a clear
789  * advantage to either choice. We choose to follow the behavior of the
790  * pre-existing C++ behavior for consistency, but if it becomes apparent that
791  * there would be some benefit to reversing this decision, it should be totally
792  * within the realm of possibility.
793  */
795  const upb_FieldDef* field) {
796  PyObject* _self = (void*)self;
797  if (!self->unset_subobj_map) {
798  self->unset_subobj_map = PyUpb_WeakMap_New();
799  }
800  PyObject* subobj = PyUpb_WeakMap_Get(self->unset_subobj_map, field);
801 
802  if (subobj) return subobj;
803 
804  if (upb_FieldDef_IsMap(field)) {
805  subobj = PyUpb_MapContainer_NewStub(_self, field, self->arena);
806  } else if (upb_FieldDef_IsRepeated(field)) {
807  subobj = PyUpb_RepeatedContainer_NewStub(_self, field, self->arena);
808  } else {
809  subobj = PyUpb_CMessage_NewStub(&self->ob_base, field, self->arena);
810  }
811  PyUpb_WeakMap_Add(self->unset_subobj_map, field, subobj);
812 
813  assert(!PyErr_Occurred());
814  return subobj;
815 }
816 
818  const upb_FieldDef* field) {
819  assert(!PyUpb_CMessage_IsStub(self));
820  upb_MutableMessageValue mutval =
821  upb_Message_Mutable(self->ptr.msg, field, PyUpb_Arena_Get(self->arena));
822  if (upb_FieldDef_IsMap(field)) {
824  self->arena);
825  } else {
827  self->arena);
828  }
829 }
830 
832  const upb_FieldDef* field) {
833  upb_MessageValue val;
834  if (PyUpb_CMessage_IsStub(self)) {
835  // Unset message always returns default values.
837  } else {
838  val = upb_Message_Get(self->ptr.msg, field);
839  }
840  return PyUpb_UpbToPy(val, field, self->arena);
841 }
842 
843 /*
844  * PyUpb_CMessage_GetFieldValue()
845  *
846  * Implements the equivalent of getattr(msg, field), once `field` has
847  * already been resolved to a `upb_FieldDef*`.
848  *
849  * This may involve constructing a wrapper object for the given field, or
850  * returning one that was previously constructed. If the field is not actually
851  * set, the wrapper object will be an "unset" object that is not actually
852  * connected to any C data.
853  */
854 PyObject* PyUpb_CMessage_GetFieldValue(PyObject* _self,
855  const upb_FieldDef* field) {
856  PyUpb_CMessage* self = (void*)_self;
858  bool submsg = upb_FieldDef_IsSubMessage(field);
859  bool seq = upb_FieldDef_IsRepeated(field);
860 
861  if ((PyUpb_CMessage_IsStub(self) && (submsg || seq)) ||
862  (submsg && !seq && !upb_Message_Has(self->ptr.msg, field))) {
863  return PyUpb_CMessage_GetStub(self, field);
864  } else if (seq) {
866  } else {
867  return PyUpb_CMessage_GetScalarValue(self, field);
868  }
869 }
870 
871 int PyUpb_CMessage_SetFieldValue(PyObject* _self, const upb_FieldDef* field,
872  PyObject* value, PyObject* exc) {
873  PyUpb_CMessage* self = (void*)_self;
874  assert(value);
875 
877  PyErr_Format(exc,
878  "Assignment not allowed to message, map, or repeated "
879  "field \"%s\" in protocol message object.",
881  return -1;
882  }
883 
885 
886  upb_MessageValue val;
887  upb_Arena* arena = PyUpb_Arena_Get(self->arena);
888  if (!PyUpb_PyToUpb(value, field, &val, arena)) {
889  return -1;
890  }
891 
892  upb_Message_Set(self->ptr.msg, field, val, arena);
893  return 0;
894 }
895 
896 int PyUpb_CMessage_GetVersion(PyObject* _self) {
897  PyUpb_CMessage* self = (void*)_self;
898  return self->version;
899 }
900 
901 /*
902  * PyUpb_CMessage_GetAttr()
903  *
904  * Implements:
905  * foo = msg.foo
906  *
907  * Attribute lookup must find both message fields and base class methods like
908  * msg.SerializeToString().
909  */
911  PyObject* _self, PyObject* attr) {
912  PyUpb_CMessage* self = (void*)_self;
913 
914  // Lookup field by name.
915  const upb_FieldDef* field;
916  if (PyUpb_CMessage_LookupName(self, attr, &field, NULL, NULL)) {
917  return PyUpb_CMessage_GetFieldValue(_self, field);
918  }
919 
920  // Check base class attributes.
921  assert(!PyErr_Occurred());
922  PyObject* ret = PyObject_GenericGetAttr(_self, attr);
923  if (ret) return ret;
924 
925  // Swallow AttributeError if it occurred and try again on the metaclass
926  // to pick up class attributes. But we have to special-case "Extensions"
927  // which affirmatively returns AttributeError when a message is not
928  // extendable.
929  const char* name;
930  if (PyErr_ExceptionMatches(PyExc_AttributeError) &&
931  (name = PyUpb_GetStrData(attr)) && strcmp(name, "Extensions") != 0) {
932  PyErr_Clear();
933  return PyUpb_MessageMeta_GetAttr((PyObject*)Py_TYPE(_self), attr);
934  }
935 
936  return NULL;
937 }
938 
939 /*
940  * PyUpb_CMessage_SetAttr()
941  *
942  * Implements:
943  * msg.foo = foo
944  */
945 static int PyUpb_CMessage_SetAttr(PyObject* _self, PyObject* attr,
946  PyObject* value) {
947  PyUpb_CMessage* self = (void*)_self;
948  const upb_FieldDef* field;
949  if (!PyUpb_CMessage_LookupName(self, attr, &field, NULL,
950  PyExc_AttributeError)) {
951  return -1;
952  }
953 
955  PyExc_AttributeError);
956 }
957 
958 static PyObject* PyUpb_CMessage_HasField(PyObject* _self, PyObject* arg) {
959  PyUpb_CMessage* self = (void*)_self;
960  const upb_FieldDef* field;
961  const upb_OneofDef* oneof;
962 
963  if (!PyUpb_CMessage_LookupName(self, arg, &field, &oneof, PyExc_ValueError)) {
964  return NULL;
965  }
966 
968  PyErr_Format(PyExc_ValueError, "Field %s does not have presence.",
970  return NULL;
971  }
972 
973  if (PyUpb_CMessage_IsStub(self)) Py_RETURN_FALSE;
974 
975  return PyBool_FromLong(field ? upb_Message_Has(self->ptr.msg, field)
976  : upb_Message_WhichOneof(self->ptr.msg, oneof) !=
977  NULL);
978 }
979 
980 static PyObject* PyUpb_CMessage_FindInitializationErrors(PyObject* _self,
981  PyObject* arg);
982 
983 static PyObject* PyUpb_CMessage_IsInitializedAppendErrors(PyObject* _self,
984  PyObject* errors) {
985  PyObject* list = PyUpb_CMessage_FindInitializationErrors(_self, NULL);
986  if (!list) return NULL;
987  bool ok = PyList_Size(list) == 0;
988  PyObject* ret = NULL;
989  PyObject* extend_result = NULL;
990  if (!ok) {
991  extend_result = PyObject_CallMethod(errors, "extend", "O", list);
992  if (!extend_result) goto done;
993  }
994  ret = PyBool_FromLong(ok);
995 
996 done:
997  Py_XDECREF(list);
998  Py_XDECREF(extend_result);
999  return ret;
1000 }
1001 
1002 static PyObject* PyUpb_CMessage_IsInitialized(PyObject* _self, PyObject* args) {
1003  PyObject* errors = NULL;
1004  if (!PyArg_ParseTuple(args, "|O", &errors)) {
1005  return NULL;
1006  }
1007  if (errors) {
1008  // We need to collect a list of unset required fields and append it to
1009  // `errors`.
1011  } else {
1012  // We just need to return a boolean "true" or "false" for whether all
1013  // required fields are set.
1015  const upb_MessageDef* m = PyUpb_CMessage_GetMsgdef(_self);
1018  return PyBool_FromLong(initialized);
1019  }
1020 }
1021 
1022 static PyObject* PyUpb_CMessage_ListFieldsItemKey(PyObject* self,
1023  PyObject* val) {
1024  assert(PyTuple_Check(val));
1025  PyObject* field = PyTuple_GetItem(val, 0);
1027  return PyLong_FromLong(upb_FieldDef_Number(f));
1028 }
1029 
1030 static bool PyUpb_CMessage_SortFieldList(PyObject* list) {
1032  bool ok = false;
1033  PyObject* args = PyTuple_New(0);
1034  PyObject* kwargs = PyDict_New();
1035  PyObject* method = PyObject_GetAttrString(list, "sort");
1036  PyObject* call_result = NULL;
1037  if (!args || !kwargs || !method) goto err;
1038  if (PyDict_SetItemString(kwargs, "key", state->listfields_item_key) < 0) {
1039  goto err;
1040  }
1041  call_result = PyObject_Call(method, args, kwargs);
1042  if (!call_result) goto err;
1043  ok = true;
1044 
1045 err:
1046  Py_XDECREF(method);
1047  Py_XDECREF(args);
1048  Py_XDECREF(kwargs);
1049  Py_XDECREF(call_result);
1050  return ok;
1051 }
1052 
1053 static PyObject* PyUpb_CMessage_ListFields(PyObject* _self, PyObject* arg) {
1054  PyObject* list = PyList_New(0);
1056  if (!msg) return list;
1057 
1058  size_t iter1 = kUpb_Message_Begin;
1059  const upb_MessageDef* m = PyUpb_CMessage_GetMsgdef(_self);
1061  const upb_FieldDef* f;
1062  PyObject* field_desc = NULL;
1063  PyObject* py_val = NULL;
1064  PyObject* tuple = NULL;
1065  upb_MessageValue val;
1066  uint32_t last_field = 0;
1067  bool in_order = true;
1068  while (upb_Message_Next(msg, m, symtab, &f, &val, &iter1)) {
1069  const uint32_t field_number = upb_FieldDef_Number(f);
1070  if (field_number < last_field) in_order = false;
1071  last_field = field_number;
1072  PyObject* field_desc = PyUpb_FieldDescriptor_Get(f);
1073  PyObject* py_val = PyUpb_CMessage_GetFieldValue(_self, f);
1074  if (!field_desc || !py_val) goto err;
1075  PyObject* tuple = Py_BuildValue("(NN)", field_desc, py_val);
1076  field_desc = NULL;
1077  py_val = NULL;
1078  if (!tuple) goto err;
1079  if (PyList_Append(list, tuple)) goto err;
1080  Py_DECREF(tuple);
1081  tuple = NULL;
1082  }
1083 
1084  // Users rely on fields being returned in field number order.
1085  if (!in_order && !PyUpb_CMessage_SortFieldList(list)) goto err;
1086 
1087  return list;
1088 
1089 err:
1090  Py_XDECREF(field_desc);
1091  Py_XDECREF(py_val);
1092  Py_XDECREF(tuple);
1093  Py_DECREF(list);
1094  return NULL;
1095 }
1096 
1097 PyObject* PyUpb_CMessage_MergeFrom(PyObject* self, PyObject* arg) {
1098  if (self->ob_type != arg->ob_type) {
1099  PyErr_Format(PyExc_TypeError,
1100  "Parameter to MergeFrom() must be instance of same class: "
1101  "expected %S got %S.",
1102  Py_TYPE(self), Py_TYPE(arg));
1103  return NULL;
1104  }
1105  // OPT: exit if src is empty.
1106  PyObject* subargs = PyTuple_New(0);
1107  PyObject* serialized = PyUpb_CMessage_SerializeToString(arg, subargs, NULL);
1108  Py_DECREF(subargs);
1109  if (!serialized) return NULL;
1110  PyObject* ret = PyUpb_CMessage_MergeFromString(self, serialized);
1111  Py_DECREF(serialized);
1112  Py_DECREF(ret);
1113  Py_RETURN_NONE;
1114 }
1115 
1116 static PyObject* PyUpb_CMessage_SetInParent(PyObject* _self, PyObject* arg) {
1117  PyUpb_CMessage* self = (void*)_self;
1119  Py_RETURN_NONE;
1120 }
1121 
1122 static PyObject* PyUpb_CMessage_UnknownFields(PyObject* _self, PyObject* arg) {
1123  // TODO(haberman): re-enable when unknown fields are added.
1124  // return PyUpb_UnknownFields_New(_self);
1125  PyErr_SetString(PyExc_NotImplementedError, "unknown field accessor");
1126  return NULL;
1127 }
1128 
1129 PyObject* PyUpb_CMessage_MergeFromString(PyObject* _self, PyObject* arg) {
1130  PyUpb_CMessage* self = (void*)_self;
1131  char* buf;
1132  Py_ssize_t size;
1133  PyObject* bytes = NULL;
1134 
1135  if (PyMemoryView_Check(arg)) {
1136  bytes = PyBytes_FromObject(arg);
1137  // Cannot fail when passed something of the correct type.
1138  int err = PyBytes_AsStringAndSize(bytes, &buf, &size);
1139  (void)err;
1140  assert(err >= 0);
1141  } else if (PyBytes_AsStringAndSize(arg, &buf, &size) < 0) {
1142  return NULL;
1143  }
1144 
1148  const upb_ExtensionRegistry* extreg =
1151  upb_Arena* arena = PyUpb_Arena_Get(self->arena);
1153  int options =
1154  UPB_DECODE_MAXDEPTH(state->allow_oversize_protos ? UINT32_MAX : 100);
1156  upb_Decode(buf, size, self->ptr.msg, layout, extreg, options, arena);
1157  Py_XDECREF(bytes);
1158  if (status != kUpb_DecodeStatus_Ok) {
1159  PyErr_Format(state->decode_error_class, "Error parsing message");
1160  return NULL;
1161  }
1163  return PyLong_FromSsize_t(size);
1164 }
1165 
1166 static PyObject* PyUpb_CMessage_Clear(PyUpb_CMessage* self, PyObject* args);
1167 
1168 static PyObject* PyUpb_CMessage_ParseFromString(PyObject* self, PyObject* arg) {
1169  PyObject* tmp = PyUpb_CMessage_Clear((PyUpb_CMessage*)self, NULL);
1170  Py_DECREF(tmp);
1171  return PyUpb_CMessage_MergeFromString(self, arg);
1172 }
1173 
1174 static PyObject* PyUpb_CMessage_ByteSize(PyObject* self, PyObject* args) {
1175  // TODO(https://github.com/protocolbuffers/upb/issues/462): At the moment upb
1176  // does not have a "byte size" function, so we just serialize to string and
1177  // get the size of the string.
1178  PyObject* subargs = PyTuple_New(0);
1179  PyObject* serialized = PyUpb_CMessage_SerializeToString(self, subargs, NULL);
1180  Py_DECREF(subargs);
1181  if (!serialized) return NULL;
1182  size_t size = PyBytes_Size(serialized);
1183  Py_DECREF(serialized);
1184  return PyLong_FromSize_t(size);
1185 }
1186 
1187 static PyObject* PyUpb_CMessage_Clear(PyUpb_CMessage* self, PyObject* args) {
1190  PyUpb_WeakMap* subobj_map = self->unset_subobj_map;
1191 
1192  if (subobj_map) {
1195  const void* key;
1196  PyObject* obj;
1197 
1198  while (PyUpb_WeakMap_Next(subobj_map, &key, &obj, &iter)) {
1199  const upb_FieldDef* f = key;
1200  PyUpb_WeakMap_DeleteIter(subobj_map, &iter);
1201  if (upb_FieldDef_IsMap(f)) {
1202  assert(upb_Message_Get(msg, f).map_val == NULL);
1204  } else if (upb_FieldDef_IsRepeated(f)) {
1205  assert(upb_Message_Get(msg, f).array_val == NULL);
1207  } else {
1208  assert(!upb_Message_Has(msg, f));
1209  PyUpb_CMessage* sub = (void*)obj;
1210  assert(self == sub->ptr.parent);
1211  PyUpb_CMessage_Reify(sub, f, NULL);
1212  }
1213  }
1214  }
1215 
1216  upb_Message_Clear(self->ptr.msg, msgdef);
1217  Py_RETURN_NONE;
1218 }
1219 
1220 void PyUpb_CMessage_DoClearField(PyObject* _self, const upb_FieldDef* f) {
1221  PyUpb_CMessage* self = (void*)_self;
1223 
1224  // We must ensure that any stub object is reified so its parent no longer
1225  // points to us.
1226  PyObject* sub = self->unset_subobj_map
1227  ? PyUpb_WeakMap_Get(self->unset_subobj_map, f)
1228  : NULL;
1229 
1230  if (upb_FieldDef_IsMap(f)) {
1231  // For maps we additionally have to invalidate any iterators. So we need
1232  // to get an object even if it's reified.
1233  if (!sub) {
1234  sub = PyUpb_CMessage_GetFieldValue(_self, f);
1235  }
1238  } else if (upb_FieldDef_IsRepeated(f)) {
1239  if (sub) {
1241  }
1242  } else if (upb_FieldDef_IsSubMessage(f)) {
1243  if (sub) {
1245  }
1246  }
1247 
1248  Py_XDECREF(sub);
1249  upb_Message_ClearField(self->ptr.msg, f);
1250 }
1251 
1252 static PyObject* PyUpb_CMessage_ClearExtension(PyObject* _self, PyObject* arg) {
1253  PyUpb_CMessage* self = (void*)_self;
1256  if (!f) return NULL;
1258  Py_RETURN_NONE;
1259 }
1260 
1261 static PyObject* PyUpb_CMessage_ClearField(PyObject* _self, PyObject* arg) {
1262  PyUpb_CMessage* self = (void*)_self;
1263 
1264  // We always need EnsureReified() here (even for an unset message) to
1265  // preserve behavior like:
1266  // msg = FooMessage()
1267  // msg.foo.Clear()
1268  // assert msg.HasField("foo")
1270 
1271  const upb_FieldDef* f;
1272  const upb_OneofDef* o;
1273  if (!PyUpb_CMessage_LookupName(self, arg, &f, &o, PyExc_ValueError)) {
1274  return NULL;
1275  }
1276 
1277  if (o) f = upb_Message_WhichOneof(self->ptr.msg, o);
1279  Py_RETURN_NONE;
1280 }
1281 
1283  PyObject* arg) {
1286  upb_Message_DiscardUnknown(self->ptr.msg, msgdef, 64);
1287  Py_RETURN_NONE;
1288 }
1289 
1290 static PyObject* PyUpb_CMessage_FindInitializationErrors(PyObject* _self,
1291  PyObject* arg) {
1292  PyUpb_CMessage* self = (void*)_self;
1297  PyObject* ret = PyList_New(0);
1298  if (upb_util_HasUnsetRequired(msg, msgdef, ext_pool, &fields)) {
1299  char* buf = NULL;
1300  size_t size = 0;
1301  assert(fields->field);
1302  while (fields->field) {
1304  size_t need = upb_FieldPath_ToText(&fields, buf, size);
1305  if (need >= size) {
1306  fields = field;
1307  size = size ? size * 2 : 16;
1308  while (size <= need) size *= 2;
1309  buf = realloc(buf, size);
1310  need = upb_FieldPath_ToText(&fields, buf, size);
1311  assert(size > need);
1312  }
1313  PyObject* str = PyUnicode_FromString(buf);
1314  PyList_Append(ret, str);
1315  Py_DECREF(str);
1316  }
1317  free(buf);
1318  }
1319  return ret;
1320 }
1321 
1322 static PyObject* PyUpb_CMessage_FromString(PyObject* cls,
1323  PyObject* serialized) {
1324  PyObject* ret = NULL;
1325  PyObject* length = NULL;
1326 
1327  ret = PyObject_CallObject(cls, NULL);
1328  if (ret == NULL) goto err;
1329  length = PyUpb_CMessage_MergeFromString(ret, serialized);
1330  if (length == NULL) goto err;
1331 
1332 done:
1333  Py_XDECREF(length);
1334  return ret;
1335 
1336 err:
1337  Py_XDECREF(ret);
1338  ret = NULL;
1339  goto done;
1340 }
1341 
1343  PyObject* key) {
1345  if (!f) {
1346  PyErr_Clear();
1347  PyErr_Format(PyExc_KeyError, "Object %R is not a field descriptor\n", key);
1348  return NULL;
1349  }
1350  if (!upb_FieldDef_IsExtension(f)) {
1351  PyErr_Format(PyExc_KeyError, "Field %s is not an extension\n",
1353  return NULL;
1354  }
1357  PyErr_Format(PyExc_KeyError, "Extension doesn't match (%s vs %s)",
1359  return NULL;
1360  }
1361  return f;
1362 }
1363 
1364 static PyObject* PyUpb_CMessage_HasExtension(PyObject* _self,
1365  PyObject* ext_desc) {
1367  const upb_FieldDef* f = PyUpb_CMessage_GetExtensionDef(_self, ext_desc);
1368  if (!f) return NULL;
1369  if (upb_FieldDef_IsRepeated(f)) {
1370  PyErr_SetString(PyExc_KeyError,
1371  "Field is repeated. A singular method is required.");
1372  return NULL;
1373  }
1374  if (!msg) Py_RETURN_FALSE;
1375  return PyBool_FromLong(upb_Message_Has(msg, f));
1376 }
1377 
1379  PyObject* errors,
1380  PyObject* exc) {
1381  PyObject* comma = PyUnicode_FromString(",");
1382  PyObject* missing_fields = NULL;
1383  if (!comma) goto done;
1384  missing_fields = PyUnicode_Join(comma, errors);
1385  if (!missing_fields) goto done;
1386  PyErr_Format(exc, "Message %s is missing required fields: %U",
1387  upb_MessageDef_FullName(msgdef), missing_fields);
1388 done:
1389  Py_XDECREF(comma);
1390  Py_XDECREF(missing_fields);
1391  Py_DECREF(errors);
1392 }
1393 
1394 PyObject* PyUpb_CMessage_SerializeInternal(PyObject* _self, PyObject* args,
1395  PyObject* kwargs,
1396  bool check_required) {
1397  PyUpb_CMessage* self = (void*)_self;
1398  if (!PyUpb_CMessage_Verify((PyObject*)self)) return NULL;
1399  static const char* kwlist[] = {"deterministic", NULL};
1400  int deterministic = 0;
1401  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|p", (char**)(kwlist),
1402  &deterministic)) {
1403  return NULL;
1404  }
1405 
1407  if (PyUpb_CMessage_IsStub(self)) {
1408  // Nothing to serialize, but we do have to check whether the message is
1409  // initialized.
1411  PyObject* errors = PyUpb_CMessage_FindInitializationErrors(_self, NULL);
1412  if (!errors) return NULL;
1413  if (PyList_Size(errors) == 0) {
1414  Py_DECREF(errors);
1415  return PyBytes_FromStringAndSize(NULL, 0);
1416  }
1418  state->encode_error_class);
1419  return NULL;
1420  }
1421 
1424  size_t size = 0;
1425  // Python does not currently have any effective limit on serialization depth.
1427  if (check_required) options |= kUpb_Encode_CheckRequired;
1428  if (deterministic) options |= kUpb_Encode_Deterministic;
1429  char* pb = upb_Encode(self->ptr.msg, layout, options, arena, &size);
1430  PyObject* ret = NULL;
1431 
1432  if (!pb) {
1434  PyObject* errors = PyUpb_CMessage_FindInitializationErrors(_self, NULL);
1435  if (PyList_Size(errors) != 0) {
1437  state->encode_error_class);
1438  } else {
1439  PyErr_Format(state->encode_error_class, "Failed to serialize proto");
1440  }
1441  goto done;
1442  }
1443 
1444  ret = PyBytes_FromStringAndSize(pb, size);
1445 
1446 done:
1448  return ret;
1449 }
1450 
1451 PyObject* PyUpb_CMessage_SerializeToString(PyObject* _self, PyObject* args,
1452  PyObject* kwargs) {
1453  return PyUpb_CMessage_SerializeInternal(_self, args, kwargs, true);
1454 }
1455 
1457  PyObject* args,
1458  PyObject* kwargs) {
1459  return PyUpb_CMessage_SerializeInternal(_self, args, kwargs, false);
1460 }
1461 
1462 static PyObject* PyUpb_CMessage_WhichOneof(PyObject* _self, PyObject* name) {
1463  PyUpb_CMessage* self = (void*)_self;
1464  const upb_OneofDef* o;
1465  if (!PyUpb_CMessage_LookupName(self, name, NULL, &o, PyExc_ValueError)) {
1466  return NULL;
1467  }
1469  if (!msg) Py_RETURN_NONE;
1471  if (!f) Py_RETURN_NONE;
1472  return PyUnicode_FromString(upb_FieldDef_Name(f));
1473 }
1474 
1475 void PyUpb_CMessage_ClearExtensionDict(PyObject* _self) {
1476  PyUpb_CMessage* self = (void*)_self;
1477  assert(self->ext_dict);
1478  self->ext_dict = NULL;
1479 }
1480 
1481 static PyObject* PyUpb_CMessage_GetExtensionDict(PyObject* _self,
1482  void* closure) {
1483  PyUpb_CMessage* self = (void*)_self;
1484  if (self->ext_dict) {
1485  Py_INCREF(self->ext_dict);
1486  return self->ext_dict;
1487  }
1488 
1491  PyErr_SetNone(PyExc_AttributeError);
1492  return NULL;
1493  }
1494 
1495  self->ext_dict = PyUpb_ExtensionDict_New(_self);
1496  return self->ext_dict;
1497 }
1498 
1499 static PyGetSetDef PyUpb_CMessage_Getters[] = {
1500  {"Extensions", PyUpb_CMessage_GetExtensionDict, NULL, "Extension dict"},
1501  {NULL}};
1502 
1503 static PyMethodDef PyUpb_CMessage_Methods[] = {
1504  // TODO(https://github.com/protocolbuffers/upb/issues/459)
1505  //{ "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
1506  // "Makes a deep copy of the class." },
1507  //{ "__unicode__", (PyCFunction)ToUnicode, METH_NOARGS,
1508  // "Outputs a unicode representation of the message." },
1509  {"ByteSize", (PyCFunction)PyUpb_CMessage_ByteSize, METH_NOARGS,
1510  "Returns the size of the message in bytes."},
1511  {"Clear", (PyCFunction)PyUpb_CMessage_Clear, METH_NOARGS,
1512  "Clears the message."},
1513  {"ClearExtension", PyUpb_CMessage_ClearExtension, METH_O,
1514  "Clears a message field."},
1515  {"ClearField", PyUpb_CMessage_ClearField, METH_O,
1516  "Clears a message field."},
1517  // TODO(https://github.com/protocolbuffers/upb/issues/459)
1518  //{ "CopyFrom", (PyCFunction)CopyFrom, METH_O,
1519  // "Copies a protocol message into the current message." },
1520  {"DiscardUnknownFields", (PyCFunction)PyUpb_CMessage_DiscardUnknownFields,
1521  METH_NOARGS, "Discards the unknown fields."},
1522  {"FindInitializationErrors", PyUpb_CMessage_FindInitializationErrors,
1523  METH_NOARGS, "Finds unset required fields."},
1524  {"FromString", PyUpb_CMessage_FromString, METH_O | METH_CLASS,
1525  "Creates new method instance from given serialized data."},
1526  {"HasExtension", PyUpb_CMessage_HasExtension, METH_O,
1527  "Checks if a message field is set."},
1528  {"HasField", PyUpb_CMessage_HasField, METH_O,
1529  "Checks if a message field is set."},
1530  {"IsInitialized", PyUpb_CMessage_IsInitialized, METH_VARARGS,
1531  "Checks if all required fields of a protocol message are set."},
1532  {"ListFields", PyUpb_CMessage_ListFields, METH_NOARGS,
1533  "Lists all set fields of a message."},
1534  {"MergeFrom", PyUpb_CMessage_MergeFrom, METH_O,
1535  "Merges a protocol message into the current message."},
1536  {"MergeFromString", PyUpb_CMessage_MergeFromString, METH_O,
1537  "Merges a serialized message into the current message."},
1538  {"ParseFromString", PyUpb_CMessage_ParseFromString, METH_O,
1539  "Parses a serialized message into the current message."},
1540  // TODO(https://github.com/protocolbuffers/upb/issues/459)
1541  //{ "RegisterExtension", (PyCFunction)RegisterExtension, METH_O |
1542  // METH_CLASS,
1543  // "Registers an extension with the current message." },
1544  {"SerializePartialToString",
1546  METH_VARARGS | METH_KEYWORDS,
1547  "Serializes the message to a string, even if it isn't initialized."},
1548  {"SerializeToString", (PyCFunction)PyUpb_CMessage_SerializeToString,
1549  METH_VARARGS | METH_KEYWORDS,
1550  "Serializes the message to a string, only for initialized messages."},
1551  {"SetInParent", (PyCFunction)PyUpb_CMessage_SetInParent, METH_NOARGS,
1552  "Sets the has bit of the given field in its parent message."},
1553  {"UnknownFields", (PyCFunction)PyUpb_CMessage_UnknownFields, METH_NOARGS,
1554  "Parse unknown field set"},
1555  {"WhichOneof", PyUpb_CMessage_WhichOneof, METH_O,
1556  "Returns the name of the field set inside a oneof, "
1557  "or None if no field is set."},
1558  {"_ListFieldsItemKey", PyUpb_CMessage_ListFieldsItemKey,
1559  METH_O | METH_STATIC,
1560  "Compares ListFields() list entries by field number"},
1561  {NULL, NULL}};
1562 
1563 static PyType_Slot PyUpb_CMessage_Slots[] = {
1564  {Py_tp_dealloc, PyUpb_CMessage_Dealloc},
1565  {Py_tp_doc, "A ProtocolMessage"},
1566  {Py_tp_getattro, PyUpb_CMessage_GetAttr},
1567  {Py_tp_getset, PyUpb_CMessage_Getters},
1568  {Py_tp_hash, PyObject_HashNotImplemented},
1569  {Py_tp_methods, PyUpb_CMessage_Methods},
1570  {Py_tp_new, PyUpb_CMessage_New},
1571  {Py_tp_str, PyUpb_CMessage_ToString},
1572  {Py_tp_repr, PyUpb_CMessage_ToString},
1573  {Py_tp_richcompare, PyUpb_CMessage_RichCompare},
1574  {Py_tp_setattro, PyUpb_CMessage_SetAttr},
1575  {Py_tp_init, PyUpb_CMessage_Init},
1576  {0, NULL}};
1577 
1578 PyType_Spec PyUpb_CMessage_Spec = {
1579  PYUPB_MODULE_NAME ".CMessage", // tp_name
1580  sizeof(PyUpb_CMessage), // tp_basicsize
1581  0, // tp_itemsize
1582  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags
1584 };
1585 
1586 // -----------------------------------------------------------------------------
1587 // MessageMeta
1588 // -----------------------------------------------------------------------------
1589 
1590 // MessageMeta is the metaclass for message objects. The generated code uses it
1591 // to construct message classes, ie.
1592 //
1593 // FooMessage = _message.MessageMeta('FooMessage', (_message.Message), {...})
1594 //
1595 // (This is not quite true: at the moment the Python library subclasses
1596 // MessageMeta, and uses that subclass as the metaclass. There is a TODO below
1597 // to simplify this, so that the illustration above is indeed accurate).
1598 
1599 typedef struct {
1603 
1604 // The PyUpb_MessageMeta struct is trailing data tacked onto the end of
1605 // MessageMeta instances. This means that we get our instances of this struct
1606 // by adding the appropriate number of bytes.
1607 static PyUpb_MessageMeta* PyUpb_GetMessageMeta(PyObject* cls) {
1608 #ifndef NDEBUG
1610  assert(!state || cls->ob_type == state->message_meta_type);
1611 #endif
1612  return (PyUpb_MessageMeta*)((char*)cls + cpython_bits.type_basicsize);
1613 }
1614 
1615 static const upb_MessageDef* PyUpb_MessageMeta_GetMsgdef(PyObject* cls) {
1617  return PyUpb_Descriptor_GetDef(self->py_message_descriptor);
1618 }
1619 
1620 PyObject* PyUpb_MessageMeta_DoCreateClass(PyObject* py_descriptor,
1621  const char* name, PyObject* dict) {
1623  PyTypeObject* descriptor_type = state->descriptor_types[kPyUpb_Descriptor];
1624  if (!PyObject_TypeCheck(py_descriptor, descriptor_type)) {
1625  return PyErr_Format(PyExc_TypeError, "Expected a message Descriptor");
1626  }
1627 
1628  const upb_MessageDef* msgdef = PyUpb_Descriptor_GetDef(py_descriptor);
1629  assert(msgdef);
1631 
1632  PyObject* slots = PyTuple_New(0);
1633  if (!slots) return NULL;
1634  int status = PyDict_SetItemString(dict, "__slots__", slots);
1635  Py_DECREF(slots);
1636  if (status < 0) return NULL;
1637 
1638  // Bases are either:
1639  // (CMessage, Message) # for regular messages
1640  // (CMessage, Message, WktBase) # For well-known types
1641  PyObject* wkt_bases = PyUpb_GetWktBases(state);
1642  PyObject* wkt_base =
1643  PyDict_GetItemString(wkt_bases, upb_MessageDef_FullName(msgdef));
1644  PyObject* args;
1645  if (wkt_base == NULL) {
1646  args = Py_BuildValue("s(OO)O", name, state->cmessage_type,
1647  state->message_class, dict);
1648  } else {
1649  args = Py_BuildValue("s(OOO)O", name, state->cmessage_type,
1650  state->message_class, wkt_base, dict);
1651  }
1652 
1653  PyObject* ret = cpython_bits.type_new(state->message_meta_type, args, NULL);
1654  Py_DECREF(args);
1655  if (!ret) return NULL;
1656 
1658  meta->py_message_descriptor = py_descriptor;
1660  Py_INCREF(meta->py_message_descriptor);
1661 
1662  PyUpb_ObjCache_Add(meta->layout, ret);
1663 
1664  return ret;
1665 }
1666 
1667 static PyObject* PyUpb_MessageMeta_New(PyTypeObject* type, PyObject* args,
1668  PyObject* kwargs) {
1670  static const char* kwlist[] = {"name", "bases", "dict", 0};
1671  PyObject *bases, *dict;
1672  const char* name;
1673 
1674  // Check arguments: (name, bases, dict)
1675  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO!O!:type", (char**)kwlist,
1676  &name, &PyTuple_Type, &bases, &PyDict_Type,
1677  &dict)) {
1678  return NULL;
1679  }
1680 
1681  // Check bases: only (), or (message.Message,) are allowed
1682  Py_ssize_t size = PyTuple_Size(bases);
1683  if (!(size == 0 ||
1684  (size == 1 && PyTuple_GetItem(bases, 0) == state->message_class))) {
1685  PyErr_Format(PyExc_TypeError,
1686  "A Message class can only inherit from Message, not %S",
1687  bases);
1688  return NULL;
1689  }
1690 
1691  // Check dict['DESCRIPTOR']
1692  PyObject* py_descriptor = PyDict_GetItemString(dict, "DESCRIPTOR");
1693  if (py_descriptor == NULL) {
1694  PyErr_SetString(PyExc_TypeError, "Message class has no DESCRIPTOR");
1695  return NULL;
1696  }
1697 
1698  const upb_MessageDef* m = PyUpb_Descriptor_GetDef(py_descriptor);
1700  if (ret) return ret;
1701  return PyUpb_MessageMeta_DoCreateClass(py_descriptor, name, dict);
1702 }
1703 
1704 static void PyUpb_MessageMeta_Dealloc(PyObject* self) {
1707  Py_DECREF(meta->py_message_descriptor);
1708  PyTypeObject* tp = Py_TYPE(self);
1709  cpython_bits.type_dealloc(self);
1710  Py_DECREF(tp);
1711 }
1712 
1713 void PyUpb_MessageMeta_AddFieldNumber(PyObject* self, const upb_FieldDef* f) {
1714  PyObject* name =
1715  PyUnicode_FromFormat("%s_FIELD_NUMBER", upb_FieldDef_Name(f));
1716  PyObject* upper = PyObject_CallMethod(name, "upper", "");
1717  PyObject_SetAttr(self, upper, PyLong_FromLong(upb_FieldDef_Number(f)));
1718  Py_DECREF(name);
1719  Py_DECREF(upper);
1720 }
1721 
1722 static PyObject* PyUpb_MessageMeta_GetDynamicAttr(PyObject* self,
1723  PyObject* name) {
1724  const char* name_buf = PyUpb_GetStrData(name);
1725  if (!name_buf) return NULL;
1727  const upb_FileDef* filedef = upb_MessageDef_File(msgdef);
1728  const upb_DefPool* symtab = upb_FileDef_Pool(filedef);
1729 
1730  PyObject* py_key =
1731  PyBytes_FromFormat("%s.%s", upb_MessageDef_FullName(msgdef), name_buf);
1732  const char* key = PyUpb_GetStrData(py_key);
1733  PyObject* ret = NULL;
1735  const upb_EnumDef* enumdef;
1736  const upb_EnumValueDef* enumval;
1737  const upb_FieldDef* ext;
1738 
1739  if (nested) {
1741  } else if ((enumdef = upb_DefPool_FindEnumByName(symtab, key))) {
1743  PyObject* klass = state->enum_type_wrapper_class;
1745  ret = PyObject_CallFunctionObjArgs(klass, ret, NULL);
1746  } else if ((enumval = upb_DefPool_FindEnumByNameval(symtab, key))) {
1747  ret = PyLong_FromLong(upb_EnumValueDef_Number(enumval));
1748  } else if ((ext = upb_DefPool_FindExtensionByName(symtab, key))) {
1750  }
1751 
1752  Py_DECREF(py_key);
1753 
1754  const char* suffix = "_FIELD_NUMBER";
1755  size_t n = strlen(name_buf);
1756  size_t suffix_n = strlen(suffix);
1757  if (n > suffix_n && memcmp(suffix, name_buf + n - suffix_n, suffix_n) == 0) {
1758  // We can't look up field names dynamically, because the <NAME>_FIELD_NUMBER
1759  // naming scheme upper-cases the field name and is therefore non-reversible.
1760  // So we just add all field numbers.
1762  for (int i = 0; i < n; i++) {
1764  }
1766  for (int i = 0; i < n; i++) {
1769  }
1770  ret = PyObject_GenericGetAttr(self, name);
1771  }
1772 
1773  return ret;
1774 }
1775 
1776 static PyObject* PyUpb_MessageMeta_GetAttr(PyObject* self, PyObject* name) {
1777  // We want to first delegate to the type's tp_dict to retrieve any attributes
1778  // that were previously calculated and cached in the type's dict.
1779  PyObject* ret = cpython_bits.type_getattro(self, name);
1780  if (ret) return ret;
1781 
1782  // We did not find a cached attribute. Try to calculate the attribute
1783  // dynamically, using the descriptor as an argument.
1784  PyErr_Clear();
1786 
1787  if (ret) {
1788  PyObject_SetAttr(self, name, ret);
1789  PyErr_Clear();
1790  return ret;
1791  }
1792 
1793  PyErr_SetObject(PyExc_AttributeError, name);
1794  return NULL;
1795 }
1796 
1797 static PyType_Slot PyUpb_MessageMeta_Slots[] = {
1798  {Py_tp_new, PyUpb_MessageMeta_New},
1799  {Py_tp_dealloc, PyUpb_MessageMeta_Dealloc},
1800  {Py_tp_getattro, PyUpb_MessageMeta_GetAttr},
1801  {0, NULL}};
1802 
1803 static PyType_Spec PyUpb_MessageMeta_Spec = {
1804  PYUPB_MODULE_NAME ".MessageMeta", // tp_name
1805  0, // To be filled in by size of base // tp_basicsize
1806  0, // tp_itemsize
1807  // TODO(haberman): remove BASETYPE, Python should just use MessageMeta
1808  // directly instead of subclassing it.
1809  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags
1811 };
1812 
1813 static PyObject* PyUpb_MessageMeta_CreateType(void) {
1814  PyObject* bases = Py_BuildValue("(O)", &PyType_Type);
1815  if (!bases) return NULL;
1816  PyUpb_MessageMeta_Spec.basicsize =
1818  PyObject* type = PyType_FromSpecWithBases(&PyUpb_MessageMeta_Spec, bases);
1819  Py_DECREF(bases);
1820  return type;
1821 }
1822 
1823 bool PyUpb_InitMessage(PyObject* m) {
1824  if (!PyUpb_CPythonBits_Init(&cpython_bits)) return false;
1825  PyObject* message_meta_type = PyUpb_MessageMeta_CreateType();
1826 
1828  state->cmessage_type = PyUpb_AddClass(m, &PyUpb_CMessage_Spec);
1829  state->message_meta_type = (PyTypeObject*)message_meta_type;
1830 
1831  if (!state->cmessage_type || !state->message_meta_type) return false;
1832  if (PyModule_AddObject(m, "MessageMeta", message_meta_type)) return false;
1833  state->listfields_item_key = PyObject_GetAttrString(
1834  (PyObject*)state->cmessage_type, "_ListFieldsItemKey");
1835 
1836  PyObject* mod =
1837  PyImport_ImportModule(PYUPB_PROTOBUF_PUBLIC_PACKAGE ".message");
1838  if (mod == NULL) return false;
1839 
1840  state->encode_error_class = PyObject_GetAttrString(mod, "EncodeError");
1841  state->decode_error_class = PyObject_GetAttrString(mod, "DecodeError");
1842  state->message_class = PyObject_GetAttrString(mod, "Message");
1843  Py_DECREF(mod);
1844 
1845  PyObject* enum_type_wrapper = PyImport_ImportModule(
1846  PYUPB_PROTOBUF_INTERNAL_PACKAGE ".enum_type_wrapper");
1847  if (enum_type_wrapper == NULL) return false;
1848 
1849  state->enum_type_wrapper_class =
1850  PyObject_GetAttrString(enum_type_wrapper, "EnumTypeWrapper");
1851  Py_DECREF(enum_type_wrapper);
1852 
1853  if (!state->encode_error_class || !state->decode_error_class ||
1854  !state->message_class || !state->listfields_item_key ||
1855  !state->enum_type_wrapper_class) {
1856  return false;
1857  }
1858 
1859  return true;
1860 }
PyUpb_CMessage_IsInitialized
static PyObject * PyUpb_CMessage_IsInitialized(PyObject *_self, PyObject *args)
Definition: upb/python/message.c:1002
PyUpb_CMessage_NewStub
static PyObject * PyUpb_CMessage_NewStub(PyObject *parent, const upb_FieldDef *f, PyObject *arena)
Definition: upb/python/message.c:493
upb_MutableMessageValue::array
upb_Array * array
Definition: upb/upb/reflection.h:57
xds_interop_client.str
str
Definition: xds_interop_client.py:487
PyUpb_WeakMap
Definition: upb/python/protobuf.c:118
convert.h
upb_FieldDef_Number
uint32_t upb_FieldDef_Number(const upb_FieldDef *f)
Definition: upb/upb/def.c:541
upb_FieldPathEntry
Definition: required_fields.h:52
PyUpb_GetStrData
const char * PyUpb_GetStrData(PyObject *obj)
Definition: upb/python/protobuf.c:295
obj
OPENSSL_EXPORT const ASN1_OBJECT * obj
Definition: x509.h:1671
PyUpb_CMessage_InitAsMsg
static const upb_FieldDef * PyUpb_CMessage_InitAsMsg(PyUpb_CMessage *m, upb_Arena *arena)
Definition: upb/python/message.c:528
PyUpb_WeakMap_Delete
void PyUpb_WeakMap_Delete(PyUpb_WeakMap *map, const void *key)
Definition: upb/python/protobuf.c:144
dst
static const char dst[]
Definition: test-fs-copyfile.c:37
upb_Pre310_PyType_GetDeallocSlot
destructor upb_Pre310_PyType_GetDeallocSlot(PyTypeObject *type_subclass)
Definition: upb/python/message.c:73
UPB_DECODE_MAXDEPTH
#define UPB_DECODE_MAXDEPTH(depth)
Definition: php-upb.h:699
regen-readme.it
it
Definition: regen-readme.py:15
upb_DefPool_FindEnumByName
const upb_EnumDef * upb_DefPool_FindEnumByName(const upb_DefPool *s, const char *sym)
Definition: upb/upb/def.c:1135
PyUpb_CMessage_MergeFrom
PyObject * PyUpb_CMessage_MergeFrom(PyObject *self, PyObject *arg)
Definition: upb/python/message.c:1097
pos
int pos
Definition: libuv/docs/code/tty-gravity/main.c:11
PyUpb_CMessage_DoClearField
void PyUpb_CMessage_DoClearField(PyObject *_self, const upb_FieldDef *f)
Definition: upb/python/message.c:1220
PyUpb_MessageMeta_GetDynamicAttr
static PyObject * PyUpb_MessageMeta_GetDynamicAttr(PyObject *self, PyObject *name)
Definition: upb/python/message.c:1722
upb_Message_Clear
void upb_Message_Clear(upb_Message *msg, const upb_MessageDef *m)
Definition: reflection.c:241
PyUpb_CMessage_GetScalarValue
PyObject * PyUpb_CMessage_GetScalarValue(PyUpb_CMessage *self, const upb_FieldDef *field)
Definition: upb/python/message.c:831
kUpb_Encode_Deterministic
@ kUpb_Encode_Deterministic
Definition: encode.h:51
PyUpb_CMessage_Spec
PyType_Spec PyUpb_CMessage_Spec
Definition: upb/python/message.c:1578
upb_MessageDef_MiniTable
const upb_MiniTable * upb_MessageDef_MiniTable(const upb_MessageDef *m)
Definition: upb/upb/def.c:818
_PyUpb_CMessage_GetMsgdef
static const upb_MessageDef * _PyUpb_CMessage_GetMsgdef(PyUpb_CMessage *msg)
Definition: upb/python/message.c:214
upb_MutableMessageValue::map
upb_Map * map
Definition: upb/upb/reflection.h:55
kUpb_Encode_CheckRequired
@ kUpb_Encode_CheckRequired
Definition: encode.h:57
PyUpb_CMessage_IsStub
bool PyUpb_CMessage_IsStub(PyUpb_CMessage *msg)
Definition: upb/python/message.c:207
PyUpb_CMessage_Slots
static PyType_Slot PyUpb_CMessage_Slots[]
Definition: upb/python/message.c:1563
PyUpb_CMessage::unset_subobj_map
PyUpb_WeakMap * unset_subobj_map
Definition: upb/python/message.c:201
PyUpb_MapContainer_Reify
void PyUpb_MapContainer_Reify(PyObject *_self, upb_Map *map)
Definition: upb/python/map.c:106
PyUpb_CMessage_Verify
bool PyUpb_CMessage_Verify(PyObject *self)
Definition: upb/python/message.c:235
PyUpb_EnumDescriptor_Get
PyObject * PyUpb_EnumDescriptor_Get(const upb_EnumDef *enumdef)
Definition: descriptor.c:649
PyUpb_MessageMeta_DoCreateClass
PyObject * PyUpb_MessageMeta_DoCreateClass(PyObject *py_descriptor, const char *name, PyObject *dict)
Definition: upb/python/message.c:1620
upb_Decode
upb_DecodeStatus upb_Decode(const char *buf, size_t size, void *msg, const upb_MiniTable *l, const upb_ExtensionRegistry *extreg, int options, upb_Arena *arena)
Definition: decode.c:1076
upb_MessageDef
Definition: upb/upb/def.c:100
ext
void * ext
Definition: x509v3.h:87
upb_MessageDef_FindByNameWithSize
bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef *m, const char *name, size_t len, const upb_FieldDef **out_f, const upb_OneofDef **out_o)
Definition: upb/upb/def.c:750
upb_DefPool_ExtensionRegistry
const upb_ExtensionRegistry * upb_DefPool_ExtensionRegistry(const upb_DefPool *s)
Definition: upb/upb/def.c:3231
options
double_dict options[]
Definition: capstone_test.c:55
PyUpb_MessageMeta::layout
const upb_MiniTable * layout
Definition: upb/python/message.c:1600
PyUpb_MessageMeta_AddFieldNumber
void PyUpb_MessageMeta_AddFieldNumber(PyObject *self, const upb_FieldDef *f)
Definition: upb/python/message.c:1713
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
PyUpb_CMessage_InitScalarAttribute
static bool PyUpb_CMessage_InitScalarAttribute(upb_Message *msg, const upb_FieldDef *f, PyObject *value, upb_Arena *arena)
Definition: upb/python/message.c:425
PyUpb_CMessage_ClearField
static PyObject * PyUpb_CMessage_ClearField(PyObject *_self, PyObject *arg)
Definition: upb/python/message.c:1261
upb_DefPool_FindEnumByNameval
const upb_EnumValueDef * upb_DefPool_FindEnumByNameval(const upb_DefPool *s, const char *sym)
Definition: upb/upb/def.c:1140
upb_Message_ClearField
void upb_Message_ClearField(upb_Message *msg, const upb_FieldDef *f)
Definition: reflection.c:222
kUpb_DecodeStatus_Ok
@ kUpb_DecodeStatus_Ok
Definition: decode.h:72
PyUpb_UpbToPy
PyObject * PyUpb_UpbToPy(upb_MessageValue val, const upb_FieldDef *f, PyObject *arena)
Definition: upb/python/convert.c:35
error_ref_leak.err
err
Definition: error_ref_leak.py:35
UINT32_MAX
#define UINT32_MAX
Definition: stdint-msvc2008.h:142
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
PyUpb_ModuleState_GetFromModule
PyUpb_ModuleState * PyUpb_ModuleState_GetFromModule(PyObject *module)
Definition: upb/python/protobuf.c:82
status
absl::Status status
Definition: rls.cc:251
PyUpb_CMessage_GetMsgdef
const upb_MessageDef * PyUpb_CMessage_GetMsgdef(PyObject *self)
Definition: upb/python/message.c:220
PyUpb_Descriptor_GetDef
const upb_MessageDef * PyUpb_Descriptor_GetDef(PyObject *_self)
Definition: descriptor.c:639
PyUpb_CMessage_RichCompare
static PyObject * PyUpb_CMessage_RichCompare(PyObject *_self, PyObject *other, int opid)
Definition: upb/python/message.c:696
upb_MiniTable
Definition: msg_internal.h:185
PyUpb_MapContainer_Invalidate
void PyUpb_MapContainer_Invalidate(PyObject *obj)
Definition: upb/python/map.c:124
descriptor_type
zend_class_entry * descriptor_type
setup.name
name
Definition: setup.py:542
upb_OneofDef
Definition: upb/upb/def.c:157
PyUpb_CMessage::arena
PyObject * arena
Definition: upb/python/message.c:191
PyUpb_CMessage_SetConcreteSubobj
void PyUpb_CMessage_SetConcreteSubobj(PyObject *_self, const upb_FieldDef *f, upb_MessageValue subobj)
Definition: upb/python/message.c:713
PyUpb_CMessage_New
static PyObject * PyUpb_CMessage_New(PyObject *cls, PyObject *unused_args, PyObject *unused_kwargs)
Definition: upb/python/message.c:251
PyUpb_RepeatedContainer_Extend
PyObject * PyUpb_RepeatedContainer_Extend(PyObject *_self, PyObject *value)
Definition: repeated.c:221
PyUpb_CMessage_ByteSize
static PyObject * PyUpb_CMessage_ByteSize(PyObject *self, PyObject *args)
Definition: upb/python/message.c:1174
kPyUpb_Descriptor
@ kPyUpb_Descriptor
Definition: upb/python/descriptor.h:37
PyUpb_CMessage_LookupName
static bool PyUpb_CMessage_LookupName(PyUpb_CMessage *self, PyObject *py_name, const upb_FieldDef **f, const upb_OneofDef **o, PyObject *exc_type)
Definition: upb/python/message.c:276
upb_MessageDef_NestedExtensionCount
int upb_MessageDef_NestedExtensionCount(const upb_MessageDef *m)
Definition: upb/upb/def.c:810
PyUpb_GetWktBases
PyObject * PyUpb_GetWktBases(PyUpb_ModuleState *state)
Definition: upb/python/protobuf.c:95
PyUpb_CMessage_ReportInitializationErrors
void PyUpb_CMessage_ReportInitializationErrors(const upb_MessageDef *msgdef, PyObject *errors, PyObject *exc)
Definition: upb/python/message.c:1378
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:480
upb_Arena_New
UPB_INLINE upb_Arena * upb_Arena_New(void)
Definition: upb/upb/upb.h:267
initialized
bool initialized
Definition: timer_generic.cc:223
PyUpb_MapContainer_EnsureReified
upb_Map * PyUpb_MapContainer_EnsureReified(PyObject *_self)
Definition: upb/python/map.c:129
arena
grpc_core::ScopedArenaPtr arena
Definition: binder_transport_test.cc:237
upb_MessageValue::array_val
const upb_Array * array_val
Definition: upb/upb/reflection.h:50
PyUpb_MessageMeta_Slots
static PyType_Slot PyUpb_MessageMeta_Slots[]
Definition: upb/python/message.c:1797
PyUpb_CMessage_SetAttr
static int PyUpb_CMessage_SetAttr(PyObject *_self, PyObject *attr, PyObject *value)
Definition: upb/python/message.c:945
PyUpb_GetMessageMeta
static PyUpb_MessageMeta * PyUpb_GetMessageMeta(PyObject *cls)
Definition: upb/python/message.c:1607
upb_Message_New
upb_Message * upb_Message_New(const upb_MessageDef *m, upb_Arena *a)
Definition: reflection.c:95
cpython_bits
PyUpb_CPythonBits cpython_bits
Definition: upb/python/message.c:71
o
UnboundConversion o
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:97
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
upb_MessageValue
Definition: upb/upb/reflection.h:40
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
PyUpb_CMessage_FindInitializationErrors
static PyObject * PyUpb_CMessage_FindInitializationErrors(PyObject *_self, PyObject *arg)
Definition: upb/python/message.c:1290
upb_MessageDef_Name
const char * upb_MessageDef_Name(const upb_MessageDef *m)
Definition: upb/upb/def.c:713
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
PyUpb_CMessage_IsInitializedAppendErrors
static PyObject * PyUpb_CMessage_IsInitializedAppendErrors(PyObject *_self, PyObject *errors)
Definition: upb/python/message.c:983
errors
const char * errors
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc:841
kUpb_Message_Begin
#define kUpb_Message_Begin
Definition: upb/upb/reflection.h:113
PyUpb_CMessage::ptr
union PyUpb_CMessage::@695 ptr
upb_FieldDef_IsMap
bool upb_FieldDef_IsMap(const upb_FieldDef *f)
Definition: upb/upb/def.c:659
PyUpb_CMessage_SerializeToString
PyObject * PyUpb_CMessage_SerializeToString(PyObject *_self, PyObject *args, PyObject *kwargs)
Definition: upb/python/message.c:1451
PyUpb_RepeatedContainer_Reify
void PyUpb_RepeatedContainer_Reify(PyObject *_self, upb_Array *arr)
Definition: repeated.c:109
upb_FieldDef_HasPresence
bool upb_FieldDef_HasPresence(const upb_FieldDef *f)
Definition: upb/upb/def.c:671
PyUpb_CMessage_HasExtension
static PyObject * PyUpb_CMessage_HasExtension(PyObject *_self, PyObject *ext_desc)
Definition: upb/python/message.c:1364
PyUpb_CMessage_FromString
static PyObject * PyUpb_CMessage_FromString(PyObject *cls, PyObject *serialized)
Definition: upb/python/message.c:1322
PYUPB_PROTOBUF_INTERNAL_PACKAGE
#define PYUPB_PROTOBUF_INTERNAL_PACKAGE
Definition: upb/python/protobuf.h:40
descriptor.h
upb_Array
Definition: msg_internal.h:424
PyUpb_CMessage_DiscardUnknownFields
static PyObject * PyUpb_CMessage_DiscardUnknownFields(PyUpb_CMessage *self, PyObject *arg)
Definition: upb/python/message.c:1282
upb_FileDef_Pool
const upb_DefPool * upb_FileDef_Pool(const upb_FileDef *f)
Definition: upb/upb/def.c:993
upb_EnumValueDef
Definition: upb/upb/def.c:150
upb_Message_DiscardUnknown
bool upb_Message_DiscardUnknown(upb_Message *msg, const upb_MessageDef *m, int maxdepth)
Definition: reflection.c:351
UPB_ENCODE_MAXDEPTH
#define UPB_ENCODE_MAXDEPTH(depth)
Definition: php-upb.h:1948
bits
OPENSSL_EXPORT ASN1_BIT_STRING * bits
Definition: x509v3.h:482
upb_FieldDef_Default
upb_MessageValue upb_FieldDef_Default(const upb_FieldDef *f)
Definition: upb/upb/def.c:581
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
PyUpb_CPythonBits::type_getattro
getattrofunc type_getattro
Definition: upb/python/message.c:59
PyUpb_CMessage_GetExtensionDict
static PyObject * PyUpb_CMessage_GetExtensionDict(PyObject *_self, void *closure)
Definition: upb/python/message.c:1481
upb_FieldDef_IsExtension
bool upb_FieldDef_IsExtension(const upb_FieldDef *f)
Definition: upb/upb/def.c:543
extension_dict.h
PyUpb_CMessage
struct PyUpb_CMessage PyUpb_CMessage
arg
Definition: cmdline.cc:40
reflection.h
PYUPB_WEAKMAP_BEGIN
#define PYUPB_WEAKMAP_BEGIN
Definition: upb/python/protobuf.h:154
PyUpb_MessageMeta_New
static PyObject * PyUpb_MessageMeta_New(PyTypeObject *type, PyObject *args, PyObject *kwargs)
Definition: upb/python/message.c:1667
PyUpb_CMessage_Reify
static void PyUpb_CMessage_Reify(PyUpb_CMessage *self, const upb_FieldDef *f, upb_Message *msg)
Definition: upb/python/message.c:602
PyUpb_AddClass
PyTypeObject * PyUpb_AddClass(PyObject *m, PyType_Spec *spec)
Definition: upb/python/protobuf.c:274
upb_Message_Next
bool upb_Message_Next(const upb_Message *msg, const upb_MessageDef *m, const upb_DefPool *ext_pool, const upb_FieldDef **out_f, upb_MessageValue *out_val, size_t *iter)
Definition: reflection.c:245
googletest-filter-unittest.child
child
Definition: bloaty/third_party/googletest/googletest/test/googletest-filter-unittest.py:62
PyUpb_CMessage_InitMessageAttribute
static bool PyUpb_CMessage_InitMessageAttribute(PyObject *_self, PyObject *name, PyObject *value)
Definition: upb/python/message.c:402
intptr_t
_W64 signed int intptr_t
Definition: stdint-msvc2008.h:118
PyUpb_FieldDescriptor_Get
PyObject * PyUpb_FieldDescriptor_Get(const upb_FieldDef *field)
Definition: descriptor.c:870
upb_util_HasUnsetRequired
bool upb_util_HasUnsetRequired(const upb_Message *msg, const upb_MessageDef *m, const upb_DefPool *ext_pool, upb_FieldPathEntry **fields)
Definition: required_fields.c:293
PyUpb_ExtensionDict_New
PyObject * PyUpb_ExtensionDict_New(PyObject *msg)
Definition: extension_dict.c:42
PyUpb_CMessage_Getters
static PyGetSetDef PyUpb_CMessage_Getters[]
Definition: upb/python/message.c:1499
upb_MessageValue::msg_val
const upb_Message * msg_val
Definition: upb/upb/reflection.h:49
PyUpb_CMessage_Init
static int PyUpb_CMessage_Init(PyObject *_self, PyObject *args, PyObject *kwargs)
Definition: upb/python/message.c:483
uintptr_t
_W64 unsigned int uintptr_t
Definition: stdint-msvc2008.h:119
PyUpb_CMessage_CacheDelete
void PyUpb_CMessage_CacheDelete(PyObject *_self, const upb_FieldDef *f)
Definition: upb/python/message.c:708
layout
MessageLayout * layout
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:809
PyUpb_WeakMap_DeleteIter
void PyUpb_WeakMap_DeleteIter(PyUpb_WeakMap *map, intptr_t *iter)
Definition: upb/python/protobuf.c:177
PYUPB_PROTOBUF_PUBLIC_PACKAGE
#define PYUPB_PROTOBUF_PUBLIC_PACKAGE
Definition: upb/python/protobuf.h:39
upb_Message
void upb_Message
Definition: msg.h:49
upb_FieldDef_MessageSubDef
const upb_MessageDef * upb_FieldDef_MessageSubDef(const upb_FieldDef *f)
Definition: upb/upb/def.c:619
PyUpb_WeakMap_Get
PyObject * PyUpb_WeakMap_Get(PyUpb_WeakMap *map, const void *key)
Definition: upb/python/protobuf.c:156
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
PyUpb_FieldDescriptor_GetDef
const upb_FieldDef * PyUpb_FieldDescriptor_GetDef(PyObject *_self)
Definition: descriptor.c:864
PyUpb_CMessage_InitMessageMapEntry
static bool PyUpb_CMessage_InitMessageMapEntry(PyObject *dst, PyObject *src)
Definition: upb/python/message.c:323
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
PyUpb_CMessage_SortFieldList
static bool PyUpb_CMessage_SortFieldList(PyObject *list)
Definition: upb/python/message.c:1030
PyUpb_WeakMap_Add
void PyUpb_WeakMap_Add(PyUpb_WeakMap *map, const void *key, PyObject *py_obj)
Definition: upb/python/protobuf.c:139
PyUpb_CMessage_GetStub
PyObject * PyUpb_CMessage_GetStub(PyUpb_CMessage *self, const upb_FieldDef *field)
Definition: upb/python/message.c:794
upb_FieldDef
Definition: upb/upb/def.c:56
upb_DecodeStatus
upb_DecodeStatus
Definition: decode.h:71
nested
static int nested
Definition: test-callback-stack.c:39
upb_MessageDef_ExtensionRangeCount
int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef *m)
Definition: upb/upb/def.c:790
PyUpb_CMessage_InitRepeatedAttribute
static bool PyUpb_CMessage_InitRepeatedAttribute(PyObject *_self, PyObject *name, PyObject *value)
Definition: upb/python/message.c:385
upb_MessageValue::map_val
const upb_Map * map_val
Definition: upb/upb/reflection.h:48
PyUpb_RepeatedContainer_NewStub
PyObject * PyUpb_RepeatedContainer_NewStub(PyObject *parent, const upb_FieldDef *f, PyObject *arena)
Definition: repeated.c:165
upb_Message_Has
bool upb_Message_Has(const upb_Message *msg, const upb_FieldDef *f)
Definition: reflection.c:112
PyUpb_MessageMeta::py_message_descriptor
PyObject * py_message_descriptor
Definition: upb/python/message.c:1601
PyUpb_CMessage::msg
upb_Message * msg
Definition: upb/python/message.c:195
PyUpb_CMessage_SerializeInternal
PyObject * PyUpb_CMessage_SerializeInternal(PyObject *_self, PyObject *args, PyObject *kwargs, bool check_required)
Definition: upb/python/message.c:1394
PyUpb_RepeatedContainer_GetOrCreateWrapper
PyObject * PyUpb_RepeatedContainer_GetOrCreateWrapper(upb_Array *arr, const upb_FieldDef *f, PyObject *arena)
Definition: repeated.c:181
value
const char * value
Definition: hpack_parser_table.cc:165
PyUpb_MapContainer_NewStub
PyObject * PyUpb_MapContainer_NewStub(PyObject *parent, const upb_FieldDef *f, PyObject *arena)
Definition: upb/python/map.c:90
PyUpb_ObjCache_Get
PyObject * PyUpb_ObjCache_Get(const void *key)
Definition: upb/python/protobuf.c:206
symtab
upb_symtab * symtab
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:774
PyUpb_CMessage::version
int version
Definition: upb/python/message.c:202
PyUpb_CMessage_InitMapAttributes
int PyUpb_CMessage_InitMapAttributes(PyObject *map, PyObject *value, const upb_FieldDef *f)
Definition: upb/python/message.c:338
PyUpb_ModuleState_Get
PyUpb_ModuleState * PyUpb_ModuleState_Get(void)
Definition: upb/python/protobuf.c:89
PyUpb_CMessage_IsEqual
static bool PyUpb_CMessage_IsEqual(PyUpb_CMessage *m1, PyObject *_m2)
Definition: upb/python/message.c:512
message.h
upb_TextEncode
size_t upb_TextEncode(const upb_Message *msg, const upb_MessageDef *m, const upb_DefPool *ext_pool, int options, char *buf, size_t size)
Definition: text_encode.c:455
PyUpb_CMessage_HasField
static PyObject * PyUpb_CMessage_HasField(PyObject *_self, PyObject *arg)
Definition: upb/python/message.c:958
generate_copts.flatten
def flatten(*lists)
Definition: abseil-cpp/absl/copts/generate_copts.py:23
PyUpb_CMessage_ToString
static PyObject * PyUpb_CMessage_ToString(PyUpb_CMessage *self)
Definition: upb/python/message.c:674
upb_Encode
char * upb_Encode(const void *msg, const upb_MiniTable *l, int options, upb_Arena *arena, size_t *size)
Definition: encode.c:573
PyUpb_Arena_Get
upb_Arena * PyUpb_Arena_Get(PyObject *arena)
Definition: upb/python/protobuf.c:231
attr
OPENSSL_EXPORT X509_ATTRIBUTE * attr
Definition: x509.h:1666
upb_FieldDef_ContainingType
const upb_MessageDef * upb_FieldDef_ContainingType(const upb_FieldDef *f)
Definition: upb/upb/def.c:563
PyUpb_CMessage_SetField
static void PyUpb_CMessage_SetField(PyUpb_CMessage *parent, const upb_FieldDef *f, PyUpb_CMessage *child, upb_Arena *arena)
Definition: upb/python/message.c:537
PyUpb_CMessage_GetExtensionDef
const upb_FieldDef * PyUpb_CMessage_GetExtensionDef(PyObject *_self, PyObject *key)
Definition: upb/python/message.c:1342
PyUpb_MessageMeta_Spec
static PyType_Spec PyUpb_MessageMeta_Spec
Definition: upb/python/message.c:1803
field
const FieldDescriptor * field
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc:2692
key
const char * key
Definition: hpack_parser_table.cc:164
PyUpb_Arena_New
PyObject * PyUpb_Arena_New(void)
Definition: upb/python/protobuf.c:219
PYUPB_MODULE_NAME
#define PYUPB_MODULE_NAME
Definition: upb/python/protobuf.h:43
suffix
unsigned char suffix[65536]
Definition: bloaty/third_party/zlib/examples/gun.c:164
bytes
uint8 bytes[10]
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:153
PyUpb_CPythonBits::python_version_hex
long python_version_hex
Definition: upb/python/message.c:67
upb_FileDef
Definition: upb/upb/def.c:171
def.h
PyUpb_WeakMap_New
PyUpb_WeakMap * PyUpb_WeakMap_New(void)
Definition: upb/python/protobuf.c:123
PyUpb_CMessage_GetFieldDef
const upb_FieldDef * PyUpb_CMessage_GetFieldDef(PyUpb_CMessage *msg)
Definition: upb/python/message.c:209
upb_Message_Mutable
upb_MutableMessageValue upb_Message_Mutable(upb_Message *msg, const upb_FieldDef *f, upb_Arena *a)
Definition: reflection.c:164
upb_MessageDef_NestedExtension
const upb_FieldDef * upb_MessageDef_NestedExtension(const upb_MessageDef *m, int i)
Definition: upb/upb/def.c:849
PyUpb_CMessage_MergeFromString
PyObject * PyUpb_CMessage_MergeFromString(PyObject *_self, PyObject *arg)
Definition: upb/python/message.c:1129
upb_Message_Get
upb_MessageValue upb_Message_Get(const upb_Message *msg, const upb_FieldDef *f)
Definition: reflection.c:146
PyUpb_CMessage_UnknownFields
static PyObject * PyUpb_CMessage_UnknownFields(PyObject *_self, PyObject *arg)
Definition: upb/python/message.c:1122
upb_FieldDef_IsRepeated
bool upb_FieldDef_IsRepeated(const upb_FieldDef *f)
Definition: upb/upb/def.c:651
PyUpb_ModuleState
Definition: upb/python/protobuf.h:66
upb_FieldPath_ToText
size_t upb_FieldPath_ToText(upb_FieldPathEntry **path, char *buf, size_t size)
Definition: required_fields.c:119
upb_Message_WhichOneof
const upb_FieldDef * upb_Message_WhichOneof(const upb_Message *msg, const upb_OneofDef *o)
Definition: reflection.c:131
PyUpb_ObjCache_Add
void PyUpb_ObjCache_Add(const void *key, PyObject *py_obj)
Definition: upb/python/protobuf.c:190
PyUpb_CMessage_SetInParent
static PyObject * PyUpb_CMessage_SetInParent(PyObject *_self, PyObject *arg)
Definition: upb/python/message.c:1116
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
PyUpb_InitMessage
bool PyUpb_InitMessage(PyObject *m)
Definition: upb/python/message.c:1823
PyUpb_CMessage_Dealloc
static void PyUpb_CMessage_Dealloc(PyObject *_self)
Definition: upb/python/message.c:721
PyUpb_CMessage_ClearExtensionDict
void PyUpb_CMessage_ClearExtensionDict(PyObject *_self)
Definition: upb/python/message.c:1475
profile_analyzer.fields
list fields
Definition: profile_analyzer.py:266
PyUpb_CMessage_EnsureReified
void PyUpb_CMessage_EnsureReified(PyUpb_CMessage *self)
Definition: upb/python/message.c:565
msgdef
const upb_msgdef * msgdef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:808
__attribute__
__attribute__((flatten))
Definition: upb/python/message.c:910
PyUpb_CMessage::PyObject_HEAD
PyObject_HEAD
Definition: upb/python/message.c:190
PyUpb_MessageMeta_CreateType
static PyObject * PyUpb_MessageMeta_CreateType(void)
Definition: upb/python/message.c:1813
enumdef
const upb_enumdef * enumdef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:839
PyUpb_RepeatedContainer_EnsureReified
upb_Array * PyUpb_RepeatedContainer_EnsureReified(PyObject *_self)
Definition: repeated.c:124
PyUpb_CMessage::ext_dict
PyObject * ext_dict
Definition: upb/python/message.c:199
ok
bool ok
Definition: async_end2end_test.cc:197
state
Definition: bloaty/third_party/zlib/contrib/blast/blast.c:41
PyUpb_CPythonBits_Init
static bool PyUpb_CPythonBits_Init(PyUpb_CPythonBits *bits)
Definition: upb/python/message.c:103
upb_DefPool_FindExtensionByName
const upb_FieldDef * upb_DefPool_FindExtensionByName(const upb_DefPool *s, const char *sym)
Definition: upb/upb/def.c:1181
UPB_TXTENC_SKIPUNKNOWN
@ UPB_TXTENC_SKIPUNKNOWN
Definition: text_encode.h:42
upb_MessageDef_FullName
const char * upb_MessageDef_FullName(const upb_MessageDef *m)
Definition: upb/upb/def.c:701
PyUpb_MapContainer_GetOrCreateWrapper
PyObject * PyUpb_MapContainer_GetOrCreateWrapper(upb_Map *map, const upb_FieldDef *f, PyObject *arena)
Definition: upb/python/map.c:319
closure
Definition: proxy.cc:59
PyUpb_CMessage_Get
PyObject * PyUpb_CMessage_Get(upb_Message *u_msg, const upb_MessageDef *m, PyObject *arena)
Definition: upb/python/message.c:751
PyUpb_CMessage_InitMapAttribute
static bool PyUpb_CMessage_InitMapAttribute(PyObject *_self, PyObject *name, const upb_FieldDef *f, PyObject *value)
Definition: upb/python/message.c:376
upb_MessageDef_File
const upb_FileDef * upb_MessageDef_File(const upb_MessageDef *m)
Definition: upb/upb/def.c:705
buf2
static char buf2[32]
Definition: test-fs.c:127
PyUpb_MessageMeta_GetAttr
static PyObject * PyUpb_MessageMeta_GetAttr(PyObject *self, PyObject *name)
Definition: upb/python/message.c:1776
PyUpb_CMessage_Clear
static PyObject * PyUpb_CMessage_Clear(PyUpb_CMessage *self, PyObject *args)
Definition: upb/python/message.c:1187
upb_MutableMessageValue
Definition: upb/upb/reflection.h:54
PyUpb_CMessage_SerializePartialToString
PyObject * PyUpb_CMessage_SerializePartialToString(PyObject *_self, PyObject *args, PyObject *kwargs)
Definition: upb/python/message.c:1456
PyUpb_CMessage_SyncSubobjs
static void PyUpb_CMessage_SyncSubobjs(PyUpb_CMessage *self)
Definition: upb/python/message.c:634
PyUpb_CPythonBits::type_setattro
setattrofunc type_setattro
Definition: upb/python/message.c:60
upb_FieldDef_IsSubMessage
bool upb_FieldDef_IsSubMessage(const upb_FieldDef *f)
Definition: upb/upb/def.c:642
PyUpb_CPythonBits
Definition: upb/python/message.c:54
PyUpb_MessageMeta_GetMsgdef
static const upb_MessageDef * PyUpb_MessageMeta_GetMsgdef(PyObject *cls)
Definition: upb/python/message.c:1615
PyUpb_CMessage_GetFieldValue
PyObject * PyUpb_CMessage_GetFieldValue(PyObject *_self, const upb_FieldDef *field)
Definition: upb/python/message.c:854
upb_EnumDef
Definition: upb/upb/def.c:134
upb_Map
Definition: msg_internal.h:581
PyUpb_Descriptor_GetClass
PyObject * PyUpb_Descriptor_GetClass(const upb_MessageDef *m)
Definition: descriptor.c:210
PyUpb_CMessage_ListFields
static PyObject * PyUpb_CMessage_ListFields(PyObject *_self, PyObject *arg)
Definition: upb/python/message.c:1053
iter
Definition: test_winkernel.cpp:47
PyUpb_CMessage_GetMsg
static upb_Message * PyUpb_CMessage_GetMsg(PyUpb_CMessage *self)
Definition: upb/python/message.c:224
upb_FieldDef_Name
const char * upb_FieldDef_Name(const upb_FieldDef *f)
Definition: upb/upb/def.c:549
Py_TYPE
#define Py_TYPE(ob)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor.cc:164
PyUpb_CMessage::parent
struct PyUpb_CMessage * parent
Definition: upb/python/message.c:197
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
PyUpb_CMessage_ListFieldsItemKey
static PyObject * PyUpb_CMessage_ListFieldsItemKey(PyObject *self, PyObject *val)
Definition: upb/python/message.c:1022
autogen_x86imm.tmp
tmp
Definition: autogen_x86imm.py:12
PyUpb_CMessage_TryCheck
bool PyUpb_CMessage_TryCheck(PyObject *self)
Definition: upb/python/message.c:229
PyUpb_CMessage_ParseFromString
static PyObject * PyUpb_CMessage_ParseFromString(PyObject *self, PyObject *arg)
Definition: upb/python/message.c:1168
upb_MessageDef_FieldCount
int upb_MessageDef_FieldCount(const upb_MessageDef *m)
Definition: upb/upb/def.c:794
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
PyUpb_WeakMap_Free
void PyUpb_WeakMap_Free(PyUpb_WeakMap *map)
Definition: upb/python/protobuf.c:131
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
self
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern self
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/map.c:543
upb_MessageDef_Field
const upb_FieldDef * upb_MessageDef_Field(const upb_MessageDef *m, int i)
Definition: upb/upb/def.c:828
regress.m
m
Definition: regress/regress.py:25
method
NSString * method
Definition: ProtoMethod.h:28
upb_Message_Set
bool upb_Message_Set(upb_Message *msg, const upb_FieldDef *f, upb_MessageValue val, upb_Arena *a)
Definition: reflection.c:202
PyUpb_CMessage_InitAttributes
int PyUpb_CMessage_InitAttributes(PyObject *_self, PyObject *args, PyObject *kwargs)
Definition: upb/python/message.c:436
PyUpb_CPythonBits::type_dealloc
destructor type_dealloc
Definition: upb/python/message.c:58
PyUpb_CMessage_SetFieldValue
int PyUpb_CMessage_SetFieldValue(PyObject *_self, const upb_FieldDef *field, PyObject *value, PyObject *exc)
Definition: upb/python/message.c:871
PyUpb_CMessage
Definition: upb/python/message.c:189
PyUpb_ObjCache_Delete
void PyUpb_ObjCache_Delete(const void *key)
Definition: upb/python/protobuf.c:194
PyUpb_MessageMeta_Dealloc
static void PyUpb_MessageMeta_Dealloc(PyObject *self)
Definition: upb/python/message.c:1704
klass
zend_class_entry * klass
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:810
PyUpb_CPythonBits::type_basicsize
size_t type_basicsize
Definition: upb/python/message.c:61
map.h
PyUpb_CMessage_GetIfReified
upb_Message * PyUpb_CMessage_GetIfReified(PyObject *_self)
Definition: upb/python/message.c:246
PyUpb_CMessage_Methods
static PyMethodDef PyUpb_CMessage_Methods[]
Definition: upb/python/message.c:1503
upb_DefPool
Definition: upb/upb/def.c:217
PyUpb_CPythonBits::type_new
newfunc type_new
Definition: upb/python/message.c:57
text_encode.h
upb_EnumValueDef_Number
int32_t upb_EnumValueDef_Number(const upb_EnumValueDef *ev)
Definition: upb/upb/def.c:458
upb_Arena
Definition: upb_internal.h:36
required_fields.h
upb_DefPool_FindMessageByName
const upb_MessageDef * upb_DefPool_FindMessageByName(const upb_DefPool *s, const char *sym)
Definition: upb/upb/def.c:1125
repeated
static grpc_slice repeated(char c, size_t length)
Definition: message_compress_test.cc:109
upb_Arena_Free
void upb_Arena_Free(upb_Arena *a)
Definition: upb/upb/upb.c:273
PyUpb_ModuleState_MaybeGet
PyUpb_ModuleState * PyUpb_ModuleState_MaybeGet(void)
Definition: upb/python/protobuf.c:77
PyUpb_CMessage_GetAttr
static PyObject * PyUpb_CMessage_GetAttr(PyObject *_self, PyObject *attr)
upb_FieldDef_FullName
const char * upb_FieldDef_FullName(const upb_FieldDef *f)
Definition: upb/upb/def.c:496
upb_ExtensionRegistry
Definition: msg.c:372
PyUpb_MessageMeta
Definition: upb/python/message.c:1599
PyUpb_CMessage_GetVersion
int PyUpb_CMessage_GetVersion(PyObject *_self)
Definition: upb/python/message.c:896
PyUpb_CMessage_WhichOneof
static PyObject * PyUpb_CMessage_WhichOneof(PyObject *_self, PyObject *name)
Definition: upb/python/message.c:1462
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
PyUpb_CMessage::def
uintptr_t def
Definition: upb/python/message.c:192
repeated.h
PyUpb_CMessage_GetPresentWrapper
PyObject * PyUpb_CMessage_GetPresentWrapper(PyUpb_CMessage *self, const upb_FieldDef *field)
Definition: upb/python/message.c:817
PyUpb_CMessage_ClearExtension
static PyObject * PyUpb_CMessage_ClearExtension(PyObject *_self, PyObject *arg)
Definition: upb/python/message.c:1252
PyUpb_PyToUpb
bool PyUpb_PyToUpb(PyObject *obj, const upb_FieldDef *f, upb_MessageValue *val, upb_Arena *arena)
Definition: upb/python/convert.c:179
PyUpb_WeakMap_Next
bool PyUpb_WeakMap_Next(PyUpb_WeakMap *map, const void **key, PyObject **obj, intptr_t *iter)
Definition: upb/python/protobuf.c:167
PyUpb_Message_IsEqual
bool PyUpb_Message_IsEqual(const upb_Message *msg1, const upb_Message *msg2, const upb_MessageDef *m)
Definition: upb/python/convert.c:336


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:00:36