message.c 66 KB

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