// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#include "python/message.h"

#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "google/protobuf/breaking_changes.h"
#include "python/convert.h"
#include "python/descriptor.h"
#include "python/descriptor_pool.h"
#include "python/extension_dict.h"
#include "python/free_threading/lazy_ptr.h"
#include "python/free_threading/weak_map.h"
#include "python/map.h"
#include "python/protobuf.h"
#include "python/repeated.h"
#include "upb/base/status.h"
#include "upb/mem/alloc.h"
#include "upb/mem/arena.h"
#include "upb/message/array.h"
#include "upb/message/compare.h"
#include "upb/message/copy.h"
#include "upb/message/map.h"
#include "upb/message/message.h"
#include "upb/mini_table/extension_registry.h"
#include "upb/mini_table/message.h"
#include "upb/port/atomic.h"
#include "upb/reflection/def.h"
#include "upb/reflection/message.h"
#include "upb/text/encode.h"
#include "upb/util/required_fields.h"
#include "upb/wire/decode.h"
#include "upb/wire/encode.h"

// Must be last.
#include "upb/port/def.inc"

static const upb_MessageDef* PyUpb_MessageMeta_GetMsgdef(PyObject* cls);
static PyObject* PyUpb_MessageMeta_GetAttr(PyObject* self, PyObject* name);
static PyObject* PyUpb_Message_GetDescriptor(PyObject* self);

// -----------------------------------------------------------------------------
// CPythonBits
// -----------------------------------------------------------------------------

// This struct contains a few things that are not exposed directly through the
// limited API, but that we can get at in somewhat more roundabout ways. The
// roundabout ways are slower, so we cache the values here.
//
// These values are valid to cache in a global, even across sub-interpreters,
// because they are not pointers to interpreter state.  They are process
// globals that will be the same for any interpreter in this process.
typedef struct {
  // For each member, we note the equivalent expression that we could use in the
  // full (non-limited) API.
  newfunc type_new;            // PyTypeObject.tp_new
  destructor type_dealloc;     // PyTypeObject.tp_dealloc
  getattrofunc type_getattro;  // PyTypeObject.tp_getattro
  setattrofunc type_setattro;  // PyTypeObject.tp_setattro
  size_t type_basicsize;       // sizeof(PyHeapTypeObject)
  traverseproc type_traverse;  // PyTypeObject.tp_traverse
  inquiry type_clear;          // PyTypeObject.tp_clear
} PyUpb_CPythonBits;

// A global containing the values for this process.
PyUpb_CPythonBits cpython_bits;

destructor upb_Pre310_PyType_GetDeallocSlot(PyTypeObject* type_subclass) {
  // This is a bit desperate.  We need type_dealloc(), but PyType_GetSlot(type,
  // Py_tp_dealloc) will return subtype_dealloc().  There appears to be no way
  // whatsoever to fetch type_dealloc() through the limited API until Python
  // 3.10.
  //
  // To work around this so we attempt to find it by looking for the offset of
  // tp_dealloc in PyTypeObject, then memcpy() it directly.  This should always
  // work in practice.
  //
  // Starting with Python 3.10 on you can call PyType_GetSlot() on non-heap
  // types.  We will be able to replace all this hack with just:
  //
  //   PyType_GetSlot(&PyType_Type, Py_tp_dealloc)
  //
  destructor subtype_dealloc = PyType_GetSlot(type_subclass, Py_tp_dealloc);
  for (size_t i = 0; i < 2000; i += sizeof(uintptr_t)) {
    destructor maybe_subtype_dealloc;
    memcpy(&maybe_subtype_dealloc, (char*)type_subclass + i,
           sizeof(destructor));
    if (maybe_subtype_dealloc == subtype_dealloc) {
      destructor type_dealloc;
      memcpy(&type_dealloc, (char*)&PyType_Type + i, sizeof(destructor));
      return type_dealloc;
    }
  }
  assert(false);
  return NULL;
}

static bool PyUpb_CPythonBits_Init(PyUpb_CPythonBits* bits) {
  PyObject* bases = NULL;
  PyTypeObject* type = NULL;
  PyObject* size = NULL;
  PyObject* sys = NULL;
  PyObject* hex_version = NULL;
  bool ret = false;

  // PyType_GetSlot() only works on heap types, so we cannot use it on
  // &PyType_Type directly. Instead we create our own (temporary) type derived
  // from PyType_Type: this will inherit all of the slots from PyType_Type, but
  // as a heap type it can be queried with PyType_GetSlot().
  static PyType_Slot dummy_slots[] = {{0, NULL}};

  static PyType_Spec dummy_spec = {
      "module.DummyClass",  // tp_name
      0,  // To be filled in by size of base     // tp_basicsize
      0,  // tp_itemsize
      Py_TPFLAGS_DEFAULT,  // tp_flags
      dummy_slots,
  };

  bases = Py_BuildValue("(O)", &PyType_Type);
  if (!bases) goto err;
  type = (PyTypeObject*)PyType_FromSpecWithBases(&dummy_spec, bases);
  if (!type) goto err;

  bits->type_new = PyType_GetSlot(type, Py_tp_new);
  bits->type_dealloc = upb_Pre310_PyType_GetDeallocSlot(type);
  bits->type_getattro = PyType_GetSlot(type, Py_tp_getattro);
  bits->type_setattro = PyType_GetSlot(type, Py_tp_setattro);
  bits->type_traverse = PyType_GetSlot(type, Py_tp_traverse);
  bits->type_clear = PyType_GetSlot(type, Py_tp_clear);

  size = PyObject_GetAttrString((PyObject*)&PyType_Type, "__basicsize__");
  if (!size) goto err;
  bits->type_basicsize = PyLong_AsLong(size);
  if (bits->type_basicsize == (size_t)-1) goto err;

  assert(bits->type_new);
  assert(bits->type_dealloc);
  assert(bits->type_getattro);
  assert(bits->type_setattro);
  assert(bits->type_traverse);
  assert(bits->type_clear);

#ifndef Py_LIMITED_API
  assert(bits->type_new == PyType_Type.tp_new);
  assert(bits->type_dealloc == PyType_Type.tp_dealloc);
  assert(bits->type_getattro == PyType_Type.tp_getattro);
  assert(bits->type_setattro == PyType_Type.tp_setattro);
  assert(bits->type_basicsize == sizeof(PyHeapTypeObject));
  assert(bits->type_traverse == PyType_Type.tp_traverse);
  assert(bits->type_clear == PyType_Type.tp_clear);
#endif

  sys = PyImport_ImportModule("sys");
  hex_version = PyObject_GetAttrString(sys, "hexversion");
  ret = true;

err:
  Py_XDECREF(bases);
  Py_XDECREF(type);
  Py_XDECREF(size);
  Py_XDECREF(sys);
  Py_XDECREF(hex_version);
  return ret;
}

// -----------------------------------------------------------------------------
// Message
// -----------------------------------------------------------------------------

// The main message object.  The type of the object (PyUpb_Message.ob_type)
// will be an instance of the PyUpb_MessageMeta type (defined below).  So the
// chain is:
//   FooMessage = MessageMeta(...)
//   foo = FooMessage()
//
// Which becomes:
//   Object             C Struct Type        Python type (ob_type)
//   -----------------  -----------------    ---------------------
//   foo                PyUpb_Message        FooMessage
//   FooMessage         PyUpb_MessageMeta    message_meta_type
//   message_meta_type  PyTypeObject         'type' in Python
//
// A message object can be in one of two states: present or non-present.  When
// a message is non-present, it stores a reference to its parent, and a write
// to any attribute will trigger the message to become present in its parent.
// The parent may also be non-present, in which case a mutation will trigger a
// chain reaction.
typedef struct PyUpb_Message {
  // clang-format off
  PyObject_HEAD
  PyObject* arena;
  // clang-format on
  uintptr_t def;  // Tagged, low bit 1 == upb_FieldDef*, else upb_MessageDef*
  union {
    // when def is msgdef, the data for this msg.
    upb_Message* msg;
    // when def is fielddef, owning pointer to parent
    struct PyUpb_Message* parent;
  } ptr;
  PyObject* ext_dict;  // Weak pointer to extension dict, if any.

  // upb_FieldDef* -> obj dict for non-present msg/map/repeated, NULL if none.
  //
  // This has to be separate from the cache in the arena because it takes both
  // a parent message *and* a upb_FieldDef to uniquely identify a subobject, but
  // a cache can only be keyed by a single pointer.
  PYUPB_LAZYPTR(PyUpb_WeakMap) unset_subobj_map;

  int version;
} PyUpb_Message;

static PyObject* PyUpb_Message_GetAttr(PyObject* _self, PyObject* attr);
static PyObject* PyUpb_Message_Clear(PyUpb_Message* self);

bool PyUpb_Message_IsStub(PyUpb_Message* msg) { return msg->def & 1; }

const upb_FieldDef* PyUpb_Message_GetFieldDef(PyUpb_Message* msg) {
  assert(PyUpb_Message_IsStub(msg));
  return (void*)(msg->def & ~(uintptr_t)1);
}

static const upb_MessageDef* _PyUpb_Message_GetMsgdef(PyUpb_Message* msg) {
  return PyUpb_Message_IsStub(msg)
             ? upb_FieldDef_MessageSubDef(PyUpb_Message_GetFieldDef(msg))
             : (void*)msg->def;
}

const upb_MessageDef* PyUpb_Message_GetMsgdef(PyObject* self) {
  return _PyUpb_Message_GetMsgdef((PyUpb_Message*)self);
}

static upb_Message* PyUpb_Message_GetMsg(PyUpb_Message* self) {
  assert(!PyUpb_Message_IsStub(self));
  return self->ptr.msg;
}

bool PyUpb_Message_TryCheck(PyObject* self) {
  PyUpb_ModuleState* state = PyUpb_ModuleState_MaybeGet();
  if (!state) return false;
  PyObject* type = (PyObject*)Py_TYPE(self);
  return Py_TYPE(type) == state->message_meta_type;
}

bool PyUpb_Message_Verify(PyObject* self) {
  if (!PyUpb_Message_TryCheck(self)) {
    PyErr_Format(PyExc_TypeError, "Expected a message object, but got %R.",
                 self);
    return false;
  }
  return true;
}

// If the message is reified, returns it.  Otherwise, returns NULL.
// If NULL is returned, the object is empty and has no underlying data.
upb_Message* PyUpb_Message_GetIfReified(PyObject* _self) {
  PyUpb_Message* self = (void*)_self;
  return PyUpb_Message_IsStub(self) ? NULL : self->ptr.msg;
}

static PyObject* PyUpb_Message_New(PyObject* cls, PyObject* unused_args,
                                   PyObject* unused_kwargs) {
  const upb_MessageDef* msgdef = PyUpb_MessageMeta_GetMsgdef(cls);
  const upb_MiniTable* layout = upb_MessageDef_MiniTable(msgdef);
  PyUpb_Message* msg = (void*)PyType_GenericAlloc((PyTypeObject*)cls, 0);
  if (!msg) return NULL;
  msg->def = (uintptr_t)msgdef;
  msg->arena = PyUpb_Arena_New(PyUpb_MessageClass_GetPool((PyObject*)cls));
  if (!msg->arena) goto err1;
  msg->ptr.msg = upb_Message_New(layout, PyUpb_Arena_Get(msg->arena));
  if (!msg->ptr.msg) {
    PyErr_SetNone(PyExc_MemoryError);
    goto err1;
  }
  msg->unset_subobj_map = NULL;
  msg->ext_dict = NULL;
  msg->version = 0;

  PyObject* ret = &msg->ob_base;
  if (!PyUpb_Arena_CacheAdd(msg->arena, msg->ptr.msg, &ret)) goto err2;
  return ret;

err2:
  Py_DECREF(msg->arena);
err1:
  Py_DECREF(msg);
  return NULL;
}

/*
 * PyUpb_Message_LookupName()
 *
 * Tries to find a field or oneof named `py_name` in the message object `self`.
 * The user must pass `f` and/or `o` to indicate whether a field or a oneof name
 * is expected.  If the name is found and it has an expected type, the function
 * sets `*f` or `*o` respectively and returns true.  Otherwise returns false
 * and sets an exception of type `exc_type` if provided.
 */
static bool PyUpb_Message_LookupName(PyUpb_Message* self, PyObject* py_name,
                                     const upb_FieldDef** f,
                                     const upb_OneofDef** o,
                                     PyObject* exc_type) {
  assert(f || o);
  Py_ssize_t size;
  const char* name = NULL;
  if (PyUnicode_Check(py_name)) {
    name = PyUnicode_AsUTF8AndSize(py_name, &size);
  } else if (PyBytes_Check(py_name)) {
    PyBytes_AsStringAndSize(py_name, (char**)&name, &size);
  }
  if (!name) {
    PyErr_Format(exc_type,
                 "Expected a field name, but got non-string argument %S.",
                 py_name);
    return false;
  }
  const upb_MessageDef* msgdef = _PyUpb_Message_GetMsgdef(self);

  if (!upb_MessageDef_FindByNameWithSize(msgdef, name, size, f, o)) {
    if (exc_type) {
      PyErr_Format(exc_type, "Protocol message %s has no \"%s\" field.",
                   upb_MessageDef_Name(msgdef), name);
    }
    return false;
  }

  if (!o && !*f) {
    if (exc_type) {
      PyErr_Format(exc_type, "Expected a field name, but got oneof name %s.",
                   name);
    }
    return false;
  }

  if (!f && !*o) {
    if (exc_type) {
      PyErr_Format(exc_type, "Expected a oneof name, but got field name %s.",
                   name);
    }
    return false;
  }

  return true;
}

static bool PyUpb_Message_InitMessageMapEntry(PyObject* dst, PyObject* src) {
  if (!src || !dst) return false;

  if (PyDict_Check(src)) {
    bool ok = PyUpb_Message_InitAttributes(dst, NULL, src) >= 0;
    if (!ok) return false;
  } else {
    PyObject* ok = PyObject_CallMethod(dst, "CopyFrom", "O", src);
    if (!ok) return false;
    Py_DECREF(ok);
  }

  return true;
}

int PyUpb_Message_InitMapAttributes(PyObject* map, PyObject* value,
                                    const upb_FieldDef* f) {
  const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
  const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
  PyObject* it = NULL;
  PyObject* tmp = NULL;
  int ret = -1;
  if (upb_FieldDef_IsSubMessage(val_f)) {
    it = PyObject_GetIter(value);
    if (it == NULL) {
      PyErr_Format(PyExc_TypeError, "Argument for field %s is not iterable",
                   upb_FieldDef_FullName(f));
      goto err;
    }
    PyObject* e;
    while ((e = PyIter_Next(it)) != NULL) {
      PyObject* src = PyObject_GetItem(value, e);
      PyObject* dst = PyObject_GetItem(map, e);
      Py_DECREF(e);
      bool ok = PyUpb_Message_InitMessageMapEntry(dst, src);
      Py_XDECREF(src);
      Py_XDECREF(dst);
      if (!ok) goto err;
    }
  } else {
    tmp = PyObject_CallMethod(map, "update", "O", value);
    if (!tmp) goto err;
  }
  ret = 0;

err:
  Py_XDECREF(it);
  Py_XDECREF(tmp);
  return ret;
}

bool PyUpb_Message_AssureWritable(PyUpb_Message* self);

static bool PyUpb_Message_InitMapAttribute(PyObject* _self, PyObject* name,
                                           const upb_FieldDef* f,
                                           PyObject* value) {
  PyObject* map = PyUpb_Message_GetAttr(_self, name);
  int ok = PyUpb_Message_InitMapAttributes(map, value, f);
  Py_DECREF(map);
  return ok >= 0;
}

static bool PyUpb_Message_InitWKTOrMerge(const upb_MessageDef* msgdef,
                                         PyObject* msg, PyObject* value) {
  if (PyObject_TypeCheck(value, Py_TYPE(msg))) {
    PyObject* merged = PyUpb_Message_MergeFrom(msg, value);
    if (!merged) return false;
    Py_DECREF(merged);
    return true;
  }

  if (PyDict_Check(value) &&
      (upb_MessageDef_WellKnownType(msgdef) == kUpb_WellKnown_Struct)) {
    bool ok = PyObject_CallMethod(msg, "_internal_assign", "O", value);
    if (!ok && PyDict_Size(value) == 1) {
      PyObject* fields_str = PyUnicode_FromString("fields");
      if (PyDict_Contains(value, fields_str)) {
        // Fall back to init as normal message field.
        PyErr_Clear();
        PyObject* tmp = PyUpb_Message_Clear((PyUpb_Message*)msg);
        if (!tmp) return false;
        Py_DECREF(tmp);
        ok = PyUpb_Message_InitAttributes(msg, NULL, value) >= 0;
      }
      Py_DECREF(fields_str);
    }
    return ok;
  }
  if (upb_MessageDef_WellKnownType(msgdef) != kUpb_WellKnown_Unspecified &&
      PyObject_HasAttrString(msg, "_internal_assign")) {
    return PyObject_CallMethod(msg, "_internal_assign", "O", value);
  }

  PyErr_Format(PyExc_TypeError,
               "Parameter to initialize message field must be "
               "dict or instance of same class: expected %S got %S.",
               Py_TYPE(msg), Py_TYPE(value));
  return false;
}
static bool PyUpb_Message_InitRepeatedMessageAttribute(PyObject* _self,
                                                       PyObject* repeated,
                                                       PyObject* value,
                                                       const upb_FieldDef* f) {
  PyObject* it = PyObject_GetIter(value);
  if (!it) {
    PyErr_Format(PyExc_TypeError, "Argument for field %s is not iterable",
                 upb_FieldDef_FullName(f));
    return false;
  }
  PyObject* e = NULL;
  PyObject* m = NULL;
  const upb_MessageDef* m_def = upb_FieldDef_MessageSubDef(f);
  while ((e = PyIter_Next(it)) != NULL) {
    if (PyDict_Check(e) &&
        (upb_MessageDef_WellKnownType(m_def) != kUpb_WellKnown_Struct)) {
      m = PyUpb_RepeatedCompositeContainer_Add(repeated, NULL, e);
      if (!m) goto err;
    } else {
      m = PyUpb_RepeatedCompositeContainer_Add(repeated, NULL, NULL);
      if (!m) goto err;
      if (!PyUpb_Message_InitWKTOrMerge(m_def, m, e)) goto err;
    }
    Py_DECREF(e);
    Py_DECREF(m);
    m = NULL;
  }

err:
  Py_XDECREF(it);
  Py_XDECREF(e);
  Py_XDECREF(m);
  return !PyErr_Occurred();  // Check PyIter_Next() exit.
}

static bool PyUpb_Message_InitRepeatedAttribute(PyObject* _self, PyObject* name,
                                                PyObject* value) {
  PyUpb_Message* self = (void*)_self;
  const upb_FieldDef* field;
  if (!PyUpb_Message_LookupName(self, name, &field, NULL,
                                PyExc_AttributeError)) {
    return false;
  }
  bool ok = false;
  PyObject* repeated = PyUpb_Message_GetFieldValue(_self, field);
  PyObject* tmp = NULL;
  if (!repeated) goto err;
  if (upb_FieldDef_IsSubMessage(field)) {
    if (!PyUpb_Message_InitRepeatedMessageAttribute(_self, repeated, value,
                                                    field)) {
      goto err;
    }
  } else {
    tmp = PyUpb_RepeatedContainer_Extend(repeated, value);
    if (!tmp) goto err;
  }
  ok = true;

err:
  Py_XDECREF(repeated);
  Py_XDECREF(tmp);
  return ok;
}

static PyObject* PyUpb_Message_Clear(PyUpb_Message* self);

static bool PyUpb_Message_InitMessageAttribute(PyObject* _self, PyObject* name,
                                               const upb_FieldDef* field,
                                               PyObject* value) {
  PyObject* submsg = PyUpb_Message_GetAttr(_self, name);
  if (!submsg) return -1;
  bool ok;
  const upb_MessageDef* m_def = upb_FieldDef_MessageSubDef(field);
  if (PyDict_Check(value) &&
      (upb_MessageDef_WellKnownType(m_def) != kUpb_WellKnown_Struct)) {
    ok = PyUpb_Message_InitAttributes(submsg, NULL, value) >= 0;
  } else {
    ok = PyUpb_Message_InitWKTOrMerge(m_def, submsg, value);
  }
  Py_DECREF(submsg);
  return ok;
}

static bool PyUpb_Message_InitScalarAttribute(upb_Message* msg,
                                              const upb_FieldDef* f,
                                              PyObject* value,
                                              upb_Arena* arena) {
  upb_MessageValue msgval;
  if (!PyUpb_PyToUpb(value, f, &msgval, arena)) return false;
  if (!upb_Message_SetFieldByDef(msg, f, msgval, arena)) {
    PyErr_SetNone(PyExc_MemoryError);
    return false;
  }
  return true;
}

int PyUpb_Message_InitAttributes(PyObject* _self, PyObject* args,
                                 PyObject* kwargs) {
  if (args != NULL && PyTuple_Size(args) != 0) {
    PyErr_SetString(PyExc_TypeError, "No positional arguments allowed");
    return -1;
  }

  if (kwargs == NULL) return 0;

  PyUpb_Message* self = (void*)_self;
  Py_ssize_t pos = 0;
  PyObject* name;
  PyObject* value;
  if (!PyUpb_Message_AssureWritable(self)) return -1;
  upb_Message* msg = PyUpb_Message_GetMsg(self);
  upb_Arena* arena = PyUpb_Arena_Get(self->arena);

  while (PyDict_Next(kwargs, &pos, &name, &value)) {
    const upb_FieldDef* f;
    if (!PyUpb_Message_LookupName(self, name, &f, NULL, PyExc_ValueError)) {
      return -1;
    }

    if (value == Py_None) continue;  // Ignored.

    if (upb_FieldDef_IsMap(f)) {
      if (!PyUpb_Message_InitMapAttribute(_self, name, f, value)) return -1;
    } else if (upb_FieldDef_IsRepeated(f)) {
      if (!PyUpb_Message_InitRepeatedAttribute(_self, name, value)) return -1;
    } else if (upb_FieldDef_IsSubMessage(f)) {
      if (!PyUpb_Message_InitMessageAttribute(_self, name, f, value)) return -1;
    } else {
      if (!PyUpb_Message_InitScalarAttribute(msg, f, value, arena)) return -1;
    }
    if (PyErr_Occurred()) return -1;
  }

  if (PyErr_Occurred()) return -1;
  return 0;
}

static int PyUpb_Message_Init(PyObject* _self, PyObject* args,
                              PyObject* kwargs) {
  if (args != NULL && PyTuple_Size(args) != 0) {
    PyErr_SetString(PyExc_TypeError, "No positional arguments allowed");
    return -1;
  }

  return PyUpb_Message_InitAttributes(_self, args, kwargs);
}

static PyObject* PyUpb_Message_NewStub(PyObject* parent, const upb_FieldDef* f,
                                       PyObject* arena) {
  PyObject* cls = PyUpb_MessageMeta_GetSubClass(parent, f);
  if (!cls) return NULL;

  PyUpb_Message* msg = (void*)PyType_GenericAlloc((PyTypeObject*)cls, 0);
  if (msg == NULL) {
    Py_DECREF(cls);
    return NULL;
  }
  msg->def = (uintptr_t)f | 1;
  msg->arena = arena;
  msg->ptr.parent = (PyUpb_Message*)parent;
  msg->unset_subobj_map = NULL;
  msg->ext_dict = NULL;
  msg->version = 0;

  Py_DECREF(cls);
  Py_INCREF(parent);
  Py_INCREF(arena);
  return &msg->ob_base;
}

static bool PyUpb_Message_IsEmpty(const upb_Message* msg,
                                  const upb_MessageDef* m,
                                  const upb_DefPool* ext_pool) {
  if (!msg) return true;

  size_t iter = kUpb_Message_Begin;
  const upb_FieldDef* f;
  upb_MessageValue val;
  if (upb_Message_Next(msg, m, ext_pool, &f, &val, &iter)) return false;

  return !upb_Message_HasUnknown(msg);
}

static bool PyUpb_Message_IsEqual(PyUpb_Message* m1, PyObject* _m2) {
  PyUpb_Message* m2 = (void*)_m2;
  if (m1 == m2) return true;
  if (!PyObject_TypeCheck(_m2, m1->ob_base.ob_type)) {
    return false;
  }
  const upb_MessageDef* m1_msgdef = _PyUpb_Message_GetMsgdef(m1);
#ifndef NDEBUG
  const upb_MessageDef* m2_msgdef = _PyUpb_Message_GetMsgdef(m2);
  assert(m1_msgdef == m2_msgdef);
#endif
  const upb_Message* m1_msg = PyUpb_Message_GetIfReified((PyObject*)m1);
  const upb_Message* m2_msg = PyUpb_Message_GetIfReified(_m2);
  const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(m1_msgdef));

  const bool e1 = PyUpb_Message_IsEmpty(m1_msg, m1_msgdef, symtab);
  const bool e2 = PyUpb_Message_IsEmpty(m2_msg, m1_msgdef, symtab);
  if (e1 || e2) return e1 && e2;

  const int options = kUpb_CompareOption_IncludeUnknownFields;
  return upb_Message_IsEqualByDef(m1_msg, m2_msg, m1_msgdef, options);
}

static const upb_FieldDef* PyUpb_Message_InitAsMsg(PyUpb_Message* m,
                                                   upb_Arena* arena) {
  const upb_FieldDef* f = PyUpb_Message_GetFieldDef(m);
  const upb_MessageDef* m2 = upb_FieldDef_MessageSubDef(f);
  upb_Message* msg = upb_Message_New(upb_MessageDef_MiniTable(m2), arena);
  if (!msg) {
    PyErr_SetNone(PyExc_MemoryError);
    return NULL;
  }
  m->ptr.msg = msg;
  m->def = (uintptr_t)m2;
  PyObject* py_m = &m->ob_base;
  if (!PyUpb_Arena_CacheAdd(m->arena, m->ptr.msg, &py_m)) {
    return NULL;
  }
  return f;
}

static PyUpb_WeakMap* PyUpb_Message_GetOrCreateUnsetSubobjMap(
    PyUpb_Message* self) {
  return PyUpb_LazyPtr_LazyInit(&self->unset_subobj_map,
                                (PyUpb_PtrInitFunc)PyUpb_WeakMap_New,
                                (PyUpb_PtrFreeFunc)PyUpb_WeakMap_Free, NULL);
}

static bool PyUpb_Message_SetField(PyUpb_Message* parent, const upb_FieldDef* f,
                                   PyUpb_Message* child, upb_Arena* arena) {
  upb_MessageValue msgval = {.msg_val = PyUpb_Message_GetMsg(child)};
  if (!upb_Message_SetFieldByDef(PyUpb_Message_GetMsg(parent), f, msgval,
                                 arena)) {
    PyErr_SetNone(PyExc_MemoryError);
    Py_DECREF(child);
    return false;
  }
  PyUpb_WeakMap* map = PyUpb_LazyPtr_RawGet(&parent->unset_subobj_map);
  if (map) {
    PyUpb_WeakMap_Erase(map, f, (PyObject*)child);
  }
  // Releases a ref previously owned by child->ptr.parent of our child.
  Py_DECREF(child);
  return true;
}

/*
 * PyUpb_Message_AssureWritable()
 *
 * This implements the "expando" behavior of Python protos:
 *   foo = FooProto()
 *
 *   # The intermediate messages don't really exist, and won't be serialized.
 *   x = foo.bar.bar.bar.bar.bar.baz
 *
 *   # Now all the intermediate objects are created.
 *   foo.bar.bar.bar.bar.bar.baz = 5
 *
 * This function should be called before performing any mutation of a protobuf
 * object. It will check if the message is frozen, and if not, it will
 * reify the message (and any parent stubs) so that they have underlying
 * upb_Message objects.
 *
 * Returns true if writable. If the message is frozen, it sets a Python
 * TypeError and returns false. Note that we mandate that
 *
 * Post-condition:
 *   If true is returned, PyUpb_Message_IsStub(self) is false
 */
bool PyUpb_Message_AssureWritable(PyUpb_Message* self) {
  if (PyUpb_Message_IsFrozen((PyObject*)self)) {
    if (!PyUpb_CheckFrozen(true, "Message is immutable.")) {
      return false;
    }
  }

  if (!PyUpb_Message_IsStub(self)) return true;

  upb_Arena* arena = PyUpb_Arena_Get(self->arena);

  // This is a non-present message. We need to create a real upb_Message for
  // this object and every parent until we reach a present message.
  PyUpb_Message* child = self;
  PyUpb_Message* parent = self->ptr.parent;
  const upb_FieldDef* child_f = PyUpb_Message_InitAsMsg(child, arena);
  if (!child_f) return false;
  Py_INCREF(child);  // To avoid a special-case in PyUpb_Message_SetField().

  do {
    PyUpb_Message* next_parent = parent->ptr.parent;
    const upb_FieldDef* parent_f = NULL;
    if (PyUpb_Message_IsStub(parent)) {
      parent_f = PyUpb_Message_InitAsMsg(parent, arena);
      if (!parent_f) goto err2;
    }
    if (!PyUpb_Message_SetField(parent, child_f, child, arena)) goto err1;
    child = parent;
    child_f = parent_f;
    parent = next_parent;
  } while (child_f);

  // Releases ref previously owned by child->ptr.parent of our child.
  Py_DECREF(child);
  self->version++;
  return true;

err2:
  Py_DECREF(child);
err1:
  Py_DECREF(parent);
  return false;
}

static bool PyUpb_Message_SyncSubobjs(PyUpb_Message* self);

/*
 * PyUpb_Message_Reify()
 *
 * The message equivalent of PyUpb_*Container_Reify(), this transitions
 * the wrapper from the unset state (owning a reference on self->ptr.parent) to
 * the set state (having a non-owning pointer to self->ptr.msg).
 */
static bool PyUpb_Message_Reify(PyUpb_Message* self, const upb_FieldDef* f,
                                upb_Message* msg, PyUpb_WeakMapIter* iter) {
  assert(PyUpb_Message_IsStub(self));
  assert(f == PyUpb_Message_GetFieldDef(self));
  if (iter) {
    PyUpb_WeakMapIter_Delete(iter);
  }
  if (!msg) {
    const upb_MessageDef* msgdef = PyUpb_Message_GetMsgdef((PyObject*)self);
    const upb_MiniTable* layout = upb_MessageDef_MiniTable(msgdef);
    msg = upb_Message_New(layout, PyUpb_Arena_Get(self->arena));
    if (!msg) {
      PyErr_SetNone(PyExc_MemoryError);
      return false;
    }
  }
  if (!PyUpb_Arena_CacheUniqueAdd(self->arena, msg, &self->ob_base)) {
    return false;
  }
  PyObject* parent = &self->ptr.parent->ob_base;
  self->ptr.msg = msg;  // Overwrites self->ptr.parent
  self->def = (uintptr_t)upb_FieldDef_MessageSubDef(f);
  assert(!PyUpb_Message_IsStub(self));
  Py_DECREF(parent);
  return true;
}

static bool PyUpb_Message_SyncSubobj(PyUpb_Message* self, PyObject* obj,
                                     upb_Message* msg, const upb_FieldDef* f,
                                     PyUpb_WeakMapIter* iter) {
  if (upb_FieldDef_HasPresence(f) && !upb_Message_HasFieldByDef(msg, f)) {
    return true;
  }
  upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, f);
  if (upb_FieldDef_IsMap(f)) {
    if (!msgval.map_val) return true;
    if (!PyUpb_MapContainer_Reify(obj, (upb_Map*)msgval.map_val, iter)) {
      return false;
    }
  } else if (upb_FieldDef_IsRepeated(f)) {
    if (!msgval.array_val) return true;
    if (!PyUpb_RepeatedContainer_Reify(obj, (upb_Array*)msgval.array_val,
                                       iter)) {
      return false;
    }
  } else {
    PyUpb_Message* sub = (void*)obj;
    assert(self == sub->ptr.parent);
    if (!PyUpb_Message_Reify(sub, f, (upb_Message*)msgval.msg_val, iter)) {
      return false;
    }
  }
  return true;
}

/*
 * PyUpb_Message_SyncSubobjs()
 *
 * This operation must be invoked whenever the underlying upb_Message has been
 * mutated directly in C.  This will attach any newly-present field data
 * to previously returned stub wrapper objects.
 *
 * For example:
 *   foo = FooMessage()
 *   sub = foo.submsg  # Empty, unset sub-message
 *
 *   # SyncSubobjs() is required to connect our existing 'sub' wrapper to the
 *   # newly created foo.submsg data in C.
 *   foo.MergeFrom(FooMessage(submsg={}))
 *
 * This requires that all of the new sub-objects that have appeared are owned
 * by `self`'s arena.
 */
static bool PyUpb_Message_DoSyncSubobjs(upb_Message* msg,
                                        const upb_MessageDef* msgdef,
                                        PyObject* arena, PyUpb_Message* py_msg);

static bool PyUpb_Message_SyncPresentSubobjs(upb_Message* msg,
                                             const upb_MessageDef* msgdef,
                                             PyObject* arena) {
  const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(msgdef));
  size_t field_iter = kUpb_Message_Begin;
  const upb_FieldDef* f;
  upb_MessageValue val;

  while (upb_Message_Next(msg, msgdef, symtab, &f, &val, &field_iter)) {
    if (upb_FieldDef_IsMap(f)) {
      PyObject* sub = PyUpb_Arena_CacheGet(arena, val.map_val);
      if (sub) {
        PyUpb_MapContainer_Invalidate(sub);
        Py_DECREF(sub);
      }
    } else if (upb_FieldDef_IsSubMessage(f) && !upb_FieldDef_IsRepeated(f)) {
      if (!val.msg_val) continue;
      PyObject* sub = PyUpb_Arena_CacheGet(arena, val.msg_val);
      bool ok = PyUpb_Message_DoSyncSubobjs((upb_Message*)val.msg_val,
                                            upb_FieldDef_MessageSubDef(f),
                                            arena, (PyUpb_Message*)sub);
      Py_XDECREF(sub);
      if (!ok) return false;
    }
  }

  return true;
}

static bool PyUpb_Message_SyncStubSubobjs(PyUpb_Message* self,
                                          const upb_MessageDef* msgdef,
                                          PyObject* arena) {
  // `self` can be NULL when a present C submessage has no live Python wrapper
  // in `arena->obj_cache` (because the user dropped their reference to the
  // intermediate submessage wrapper), while a deeper descendant still has a
  // live Python wrapper or unpromoted stub.
  if (!self) return true;

  PyUpb_WeakMap* subobj_map = PyUpb_LazyPtr_RawGet(&self->unset_subobj_map);
  if (!subobj_map) return true;

  upb_Message* msg = PyUpb_Message_GetMsg(self);
  const void* key;
  // The last ref to this message could disappear during iteration.
  // When we call PyUpb_*Container_Reify() below, the container will drop
  // its ref on `self`.  If that was the last ref on self, the object will
  // be deleted, and `subobj_map` along with it.  We need it to live until we
  // are done iterating.
  Py_INCREF(&self->ob_base);

  bool ok = true;
  PyObject* obj = NULL;
  PyUpb_WeakMapIter iter;
  if (!PyUpb_WeakMapIter_Begin(&iter, subobj_map)) {
    Py_DECREF(&self->ob_base);
    return false;
  }
  while (PyUpb_WeakMapIter_Next(&iter, &key, &obj)) {
    if (!PyUpb_Message_SyncSubobj(self, obj, msg, key, &iter)) {
      ok = false;
      break;
    }
  }
  PyUpb_WeakMapIter_End(&iter);

  Py_DECREF(&self->ob_base);
  return ok;
}

static bool PyUpb_Message_DoSyncSubobjs(upb_Message* msg,
                                        const upb_MessageDef* msgdef,
                                        PyObject* arena,
                                        PyUpb_Message* py_msg) {
  return PyUpb_Message_SyncStubSubobjs(py_msg, msgdef, arena) &&
         PyUpb_Message_SyncPresentSubobjs(msg, msgdef, arena);
}

static bool PyUpb_Message_SyncSubobjs(PyUpb_Message* self) {
  return PyUpb_Message_DoSyncSubobjs(PyUpb_Message_GetMsg(self),
                                     _PyUpb_Message_GetMsgdef(self),
                                     self->arena, self);
}

static PyObject* PyUpb_Message_ToString(PyUpb_Message* self) {
  if (PyUpb_Message_IsStub(self)) {
    return PyUnicode_FromStringAndSize(NULL, 0);
  }
  upb_Message* msg = PyUpb_Message_GetMsg(self);
  const upb_MessageDef* msgdef = _PyUpb_Message_GetMsgdef(self);
  const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(msgdef));
  char buf[1024];
  int options = UPB_TXTENC_SKIPUNKNOWN;
  size_t size = upb_TextEncode(msg, msgdef, symtab, options, buf, sizeof(buf));
  if (size < sizeof(buf)) {
    return PyUnicode_FromStringAndSize(buf, size);
  } else {
    char* buf2 = malloc(size + 1);
    size_t size2 = upb_TextEncode(msg, msgdef, symtab, options, buf2, size + 1);
    assert(size == size2);
    PyObject* ret = PyUnicode_FromStringAndSize(buf2, size2);
    free(buf2);
    return ret;
  }
}

static PyObject* PyUpb_Message_RichCompare(PyObject* _self, PyObject* other,
                                           int opid) {
  PyUpb_Message* self = (void*)_self;
  if (opid != Py_EQ && opid != Py_NE) {
    Py_INCREF(Py_NotImplemented);
    return Py_NotImplemented;
  }
  const upb_MessageDef* msgdef = _PyUpb_Message_GetMsgdef(self);
  upb_WellKnown wkt = upb_MessageDef_WellKnownType(msgdef);
  if ((wkt == kUpb_WellKnown_ListValue && PyList_Check(other)) ||
      (wkt == kUpb_WellKnown_Struct && PyDict_Check(other))) {
    return PyObject_CallMethod(_self, "_internal_compare", "O", other);
  }

  if (!PyObject_TypeCheck(other, Py_TYPE(self))) {
    Py_INCREF(Py_NotImplemented);
    return Py_NotImplemented;
  }
  bool ret = PyUpb_Message_IsEqual(self, other);
  if (opid == Py_NE) ret = !ret;
  return PyBool_FromLong(ret);
}

void PyUpb_Message_CacheDelete(PyObject* _self, const upb_FieldDef* f,
                               PyObject* subobj) {
  PyUpb_Message* self = (void*)_self;
  PyUpb_WeakMap* map = PyUpb_LazyPtr_RawGet(&self->unset_subobj_map);
  if (map && f) {
    PyUpb_WeakMap_EraseIfEqual(map, f, subobj);
  }
}

bool PyUpb_Message_SetConcreteSubobj(PyObject* _self, const upb_FieldDef* f,
                                     upb_MessageValue subobj,
                                     PyObject* py_subobj) {
  PyUpb_Message* self = (void*)_self;
  if (!PyUpb_Message_AssureWritable(self)) return false;
  PyUpb_Message_CacheDelete(_self, f, py_subobj);
  if (!upb_Message_SetFieldByDef(self->ptr.msg, f, subobj,
                                 PyUpb_Arena_Get(self->arena))) {
    PyErr_SetNone(PyExc_MemoryError);
    return false;
  }
  return true;
}

static void PyUpb_Message_Dealloc(PyObject* _self) {
  PyUpb_Message* self = (void*)_self;

  if (PyUpb_Message_IsStub(self)) {
    PyUpb_Message_CacheDelete((PyObject*)self->ptr.parent,
                              PyUpb_Message_GetFieldDef(self), _self);
    Py_DECREF(self->ptr.parent);
  } else if (self->ptr.msg) {
    PyUpb_Arena_CacheEraseIfEqual(self->arena, self->ptr.msg, _self);
  }

  PyUpb_WeakMap* map = PyUpb_LazyPtr_RawGet(&self->unset_subobj_map);
  if (map) {
    PyUpb_WeakMap_Free(map);
  }

  Py_XDECREF(self->arena);
  PyUpb_Dealloc(self);
}

PyObject* PyUpb_Message_Get(PyObject* pool, upb_Message* u_msg,
                            const upb_MessageDef* m, PyObject* arena) {
  PyObject* ret = PyUpb_Arena_CacheGet(arena, u_msg);
  if (ret) return ret;

  PyObject* cls = PyUpb_Descriptor_GetClass(pool, m);
  if (!cls) return NULL;
  // It is not safe to use PyObject_{,GC}_New() due to:
  //    https://bugs.python.org/issue35810
  PyUpb_Message* py_msg = (void*)PyType_GenericAlloc((PyTypeObject*)cls, 0);
  if (!py_msg) {
    Py_DECREF(cls);
    return NULL;
  }
  py_msg->arena = arena;
  py_msg->def = (uintptr_t)m;
  py_msg->ptr.msg = u_msg;
  py_msg->unset_subobj_map = NULL;
  py_msg->ext_dict = NULL;
  py_msg->version = 0;
  ret = &py_msg->ob_base;
  Py_DECREF(cls);
  Py_INCREF(arena);
  if (!PyUpb_Arena_CacheAdd(arena, u_msg, &ret)) {
    Py_DECREF(ret);
    return NULL;
  }
  return ret;
}

/* PyUpb_Message_GetStub()
 *
 * Non-present messages return "stub" objects that point to their parent, but
 * will materialize into real upb objects if they are mutated.
 *
 *    msg = TestMessage()
 *    msg.submessage                # (A) Creates a stub
 *    msg.repeated_foo              # (B) Creates a stub
 *    msg.submessage.repeated_bar   # (C) Creates a stub
 *
 * In case (B) we have some freedom: we could either create a stub, or create
 * a reified object with underlying data. We choose to create a stub in all
 * cases to simplify the model.
 */
PyObject* PyUpb_Message_GetStub(PyUpb_Message* self,
                                const upb_FieldDef* field) {
  assert(PyUpb_Message_Verify((PyObject*)self));
  PyObject* _self = (void*)self;
  PyUpb_WeakMap* unset_map = PyUpb_Message_GetOrCreateUnsetSubobjMap(self);
  if (!unset_map) return NULL;
  PyObject* subobj = PyUpb_WeakMap_Get(unset_map, field);

  if (subobj) return subobj;

  if (upb_FieldDef_IsMap(field)) {
    subobj = PyUpb_MapContainer_NewStub(_self, field, self->arena);
  } else if (upb_FieldDef_IsRepeated(field)) {
    subobj = PyUpb_RepeatedContainer_NewStub(_self, field, self->arena);
  } else {
    subobj = PyUpb_Message_NewStub(&self->ob_base, field, self->arena);
  }
  if (!subobj) return NULL;
  if (!PyUpb_WeakMap_Add(unset_map, field, &subobj)) {
    Py_DECREF(subobj);
    return NULL;
  }

  return subobj;
}

PyObject* PyUpb_Message_GetPresentWrapper(PyUpb_Message* self,
                                          const upb_FieldDef* field) {
  assert(!PyUpb_Message_IsStub(self));
  upb_MessageValue val;

  if (PyUpb_Message_IsFrozen((PyObject*)self)) {
    val = upb_Message_GetFieldByDef(self->ptr.msg, field);
  } else {
    upb_MutableMessageValue mutval =
        upb_Message_Mutable(self->ptr.msg, field, PyUpb_Arena_Get(self->arena));
    val.array_val = mutval.array;
  }

  if (upb_FieldDef_IsMap(field)) {
    if (!val.map_val) {
      PyErr_SetNone(PyExc_MemoryError);
      return NULL;
    }
    return PyUpb_MapContainer_GetOrCreateWrapper((upb_Map*)val.map_val, field,
                                                 self->arena);
  } else {
    if (!val.array_val) {
      PyErr_SetNone(PyExc_MemoryError);
      return NULL;
    }
    return PyUpb_RepeatedContainer_GetOrCreateWrapper((upb_Array*)val.array_val,
                                                      field, self->arena);
  }
}

PyObject* PyUpb_Message_GetScalarValue(PyUpb_Message* self,
                                       const upb_FieldDef* field) {
  upb_MessageValue val;
  if (PyUpb_Message_IsStub(self)) {
    // Unset message always returns default values.
    val = upb_FieldDef_Default(field);
  } else {
    val = upb_Message_GetFieldByDef(self->ptr.msg, field);
  }
  return PyUpb_UpbToPy(val, field, self->arena);
}

/*
 * PyUpb_Message_GetFieldValue()
 *
 * Implements the equivalent of getattr(msg, field), once `field` has
 * already been resolved to a `upb_FieldDef*`.
 *
 * This may involve constructing a wrapper object for the given field, or
 * returning one that was previously constructed.  If the field is not actually
 * set, the wrapper object will be an "unset" object that is not actually
 * connected to any C data.
 */
PyObject* PyUpb_Message_GetFieldValue(PyObject* _self,
                                      const upb_FieldDef* field) {
  PyUpb_Message* self = (void*)_self;
  assert(upb_FieldDef_ContainingType(field) == PyUpb_Message_GetMsgdef(_self));
  bool submsg = upb_FieldDef_IsSubMessage(field);
  bool seq = upb_FieldDef_IsRepeated(field);

  if (PyUpb_Message_IsStub(self) && (submsg || seq)) {
    return PyUpb_Message_GetStub(self, field);
  }

  if (seq) {
    upb_MessageValue val = upb_Message_GetFieldByDef(self->ptr.msg, field);
    bool is_unset = upb_FieldDef_IsMap(field) ? !val.map_val : !val.array_val;
    if (is_unset) return PyUpb_Message_GetStub(self, field);
    if (upb_FieldDef_IsMap(field)) {
      return PyUpb_MapContainer_GetOrCreateWrapper((upb_Map*)val.map_val, field,
                                                   self->arena);
    } else {
      return PyUpb_RepeatedContainer_GetOrCreateWrapper(
          (upb_Array*)val.array_val, field, self->arena);
    }
  }

  if (submsg && !upb_Message_HasFieldByDef(self->ptr.msg, field)) {
    return PyUpb_Message_GetStub(self, field);
  }

  return PyUpb_Message_GetScalarValue(self, field);
}

int PyUpb_Message_SetFieldValue(PyObject* _self, const upb_FieldDef* field,
                                PyObject* value, PyObject* exc) {
  PyUpb_Message* self = (void*)_self;
  assert(value);

  if (upb_FieldDef_IsRepeated(field)) {
    PyErr_Format(exc,
                 "Assignment not allowed to map, or repeated "
                 "field \"%s\" in protocol message object.",
                 upb_FieldDef_Name(field));
    return -1;
  }

  if (!PyUpb_Message_AssureWritable(self)) return -1;

  if (upb_FieldDef_IsSubMessage(field)) {
    const upb_MessageDef* msgdef = upb_FieldDef_MessageSubDef(field);
    if (upb_MessageDef_WellKnownType(msgdef) != kUpb_WellKnown_Unspecified) {
      PyObject* sub_message = PyUpb_Message_GetFieldValue(_self, field);
      if (!sub_message) return -1;
      if (PyObject_HasAttrString(sub_message, "_internal_assign")) {
        PyObject* ok =
            PyObject_CallMethod(sub_message, "_internal_assign", "O", value);
        Py_DECREF(sub_message);
        if (!ok) return -1;
        Py_DECREF(ok);
        return 0;
      }
      Py_DECREF(sub_message);
    }
    PyErr_Format(exc,
                 "Assignment not allowed to message "
                 "field \"%s\" in protocol message object.",
                 upb_FieldDef_Name(field));
    return -1;
  }

  upb_MessageValue val;
  upb_Arena* arena = PyUpb_Arena_Get(self->arena);
  if (!PyUpb_PyToUpb(value, field, &val, arena)) {
    return -1;
  }

  if (!upb_Message_SetFieldByDef(self->ptr.msg, field, val, arena)) {
    PyErr_SetNone(PyExc_MemoryError);
    return -1;
  }
  return 0;
}

int PyUpb_Message_GetVersion(PyObject* _self) {
  PyUpb_Message* self = (void*)_self;
  return self->version;
}

bool PyUpb_Message_IsFrozen(PyObject* _self) {
  PyUpb_Message* self = (void*)_self;
  while (PyUpb_Message_IsStub(self)) {
    self = self->ptr.parent;
  }
  bool is_frozen =
      upb_Message_IsFrozen(self->ptr.msg) || PyUpb_Arena_IsFrozen(self->arena);
  // Invariant: Since we only store the parent *message* (and not any parent
  // repeated field or map) in a stub's `ptr.parent`, we wouldn't correctly
  // handle the case where a parent message is unfrozen but a containing
  // repeated field or map is frozen. Therefore, we enforce the invariant that
  // every unfrozen message must also have unfrozen repeated fields and maps.
#ifndef NDEBUG
  if (!is_frozen) {
    const upb_MessageDef* msgdef = _PyUpb_Message_GetMsgdef(self);
    int n = upb_MessageDef_FieldCount(msgdef);
    for (int i = 0; i < n; i++) {
      const upb_FieldDef* f = upb_MessageDef_Field(msgdef, i);
      if (upb_FieldDef_IsMap(f)) {
        upb_MessageValue val = upb_Message_GetFieldByDef(self->ptr.msg, f);
        assert(!val.map_val || !upb_Map_IsFrozen(val.map_val));
      } else if (upb_FieldDef_IsRepeated(f)) {
        upb_MessageValue val = upb_Message_GetFieldByDef(self->ptr.msg, f);
        assert(!val.array_val || !upb_Array_IsFrozen(val.array_val));
      }
    }
  }
#endif
  return is_frozen;
}

/*
 * PyUpb_Message_GetAttr()
 *
 * Implements:
 *   foo = msg.foo
 *
 * Attribute lookup must find both message fields and base class methods like
 * msg.SerializeToString().
 */
__attribute__((flatten)) static PyObject* PyUpb_Message_GetAttr(
    PyObject* _self, PyObject* attr) {
  PyUpb_Message* self = (void*)_self;

  // Lookup field by name.
  const upb_FieldDef* field;
  if (PyUpb_Message_LookupName(self, attr, &field, NULL, NULL)) {
    return PyUpb_Message_GetFieldValue(_self, field);
  }

  // Check base class attributes.
  PyObject* ret = PyObject_GenericGetAttr(_self, attr);
  if (ret) return ret;

  // Swallow AttributeError if it occurred and try again on the metaclass
  // to pick up class attributes.  But we have to special-case "Extensions"
  // which affirmatively returns AttributeError when a message is not
  // extendable.
  const char* name;
  if (PyErr_ExceptionMatches(PyExc_AttributeError) &&
      (name = PyUpb_GetStrData(attr)) && strcmp(name, "Extensions") != 0) {
    PyErr_Clear();
    return PyUpb_MessageMeta_GetAttr((PyObject*)Py_TYPE(_self), attr);
  }

  return NULL;
}

/*
 * PyUpb_Message_SetAttr()
 *
 * Implements:
 *   msg.foo = foo
 */
static int PyUpb_Message_SetAttr(PyObject* _self, PyObject* attr,
                                 PyObject* value) {
  PyUpb_Message* self = (void*)_self;

  if (value == NULL) {
    PyErr_SetString(PyExc_AttributeError, "Cannot delete field attribute");
    return -1;
  }

  const upb_FieldDef* field;
  if (!PyUpb_Message_LookupName(self, attr, &field, NULL,
                                PyExc_AttributeError)) {
    return -1;
  }

  return PyUpb_Message_SetFieldValue(_self, field, value, PyExc_AttributeError);
}

static PyObject* PyUpb_Message_HasField(PyObject* _self, PyObject* arg) {
  PyUpb_Message* self = (void*)_self;
  const upb_FieldDef* field;
  const upb_OneofDef* oneof;

  if (!PyUpb_Message_LookupName(self, arg, &field, &oneof, PyExc_ValueError)) {
    return NULL;
  }

  if (field && !upb_FieldDef_HasPresence(field)) {
    PyErr_Format(PyExc_ValueError, "Field %s does not have presence.",
                 upb_FieldDef_FullName(field));
    return NULL;
  }

  if (PyUpb_Message_IsStub(self)) Py_RETURN_FALSE;

  return PyBool_FromLong(
      field ? upb_Message_HasFieldByDef(self->ptr.msg, field)
            : upb_Message_WhichOneofByDef(self->ptr.msg, oneof) != NULL);
}

static PyObject* PyUpb_Message_Contains(PyObject* _self, PyObject* arg) {
  const upb_MessageDef* msgdef = PyUpb_Message_GetMsgdef(_self);
  switch (upb_MessageDef_WellKnownType(msgdef)) {
    case kUpb_WellKnown_Struct: {
      // For WKT Struct, check if the key is in the fields.
      PyUpb_Message* self = (void*)_self;
      if (PyUpb_Message_IsStub(self)) Py_RETURN_FALSE;
      upb_Message* msg = PyUpb_Message_GetMsg(self);
      const upb_FieldDef* f = upb_MessageDef_FindFieldByName(msgdef, "fields");
      const upb_Map* map = upb_Message_GetFieldByDef(msg, f).map_val;
      if (!map || upb_Map_Size(map) == 0) Py_RETURN_FALSE;
      const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
      const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
      upb_MessageValue u_key;
      if (!PyUpb_PyToUpb(arg, key_f, &u_key, NULL)) return NULL;
      return PyBool_FromLong(upb_Map_Get(map, u_key, NULL));
    }
    case kUpb_WellKnown_ListValue: {
      // For WKT ListValue, check if the key is in the items.
      PyUpb_Message* self = (void*)_self;
      if (PyUpb_Message_IsStub(self)) Py_RETURN_FALSE;
      PyObject* items = PyObject_CallMethod(_self, "items", NULL);
      if (!items) return NULL;
      int ret = PySequence_Contains(items, arg);
      Py_DECREF(items);
      if (ret < 0) return NULL;
      return PyBool_FromLong(ret);
    }
    default:
      // For other messages, check with HasField.
      return PyUpb_Message_HasField(_self, arg);
  }
}

static PyObject* PyUpb_Message_FindInitializationErrors(PyObject* _self,
                                                        PyObject* arg);

static PyObject* PyUpb_Message_IsInitializedAppendErrors(PyObject* _self,
                                                         PyObject* errors) {
  PyObject* list = PyUpb_Message_FindInitializationErrors(_self, NULL);
  if (!list) return NULL;
  bool ok = PyList_Size(list) == 0;
  PyObject* ret = NULL;
  PyObject* extend_result = NULL;
  if (!ok) {
    extend_result = PyObject_CallMethod(errors, "extend", "O", list);
    if (!extend_result) goto done;
  }
  ret = PyBool_FromLong(ok);

done:
  Py_XDECREF(list);
  Py_XDECREF(extend_result);
  return ret;
}

static PyObject* PyUpb_Message_IsInitialized(PyObject* _self, PyObject* args) {
  PyObject* errors = NULL;
  if (!PyArg_ParseTuple(args, "|O", &errors)) {
    return NULL;
  }
  if (errors) {
    // We need to collect a list of unset required fields and append it to
    // `errors`.
    return PyUpb_Message_IsInitializedAppendErrors(_self, errors);
  } else {
    // We just need to return a boolean "true" or "false" for whether all
    // required fields are set.
    upb_Message* msg = PyUpb_Message_GetIfReified(_self);
    const upb_MessageDef* m = PyUpb_Message_GetMsgdef(_self);
    const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(m));
    upb_Status status;
    upb_Status_Clear(&status);
    bool initialized =
        !upb_util_HasUnsetRequired(msg, m, symtab, NULL, &status);
    if (!upb_Status_IsOk(&status)) {
      PyErr_SetNone(PyExc_MemoryError);
      return NULL;
    }
    return PyBool_FromLong(initialized);
  }
}

static PyObject* PyUpb_Message_ListFieldsItemKey(PyObject* self,
                                                 PyObject* val) {
  assert(PyTuple_Check(val));
  PyObject* field = PyTuple_GetItem(val, 0);
  const upb_FieldDef* f = PyUpb_FieldDescriptor_GetDef(field);
  return PyLong_FromLong(upb_FieldDef_Number(f));
}

static PyObject* PyUpb_Message_CheckCalledFromGeneratedFile(
    PyObject* unused, PyObject* unused_arg) {
  PyErr_SetString(
      PyExc_TypeError,
      "Descriptors cannot be created directly.\n"
      "If this call came from a _pb2.py file, your generated code is out of "
      "date and must be regenerated with protoc >= 3.19.0.\n"
      "If you cannot immediately regenerate your protos, some other possible "
      "workarounds are:\n"
      " 1. Downgrade the protobuf package to 3.20.x or lower.\n"
      " 2. Set PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python (but this will "
      "use pure-Python parsing and will be much slower).\n"
      "\n"
      "More information: "
      "https://developers.google.com/protocol-buffers/docs/news/"
      "2022-05-06#python-updates");
  return NULL;
}

static bool PyUpb_Message_SortFieldList(PyObject* list) {
  PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
  bool ok = false;
  PyObject* args = PyTuple_New(0);
  PyObject* kwargs = PyDict_New();
  PyObject* method = PyObject_GetAttrString(list, "sort");
  PyObject* call_result = NULL;
  if (!args || !kwargs || !method) goto err;
  if (PyDict_SetItemString(kwargs, "key", state->listfields_item_key) < 0) {
    goto err;
  }
  call_result = PyObject_Call(method, args, kwargs);
  if (!call_result) goto err;
  ok = true;

err:
  Py_XDECREF(method);
  Py_XDECREF(args);
  Py_XDECREF(kwargs);
  Py_XDECREF(call_result);
  return ok;
}

static PyObject* PyUpb_Message_ListFields(PyObject* _self, PyObject* arg) {
  PyObject* list = PyList_New(0);
  upb_Message* msg = PyUpb_Message_GetIfReified(_self);
  if (!msg) return list;

  size_t iter1 = kUpb_Message_Begin;
  const upb_MessageDef* m = PyUpb_Message_GetMsgdef(_self);
  const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(m));
  const upb_FieldDef* f;
  PyObject* field_desc = NULL;
  PyObject* py_val = NULL;
  PyObject* tuple = NULL;
  upb_MessageValue val;
  uint32_t last_field = 0;
  bool in_order = true;
  while (upb_Message_Next(msg, m, symtab, &f, &val, &iter1)) {
    const uint32_t field_number = upb_FieldDef_Number(f);
    if (field_number < last_field) in_order = false;
    last_field = field_number;
    PyObject* desc = PyUpb_Message_GetDescriptor(_self);
    PyObject* pool = PyUpb_AnyDescriptor_GetPool(desc);
    field_desc = PyUpb_FieldDescriptor_Get(pool, f);
    py_val = PyUpb_Message_GetFieldValue(_self, f);
    if (!field_desc || !py_val) goto err;
    tuple = Py_BuildValue("(NN)", field_desc, py_val);
    field_desc = NULL;
    py_val = NULL;
    if (!tuple) goto err;
    if (PyList_Append(list, tuple)) goto err;
    Py_DECREF(tuple);
    tuple = NULL;
  }

  // Users rely on fields being returned in field number order.
  if (!in_order && !PyUpb_Message_SortFieldList(list)) goto err;

  return list;

err:
  Py_XDECREF(field_desc);
  Py_XDECREF(py_val);
  Py_XDECREF(tuple);
  Py_DECREF(list);
  return NULL;
}

PyObject* PyUpb_Message_MergeFrom(PyObject* self, PyObject* arg) {
  if (self->ob_type != arg->ob_type) {
    PyErr_Format(PyExc_TypeError,
                 "Parameter to MergeFrom() must be instance of same class: "
                 "expected %S got %S.",
                 Py_TYPE(self), Py_TYPE(arg));
    return NULL;
  }
  // OPT: exit if src is empty.
  PyObject* subargs = PyTuple_New(0);
  PyObject* serialized =
      PyUpb_Message_SerializePartialToString(arg, subargs, NULL);
  Py_DECREF(subargs);
  if (!serialized) return NULL;
  PyObject* ret = PyUpb_Message_MergeFromString(self, serialized);
  Py_DECREF(serialized);
  if (!ret) return NULL;
  Py_DECREF(ret);
  Py_RETURN_NONE;
}

static PyObject* PyUpb_Message_CopyFrom(PyObject* _self, PyObject* arg) {
  PyUpb_Message* self = (void*)_self;
  if (_self->ob_type != arg->ob_type) {
    PyErr_Format(PyExc_TypeError,
                 "Parameter to CopyFrom() must be instance of same class: "
                 "expected %S got %S.",
                 Py_TYPE(_self), Py_TYPE(arg));
    return NULL;
  }
  if (_self == arg) {
    Py_RETURN_NONE;
  }
  PyUpb_Message* other = (void*)arg;
  if (!PyUpb_Message_AssureWritable(self)) return NULL;

  const upb_Message* other_msg = PyUpb_Message_GetIfReified((PyObject*)other);
  if (other_msg) {
    if (!upb_Message_DeepCopy(
            self->ptr.msg, other_msg,
            upb_MessageDef_MiniTable((const upb_MessageDef*)other->def),
            PyUpb_Arena_Get(self->arena))) {
      PyErr_SetNone(PyExc_MemoryError);
      return NULL;
    }
  } else {
    PyObject* tmp = PyUpb_Message_Clear(self);
    if (!tmp) return NULL;
    Py_DECREF(tmp);
  }
  if (!PyUpb_Message_SyncSubobjs(self)) return NULL;

  Py_RETURN_NONE;
}

static PyObject* PyUpb_Message_SetInParent(PyObject* _self, PyObject* arg) {
  PyUpb_Message* self = (void*)_self;
  if (!PyUpb_Message_AssureWritable(self)) return NULL;
  Py_RETURN_NONE;
}

static PyObject* PyUpb_Message_UnknownFields(PyObject* _self, PyObject* arg) {
  // TODO: re-enable when unknown fields are added.
  // return PyUpb_UnknownFields_New(_self);
  PyErr_SetString(PyExc_NotImplementedError, "unknown field accessor");
  return NULL;
}

static bool PyUpb_AsReadBuffer(PyObject* arg, const char** buf,
                               Py_ssize_t* size) {
#if PY_VERSION_HEX >= 0x030B0000
  // PyObject_AsReadBuffer is deprecated and may be removed in later versions
  // of Python.
  Py_buffer buffer;
  int err = PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE);
  if (err == 0) {
    *buf = buffer.buf;
    *size = buffer.len;
    // Safe as `arg` is a memoryview and does not release the underlying buffer.
    PyBuffer_Release(&buffer);
  }
#else
  UPB_IGNORE_DEPRECATION_START
  int err = PyObject_AsReadBuffer(arg, (const void**)buf, size);
  UPB_IGNORE_DEPRECATION_STOP
#endif
  if (err != 0) {
    PyErr_Clear();
    return false;
  }
  return true;
}

static bool PyUpb_GetContiguousBuffer(PyObject* arg, const char** buf,
                                      Py_ssize_t* size,
                                      PyObject** mv_contiguous) {
  if (PyMemoryView_Check(arg)) {
    bool ok = PyUpb_AsReadBuffer(arg, buf, size);
    if (!ok) {
      // PyBUF_READ is defined as 0x100 but not available in limited API.
      *mv_contiguous = PyMemoryView_GetContiguous(arg, 0x100, 'C');
      if (!*mv_contiguous) return false;
      ok = PyUpb_AsReadBuffer(*mv_contiguous, buf, size);
    }
    assert(ok);
    return true;
  }
  if (PyByteArray_Check(arg)) {
    *buf = PyByteArray_AsString(arg);
    *size = PyByteArray_Size(arg);
    return true;
  }
  return PyBytes_AsStringAndSize(arg, (char**)buf, size) >= 0;
}

PyObject* PyUpb_Message_MergeFromString(PyObject* _self, PyObject* arg) {
  PyUpb_Message* self = (void*)_self;
  if (!PyUpb_Message_AssureWritable(self)) return NULL;
  const char* buf;
  Py_ssize_t size;
  PyObject* mv_contiguous = NULL;
  if (!PyUpb_GetContiguousBuffer(arg, &buf, &size, &mv_contiguous)) {
    return NULL;
  }
  const upb_MessageDef* msgdef = _PyUpb_Message_GetMsgdef(self);
  const upb_FileDef* file = upb_MessageDef_File(msgdef);
  const upb_ExtensionRegistry* extreg =
      upb_DefPool_ExtensionRegistry(upb_FileDef_Pool(file));
  const upb_MiniTable* layout = upb_MessageDef_MiniTable(msgdef);
  upb_Arena* arena = PyUpb_Arena_Get(self->arena);
  PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
  int options =
      upb_DecodeOptions_MaxDepth(state->allow_oversize_protos ? UINT16_MAX : 0);
  upb_DecodeStatus status =
      upb_Decode(buf, size, self->ptr.msg, layout, extreg, options, arena);
  Py_XDECREF(mv_contiguous);
  if (!PyUpb_Message_SyncSubobjs(self)) return NULL;
  if (status != kUpb_DecodeStatus_Ok) {
    if (status == kUpb_DecodeStatus_OutOfMemory) {
      PyErr_SetNone(PyExc_MemoryError);
    } else {
      PyErr_Format(
          state->decode_error_class, "Error parsing message with type '%s': %s",
          upb_MessageDef_FullName(msgdef), upb_DecodeStatus_String(status));
    }
    return NULL;
  }
  return PyLong_FromSsize_t(size);
}

static PyObject* PyUpb_Message_ParseFromString(PyObject* self, PyObject* arg) {
  PyObject* tmp = PyUpb_Message_Clear((PyUpb_Message*)self);
  if (!tmp) return NULL;
  Py_DECREF(tmp);
  return PyUpb_Message_MergeFromString(self, arg);
}

static PyObject* PyUpb_Message_ByteSize(PyObject* self, PyObject* args) {
  // TODO: At the
  // moment upb does not have a "byte size" function, so we just serialize to
  // string and get the size of the string.
  PyObject* subargs = PyTuple_New(0);
  // SerializePartialToString because Message.ByteSize should not raise
  // EncodeError if required fields are not set, unlike SerializeToString.
  PyObject* serialized =
      PyUpb_Message_SerializePartialToString(self, subargs, NULL);
  Py_DECREF(subargs);
  if (!serialized) return NULL;
  size_t size = PyBytes_Size(serialized);
  Py_DECREF(serialized);
  return PyLong_FromSize_t(size);
}

static PyObject* PyUpb_Message_Clear(PyUpb_Message* self) {
  if (!PyUpb_Message_AssureWritable(self)) return NULL;
  const upb_MessageDef* msgdef = _PyUpb_Message_GetMsgdef(self);
  PyUpb_WeakMap* subobj_map = PyUpb_LazyPtr_RawGet(&self->unset_subobj_map);

  if (subobj_map) {
    upb_Message* msg = PyUpb_Message_GetMsg(self);
    (void)msg;  // Suppress unused warning when asserts are disabled.
    const void* key;
    PyObject* obj = NULL;
    PyUpb_WeakMapIter iter;

    if (!PyUpb_WeakMapIter_Begin(&iter, subobj_map)) {
      return NULL;
    }
    while (PyUpb_WeakMapIter_Next(&iter, &key, &obj)) {
      const upb_FieldDef* f = key;
      if (upb_FieldDef_IsMap(f)) {
        assert(upb_Message_GetFieldByDef(msg, f).map_val == NULL);
        if (!PyUpb_MapContainer_Reify(obj, NULL, &iter)) {
          PyUpb_WeakMapIter_End(&iter);
          return NULL;
        }
      } else if (upb_FieldDef_IsRepeated(f)) {
        assert(upb_Message_GetFieldByDef(msg, f).array_val == NULL);
        if (!PyUpb_RepeatedContainer_Reify(obj, NULL, &iter)) {
          PyUpb_WeakMapIter_End(&iter);
          return NULL;
        }
      } else {
        assert(!upb_Message_HasFieldByDef(msg, f));
        PyUpb_Message* sub = (void*)obj;
        assert(self == sub->ptr.parent);
        if (!PyUpb_Message_Reify(sub, f, NULL, &iter)) {
          PyUpb_WeakMapIter_End(&iter);
          return NULL;
        }
      }
    }
    PyUpb_WeakMapIter_End(&iter);
  }

  upb_Message_ClearByDef(self->ptr.msg, msgdef);
  Py_RETURN_NONE;
}

bool PyUpb_Message_DoClearField(PyObject* _self, const upb_FieldDef* f) {
  PyUpb_Message* self = (void*)_self;
  if (!PyUpb_Message_AssureWritable((PyUpb_Message*)self)) return false;

  // We must ensure that any stub object is reified so its parent no longer
  // points to us. Otherwise, if the user later mutates the stub, it will
  // re-attach itself to the parent message, which we just cleared.
  PyUpb_WeakMap* map = PyUpb_LazyPtr_RawGet(&self->unset_subobj_map);
  PyObject* sub = map ? PyUpb_WeakMap_Get(map, f) : NULL;
  // The goal is to ensure child is reified here, but that functionality is
  // encapsulated in the AssureWritable() calls for now. Therefore assuring the
  // child is writable is a side-effect we rely on here but could be reverted in
  // the future if needed.
  if (upb_FieldDef_IsMap(f)) {
    // For maps we additionally have to invalidate any iterators.  So we need
    // to get an object even if it's reified.
    if (!sub) {
      sub = PyUpb_Message_GetFieldValue(_self, f);
    }
    PyUpb_MapContainer_AssureWritable(sub);
    PyUpb_MapContainer_Invalidate(sub);
  } else if (upb_FieldDef_IsRepeated(f)) {
    if (sub) {
      PyUpb_RepeatedContainer_AssureWritable(sub);
    }
  } else if (upb_FieldDef_IsSubMessage(f)) {
    if (sub) {
      PyUpb_Message_AssureWritable((PyUpb_Message*)sub);
    }
  }

  Py_XDECREF(sub);
  upb_Message_ClearFieldByDef(self->ptr.msg, f);
  return true;
}

static PyObject* PyUpb_Message_ClearExtension(PyObject* _self, PyObject* arg) {
  PyUpb_Message* self = (void*)_self;
  if (!PyUpb_Message_AssureWritable(self)) return NULL;
  const upb_FieldDef* f = PyUpb_Message_GetExtensionDef(_self, arg);
  if (!f) return NULL;
  if (!PyUpb_Message_DoClearField(_self, f)) return NULL;
  Py_RETURN_NONE;
}

static PyObject* PyUpb_Message_ClearField(PyObject* _self, PyObject* arg) {
  PyUpb_Message* self = (void*)_self;

  // We always need AssureWritable() here (even for an unset message) to
  // preserve behavior like:
  //   msg = FooMessage()
  //   msg.foo.Clear()
  //   assert msg.HasField("foo")
  if (!PyUpb_Message_AssureWritable(self)) return NULL;

  const upb_FieldDef* f;
  const upb_OneofDef* o;
  if (!PyUpb_Message_LookupName(self, arg, &f, &o, PyExc_ValueError)) {
    return NULL;
  }

  if (o) f = upb_Message_WhichOneofByDef(self->ptr.msg, o);
  if (f) {
    if (!PyUpb_Message_DoClearField(_self, f)) return NULL;
  }
  Py_RETURN_NONE;
}

static PyObject* PyUpb_Message_DiscardUnknownFields(PyUpb_Message* self,
                                                    PyObject* arg) {
  if (!PyUpb_Message_AssureWritable(self)) return NULL;
  const upb_MessageDef* msgdef = _PyUpb_Message_GetMsgdef(self);
  const upb_DefPool* ext_pool = upb_FileDef_Pool(upb_MessageDef_File(msgdef));
  upb_Message_DiscardUnknown(self->ptr.msg, msgdef, ext_pool, 64);
  Py_RETURN_NONE;
}

static PyObject* PyUpb_Message_FindInitializationErrors(PyObject* _self,
                                                        PyObject* arg) {
  PyUpb_Message* self = (void*)_self;
  upb_Message* msg = PyUpb_Message_GetIfReified(_self);
  const upb_MessageDef* msgdef = _PyUpb_Message_GetMsgdef(self);
  const upb_DefPool* ext_pool = upb_FileDef_Pool(upb_MessageDef_File(msgdef));
  upb_FieldPathEntry* fields_base;
  upb_Status status;
  upb_Status_Clear(&status);
  bool has_unset_required =
      upb_util_HasUnsetRequired(msg, msgdef, ext_pool, &fields_base, &status);
  if (!upb_Status_IsOk(&status)) {
    PyErr_SetString(PyExc_MemoryError, upb_Status_ErrorMessage(&status));
    return NULL;
  }
  PyObject* ret = PyList_New(0);
  if (!ret) return NULL;

  if (!has_unset_required) {
    return ret;
  }
  upb_FieldPathEntry* fields = fields_base;
  char* buf = NULL;
  size_t size = 0;
  assert(fields->field);
  while (fields->field) {
    upb_FieldPathEntry* field = fields;
    size_t need = upb_FieldPath_ToText(&fields, buf, size);
    if (need >= size) {
      fields = field;
      size = size ? size * 2 : 16;
      while (size <= need) size *= 2;
      buf = realloc(buf, size);
      if (!buf) goto realloc_err;
      need = upb_FieldPath_ToText(&fields, buf, size);
      assert(size > need);
    }
    PyObject* str = PyUnicode_FromString(buf);
    if (!str) goto err;
    int appended = PyList_Append(ret, str);
    Py_DECREF(str);
    if (appended < 0) goto err;
  }
done:
  free(buf);
  upb_gfree(fields_base);
  return ret;
realloc_err:
  PyErr_SetNone(PyExc_MemoryError);
err:
  Py_CLEAR(ret);
  goto done;
}

static PyObject* PyUpb_Message_FromString(PyObject* cls, PyObject* serialized) {
  PyObject* ret = NULL;
  PyObject* length = NULL;

  ret = PyObject_CallObject(cls, NULL);
  if (ret == NULL) goto err;
  length = PyUpb_Message_MergeFromString(ret, serialized);
  if (length == NULL) goto err;

done:
  Py_XDECREF(length);
  return ret;

err:
  Py_XDECREF(ret);
  ret = NULL;
  goto done;
}

const upb_FieldDef* PyUpb_Message_GetExtensionDef(PyObject* _self,
                                                  PyObject* key) {
  const upb_FieldDef* f = PyUpb_FieldDescriptor_GetDef(key);
  if (!f) {
    PyErr_Clear();
    PyErr_Format(PyExc_KeyError, "Object %R is not a field descriptor\n", key);
    return NULL;
  }
  if (!upb_FieldDef_IsExtension(f)) {
    PyErr_Format(PyExc_KeyError, "Field %s is not an extension\n",
                 upb_FieldDef_FullName(f));
    return NULL;
  }
  const upb_MessageDef* msgdef = PyUpb_Message_GetMsgdef(_self);
  if (upb_FieldDef_ContainingType(f) != msgdef) {
    PyErr_Format(PyExc_KeyError, "Extension doesn't match (%s vs %s)",
                 upb_MessageDef_FullName(msgdef), upb_FieldDef_FullName(f));
    return NULL;
  }
  return f;
}

static PyObject* PyUpb_Message_HasExtension(PyObject* _self,
                                            PyObject* ext_desc) {
  upb_Message* msg = PyUpb_Message_GetIfReified(_self);
  const upb_FieldDef* f = PyUpb_Message_GetExtensionDef(_self, ext_desc);
  if (!f) return NULL;
  if (upb_FieldDef_IsRepeated(f)) {
    PyErr_SetString(PyExc_KeyError,
                    "Field is repeated. A singular method is required.");
    return NULL;
  }
  if (!msg) Py_RETURN_FALSE;
  return PyBool_FromLong(upb_Message_HasFieldByDef(msg, f));
}

void PyUpb_Message_ReportInitializationErrors(const upb_MessageDef* msgdef,
                                              PyObject* errors, PyObject* exc) {
  PyObject* comma = PyUnicode_FromString(",");
  PyObject* missing_fields = NULL;
  if (!comma) goto done;
  missing_fields = PyUnicode_Join(comma, errors);
  if (!missing_fields) goto done;
  PyErr_Format(exc, "Message %s is missing required fields: %U",
               upb_MessageDef_FullName(msgdef), missing_fields);
done:
  Py_XDECREF(comma);
  Py_XDECREF(missing_fields);
  Py_DECREF(errors);
}

PyObject* PyUpb_Message_SerializeInternal(PyObject* _self, PyObject* args,
                                          PyObject* kwargs,
                                          bool check_required) {
  PyUpb_Message* self = (void*)_self;
  if (!PyUpb_Message_Verify((PyObject*)self)) return NULL;
  static const char* kwlist[] = {"deterministic", NULL};
  int deterministic = 0;
  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|p", (char**)(kwlist),
                                   &deterministic)) {
    return NULL;
  }

  const upb_MessageDef* msgdef = _PyUpb_Message_GetMsgdef(self);
  if (PyUpb_Message_IsStub(self)) {
    // Nothing to serialize, but we do have to check whether the message is
    // initialized.
    PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
    PyObject* errors = PyUpb_Message_FindInitializationErrors(_self, NULL);
    if (!errors) return NULL;
    if (PyList_Size(errors) == 0) {
      Py_DECREF(errors);
      return PyBytes_FromStringAndSize(NULL, 0);
    }
    PyUpb_Message_ReportInitializationErrors(msgdef, errors,
                                             state->encode_error_class);
    return NULL;
  }

  upb_Arena* arena = upb_Arena_New();
  if (!arena) {
    PyErr_SetNone(PyExc_MemoryError);
    return NULL;
  }
  const upb_MiniTable* layout = upb_MessageDef_MiniTable(msgdef);
  size_t size = 0;
  // Python does not currently have any effective limit on serialization depth.
  int options = upb_EncodeOptions_MaxDepth(UINT16_MAX);
  if (check_required) options |= kUpb_EncodeOption_CheckRequired;
  if (deterministic) options |= kUpb_EncodeOption_Deterministic;
  char* pb;
  upb_EncodeStatus status =
      upb_Encode(self->ptr.msg, layout, options, arena, &pb, &size);
  PyObject* ret = NULL;

  if (status != kUpb_EncodeStatus_Ok) {
    if (status == kUpb_EncodeStatus_OutOfMemory) {
      PyErr_SetNone(PyExc_MemoryError);
    } else {
      PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
      PyObject* errors = PyUpb_Message_FindInitializationErrors(_self, NULL);
      if (PyList_Size(errors) != 0) {
        PyUpb_Message_ReportInitializationErrors(msgdef, errors,
                                                 state->encode_error_class);
      } else {
        PyErr_Format(state->encode_error_class, "Failed to serialize proto");
      }
    }
    goto done;
  }

  ret = PyBytes_FromStringAndSize(pb, size);

done:
  upb_Arena_Free(arena);
  return ret;
}

PyObject* PyUpb_Message_SerializeToString(PyObject* _self, PyObject* args,
                                          PyObject* kwargs) {
  return PyUpb_Message_SerializeInternal(_self, args, kwargs, true);
}

PyObject* PyUpb_Message_SerializePartialToString(PyObject* _self,
                                                 PyObject* args,
                                                 PyObject* kwargs) {
  return PyUpb_Message_SerializeInternal(_self, args, kwargs, false);
}

static PyObject* PyUpb_Message_WhichOneof(PyObject* _self, PyObject* name) {
  PyUpb_Message* self = (void*)_self;
  const upb_OneofDef* o;
  if (!PyUpb_Message_LookupName(self, name, NULL, &o, PyExc_ValueError)) {
    return NULL;
  }
  upb_Message* msg = PyUpb_Message_GetIfReified(_self);
  if (!msg) Py_RETURN_NONE;
  const upb_FieldDef* f = upb_Message_WhichOneofByDef(msg, o);
  if (!f) Py_RETURN_NONE;
  return PyUnicode_FromString(upb_FieldDef_Name(f));
}

PyObject* PyUpb_Message_Clone(PyObject* _self, PyObject* args) {
  upb_Message* msg = PyUpb_Message_GetIfReified(_self);
  const upb_MessageDef* def = PyUpb_Message_GetMsgdef(_self);
  const upb_MiniTable* mini_table = upb_MessageDef_MiniTable(def);
  PyObject* arena = PyUpb_Arena_New(PyUpb_Message_GetPool(_self));
  if (!arena) return NULL;
  upb_Arena* upb_arena = PyUpb_Arena_Get(arena);

  upb_Message* clone = msg ? upb_Message_DeepClone(msg, mini_table, upb_arena)
                           : upb_Message_New(mini_table, upb_arena);
  if (!clone) {
    Py_DECREF(arena);
    PyErr_SetNone(PyExc_MemoryError);
    return NULL;
  }
  PyObject* desc = PyUpb_Message_GetDescriptor(_self);
  PyObject* pool = PyUpb_AnyDescriptor_GetPool(desc);
  PyObject* ret = PyUpb_Message_Get(pool, clone, def, arena);
  Py_DECREF(arena);

  return ret;
}

void PyUpb_Message_ClearExtensionDict(PyObject* _self) {
  PyUpb_Message* self = (void*)_self;
  assert(self->ext_dict);
  self->ext_dict = NULL;
}

static PyObject* PyUpb_Message_GetExtensionDict(PyObject* _self,
                                                void* closure) {
  PyUpb_Message* self = (void*)_self;
  if (self->ext_dict) {
    Py_INCREF(self->ext_dict);
    return self->ext_dict;
  }

  const upb_MessageDef* m = _PyUpb_Message_GetMsgdef(self);
  if (upb_MessageDef_ExtensionRangeCount(m) == 0) {
    PyErr_SetNone(PyExc_AttributeError);
    return NULL;
  }

  self->ext_dict = PyUpb_ExtensionDict_New(_self);
  return self->ext_dict;
}

static PyGetSetDef PyUpb_Message_Getters[] = {
    {"Extensions", PyUpb_Message_GetExtensionDict, NULL, "Extension dict"},
    {NULL}};

static PyMethodDef PyUpb_Message_Methods[] = {
    {"__deepcopy__", (PyCFunction)PyUpb_Message_Clone, METH_VARARGS,
     "Makes a deep copy of the class."},
    // TODO
    //{ "__unicode__", (PyCFunction)ToUnicode, METH_NOARGS,
    //  "Outputs a unicode representation of the message." },
    {"__contains__", PyUpb_Message_Contains, METH_O,
     "Checks if a message field is set."},
    {"ByteSize", (PyCFunction)PyUpb_Message_ByteSize, METH_NOARGS,
     "Returns the size of the message in bytes."},
    {"Clear", (PyCFunction)PyUpb_Message_Clear, METH_NOARGS,
     "Clears the message."},
    {"ClearExtension", PyUpb_Message_ClearExtension, METH_O,
     "Clears a message field."},
    {"ClearField", PyUpb_Message_ClearField, METH_O, "Clears a message field."},
    {"CopyFrom", PyUpb_Message_CopyFrom, METH_O,
     "Copies a protocol message into the current message."},
    {"DiscardUnknownFields", (PyCFunction)PyUpb_Message_DiscardUnknownFields,
     METH_NOARGS, "Discards the unknown fields."},
    {"FindInitializationErrors", PyUpb_Message_FindInitializationErrors,
     METH_NOARGS, "Finds unset required fields."},
    {"FromString", PyUpb_Message_FromString, METH_O | METH_CLASS,
     "Creates new method instance from given serialized data."},
    {"HasExtension", PyUpb_Message_HasExtension, METH_O,
     "Checks if a message field is set."},
    {"HasField", PyUpb_Message_HasField, METH_O,
     "Checks if a message field is set."},
    {"IsInitialized", PyUpb_Message_IsInitialized, METH_VARARGS,
     "Checks if all required fields of a protocol message are set."},
    {"ListFields", PyUpb_Message_ListFields, METH_NOARGS,
     "Lists all set fields of a message."},
    {"MergeFrom", PyUpb_Message_MergeFrom, METH_O,
     "Merges a protocol message into the current message."},
    {"MergeFromString", PyUpb_Message_MergeFromString, METH_O,
     "Merges a serialized message into the current message."},
    {"ParseFromString", PyUpb_Message_ParseFromString, METH_O,
     "Parses a serialized message into the current message."},
    {"SerializePartialToString",
     (PyCFunction)PyUpb_Message_SerializePartialToString,
     METH_VARARGS | METH_KEYWORDS,
     "Serializes the message to a string, even if it isn't initialized."},
    {"SerializeToString", (PyCFunction)PyUpb_Message_SerializeToString,
     METH_VARARGS | METH_KEYWORDS,
     "Serializes the message to a string, only for initialized messages."},
    {"SetInParent", (PyCFunction)PyUpb_Message_SetInParent, METH_NOARGS,
     "Sets the has bit of the given field in its parent message."},
    {"UnknownFields", (PyCFunction)PyUpb_Message_UnknownFields, METH_NOARGS,
     "Parse unknown field set"},
    {"WhichOneof", PyUpb_Message_WhichOneof, METH_O,
     "Returns the name of the field set inside a oneof, "
     "or None if no field is set."},
    {"_ListFieldsItemKey", PyUpb_Message_ListFieldsItemKey,
     METH_O | METH_STATIC,
     "Compares ListFields() list entries by field number"},
    {"_CheckCalledFromGeneratedFile",
     PyUpb_Message_CheckCalledFromGeneratedFile, METH_NOARGS | METH_STATIC,
     "Raises TypeError if the caller is not in a _pb2.py file."},
    {NULL, NULL}};

static PyType_Slot PyUpb_Message_Slots[] = {
    {Py_tp_dealloc, PyUpb_Message_Dealloc},
    {Py_tp_doc, "A ProtocolMessage"},
    {Py_tp_getattro, PyUpb_Message_GetAttr},
    {Py_tp_getset, PyUpb_Message_Getters},
    {Py_tp_hash, PyObject_HashNotImplemented},
    {Py_tp_methods, PyUpb_Message_Methods},
    {Py_tp_new, PyUpb_Message_New},
    {Py_tp_str, PyUpb_Message_ToString},
    {Py_tp_repr, PyUpb_Message_ToString},
    {Py_tp_richcompare, PyUpb_Message_RichCompare},
    {Py_tp_setattro, PyUpb_Message_SetAttr},
    {Py_tp_init, PyUpb_Message_Init},
    {0, NULL}};

PyType_Spec PyUpb_Message_Spec = {
    PYUPB_MODULE_NAME ".Message",              // tp_name
    sizeof(PyUpb_Message),                     // tp_basicsize
    0,                                         // tp_itemsize
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  // tp_flags
    PyUpb_Message_Slots,
};

// -----------------------------------------------------------------------------
// MessageMeta
// -----------------------------------------------------------------------------

// MessageMeta is the metaclass for message objects.  The generated code uses it
// to construct message classes, ie.
//
// FooMessage = _message.MessageMeta('FooMessage', (_message.Message), {...})
//
// (This is not quite true: at the moment the Python library subclasses
// MessageMeta, and uses that subclass as the metaclass.  There is a TODO below
// to simplify this, so that the illustration above is indeed accurate).

typedef struct {
  const upb_MiniTable* layout;
  PyObject* py_message_descriptor;
} PyUpb_MessageMeta;

// The PyUpb_MessageMeta struct is trailing data tacked onto the end of
// MessageMeta instances.  This means that we get our instances of this struct
// by adding the appropriate number of bytes.
static PyUpb_MessageMeta* PyUpb_GetMessageMeta(PyObject* cls) {
#ifndef NDEBUG
  PyUpb_ModuleState* state = PyUpb_ModuleState_MaybeGet();
  assert(!state || Py_TYPE(cls) == state->message_meta_type);
#endif
  return (PyUpb_MessageMeta*)((char*)cls + cpython_bits.type_basicsize);
}

static PyObject* PyUpb_Message_GetDescriptor(PyObject* self) {
  return PyUpb_GetMessageMeta((PyObject*)Py_TYPE(self))->py_message_descriptor;
}

PyObject* PyUpb_MessageClass_GetPool(PyObject* cls) {
  PyObject* descriptor = PyUpb_GetMessageMeta(cls)->py_message_descriptor;
  return descriptor ? PyUpb_AnyDescriptor_GetPool(descriptor) : NULL;
}

PyObject* PyUpb_Message_GetPool(PyObject* self) {
  return PyUpb_MessageClass_GetPool((PyObject*)Py_TYPE(self));
}

PyObject* PyUpb_MessageMeta_GetSubClass(PyObject* parent,
                                        const upb_FieldDef* f) {
  const upb_MessageDef* sub_m = upb_FieldDef_MessageSubDef(f);
  PyObject* pool = PyUpb_Message_GetPool(parent);
  return PyUpb_Descriptor_GetClass(pool, sub_m);
}

static const upb_MessageDef* PyUpb_MessageMeta_GetMsgdef(PyObject* cls) {
  PyUpb_MessageMeta* self = PyUpb_GetMessageMeta(cls);
  return self->py_message_descriptor
             ? PyUpb_Descriptor_GetDef(self->py_message_descriptor)
             : NULL;
}

PyObject* PyUpb_MessageMeta_DoCreateClass(PyObject* py_descriptor,
                                          PyObject* name, PyObject* dict) {
  PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
  PyTypeObject* descriptor_type = state->descriptor_types[kPyUpb_Descriptor];
  if (!PyObject_TypeCheck(py_descriptor, descriptor_type)) {
    return PyErr_Format(PyExc_TypeError, "Expected a message Descriptor");
  }

  const upb_MessageDef* msgdef = PyUpb_Descriptor_GetDef(py_descriptor);
  assert(msgdef);
  PyObject* pool = PyUpb_AnyDescriptor_GetPool(py_descriptor);
  assert(
      !PyUpb_DescriptorPool_CacheGet(pool, upb_MessageDef_MiniTable(msgdef)));

  PyObject* slots = PyTuple_New(0);
  if (!slots) return NULL;
  int status = PyDict_SetItemString(dict, "__slots__", slots);
  Py_DECREF(slots);
  if (status < 0) return NULL;

  // Bases are either:
  //    (Message, Message)            # for regular messages
  //    (Message, Message, WktBase)   # For well-known types
  PyObject* wkt_bases = PyUpb_GetWktBases(state);
  PyObject* wkt_base =
      PyDict_GetItemString(wkt_bases, upb_MessageDef_FullName(msgdef));
  PyObject* args;
  if (wkt_base == NULL) {
    args = Py_BuildValue("O(OO)O", name, state->cmessage_type,
                         state->message_class, dict);
  } else {
    args = Py_BuildValue("O(OOO)O", name, state->cmessage_type,
                         state->message_class, wkt_base, dict);
  }

  PyObject* ret = cpython_bits.type_new(state->message_meta_type, args, NULL);
  Py_DECREF(args);
  if (!ret) return NULL;

  PyUpb_MessageMeta* meta = PyUpb_GetMessageMeta(ret);
  meta->py_message_descriptor = py_descriptor;
  meta->layout = upb_MessageDef_MiniTable(msgdef);
  Py_INCREF(meta->py_message_descriptor);
  PyUpb_Descriptor_SetClass(py_descriptor, ret);

  if (!PyUpb_DescriptorPool_CacheAdd(pool, meta->layout, &ret)) {
    PyUpb_Descriptor_SetClass(py_descriptor, NULL);
    Py_DECREF(ret);
    return NULL;
  }

  return ret;
}

static PyObject* PyUpb_MessageMeta_New(PyTypeObject* type, PyObject* args,
                                       PyObject* kwargs) {
  PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
  static const char* kwlist[] = {"name", "bases", "dict", 0};
  PyObject *name, *bases, *dict;

  // Check arguments: (name, bases, dict)
  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "UO!O!:type", (char**)kwlist,
                                   &name, &PyTuple_Type, &bases, &PyDict_Type,
                                   &dict)) {
    return NULL;
  }

  // Check bases: only (), or (message.Message,) are allowed
  Py_ssize_t size = PyTuple_Size(bases);
  if (!(size == 0 ||
        (size == 1 && PyTuple_GetItem(bases, 0) == state->message_class))) {
    PyErr_Format(PyExc_TypeError,
                 "A Message class can only inherit from Message, not %S",
                 bases);
    return NULL;
  }

  // Check dict['DESCRIPTOR']
  PyObject* py_descriptor = PyDict_GetItemString(dict, "DESCRIPTOR");
  if (py_descriptor == NULL) {
    PyErr_SetString(PyExc_TypeError, "Message class has no DESCRIPTOR");
    return NULL;
  }

  const upb_MessageDef* m = PyUpb_Descriptor_GetDef(py_descriptor);
  // The error message already been filled by the function above.
  if (m == NULL) return NULL;
  PyObject* pool = PyUpb_AnyDescriptor_GetPool(py_descriptor);
  PyObject* ret =
      PyUpb_DescriptorPool_CacheGet(pool, upb_MessageDef_MiniTable(m));
  if (ret) return ret;
  return PyUpb_MessageMeta_DoCreateClass(py_descriptor, name, dict);
}

static void PyUpb_MessageMeta_Dealloc(PyObject* self) {
  PyUpb_MessageMeta* meta = PyUpb_GetMessageMeta(self);
  if (meta->py_message_descriptor) {
    PyObject* pool = PyUpb_AnyDescriptor_GetPool(meta->py_message_descriptor);
    if (pool) {
      PyUpb_DescriptorPool_CacheEraseIfEqual(pool, meta->layout, self);
    }
  }
  // The MessageMeta type is a GC type, which means we should untrack the
  // object before invalidating internal state (so that code executed by the
  // GC doesn't see the invalid state). Unfortunately since we're calling
  // cpython_bits.type_dealloc, which also untracks the object, we can't.
  // Instead just make sure the internal state remains reasonable by using
  // Py_CLEAR(), which sets the struct member to NULL. The tp_traverse and
  // tp_clear methods, which are called by Python's GC, already allow for it
  // to be NULL.
  Py_CLEAR(meta->py_message_descriptor);
  PyTypeObject* tp = Py_TYPE(self);
  cpython_bits.type_dealloc(self);
  Py_DECREF(tp);
}

void PyUpb_MessageMeta_AddFieldNumber(PyObject* self, const upb_FieldDef* f) {
  PyObject* name =
      PyUnicode_FromFormat("%s_FIELD_NUMBER", upb_FieldDef_Name(f));
  if (!name) {
    PyErr_Clear();
    return;
  }
  PyObject* upper = PyObject_CallMethod(name, "upper", NULL);
  if (!upper) {
    PyErr_Clear();
    Py_DECREF(name);
    return;
  }
  PyObject* val = PyLong_FromLong(upb_FieldDef_Number(f));
  if (val) {
    if (PyObject_SetAttr(self, upper, val) < 0) {
      PyErr_Clear();
    }
    Py_DECREF(val);
  } else {
    PyErr_Clear();
  }
  Py_DECREF(name);
  Py_DECREF(upper);
}

static PyObject* PyUpb_MessageMeta_GetDynamicAttr(PyObject* self,
                                                  PyObject* name) {
  const char* name_buf = PyUpb_GetStrData(name);
  if (!name_buf) return NULL;
  const upb_MessageDef* msgdef = PyUpb_MessageMeta_GetMsgdef(self);
  const upb_FileDef* filedef = upb_MessageDef_File(msgdef);
  const upb_DefPool* symtab = upb_FileDef_Pool(filedef);

  PyObject* py_key =
      PyBytes_FromFormat("%s.%s", upb_MessageDef_FullName(msgdef), name_buf);
  const char* key = PyUpb_GetStrData(py_key);
  PyObject* ret = NULL;
  const upb_MessageDef* nested = upb_DefPool_FindMessageByName(symtab, key);
  const upb_EnumDef* enumdef;
  const upb_EnumValueDef* enumval;
  const upb_FieldDef* ext;

  PyObject* pool = PyUpb_MessageClass_GetPool(self);
  if (nested) {
    ret = PyUpb_Descriptor_GetClass(pool, nested);
  } else if ((enumdef = upb_DefPool_FindEnumByName(symtab, key))) {
    PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
    PyObject* klass = state->enum_type_wrapper_class;
    ret = PyUpb_EnumDescriptor_Get(pool, enumdef);
    ret = PyObject_CallFunctionObjArgs(klass, ret, NULL);
  } else if ((enumval = upb_DefPool_FindEnumValueByName(symtab, key))) {
    ret = PyLong_FromLong(upb_EnumValueDef_Number(enumval));
  } else if ((ext = upb_DefPool_FindExtensionByName(symtab, key))) {
    ret = PyUpb_FieldDescriptor_Get(pool, ext);
  }

  Py_DECREF(py_key);

  const char* suffix = "_FIELD_NUMBER";
  size_t n = strlen(name_buf);
  size_t suffix_n = strlen(suffix);
  if (n > suffix_n && memcmp(suffix, name_buf + n - suffix_n, suffix_n) == 0) {
    // We can't look up field names dynamically, because the <NAME>_FIELD_NUMBER
    // naming scheme upper-cases the field name and is therefore non-reversible.
    // So we just add all field numbers.
    int n = upb_MessageDef_FieldCount(msgdef);
    for (int i = 0; i < n; i++) {
      PyUpb_MessageMeta_AddFieldNumber(self, upb_MessageDef_Field(msgdef, i));
    }
    n = upb_MessageDef_NestedExtensionCount(msgdef);
    for (int i = 0; i < n; i++) {
      PyUpb_MessageMeta_AddFieldNumber(
          self, upb_MessageDef_NestedExtension(msgdef, i));
    }
    ret = PyObject_GenericGetAttr(self, name);
  }

  return ret;
}

static PyObject* PyUpb_MessageMeta_GetAttr(PyObject* self, PyObject* name) {
  // We want to first delegate to the type's tp_dict to retrieve any attributes
  // that were previously calculated and cached in the type's dict.
  PyObject* ret = cpython_bits.type_getattro(self, name);
  if (ret) return ret;
  if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
    return NULL;
  }

  // We did not find a cached attribute. Try to calculate the attribute
  // dynamically, using the descriptor as an argument.
  PyErr_Clear();
  ret = PyUpb_MessageMeta_GetDynamicAttr(self, name);

  if (ret) {
    PyObject_SetAttr(self, name, ret);
    PyErr_Clear();
    return ret;
  }

  if (!PyErr_Occurred()) {
    PyErr_SetObject(PyExc_AttributeError, name);
  }
  return NULL;
}

static int PyUpb_MessageMeta_Traverse(PyObject* self, visitproc visit,
                                      void* arg) {
  PyUpb_MessageMeta* meta = PyUpb_GetMessageMeta(self);
  Py_VISIT(meta->py_message_descriptor);
  return cpython_bits.type_traverse(self, visit, arg);
}

static int PyUpb_MessageMeta_Clear(PyObject* self) {
  PyUpb_MessageMeta* meta = PyUpb_GetMessageMeta(self);
  if (meta->py_message_descriptor) {
    PyObject* pool = PyUpb_AnyDescriptor_GetPool(meta->py_message_descriptor);
    if (pool) {
      PyUpb_DescriptorPool_CacheEraseIfEqual(pool, meta->layout, self);
    }
  }
  Py_CLEAR(meta->py_message_descriptor);
  return cpython_bits.type_clear(self);
}

static PyType_Slot PyUpb_MessageMeta_Slots[] = {
    {Py_tp_new, PyUpb_MessageMeta_New},
    {Py_tp_dealloc, PyUpb_MessageMeta_Dealloc},
    {Py_tp_getattro, PyUpb_MessageMeta_GetAttr},
    {Py_tp_traverse, PyUpb_MessageMeta_Traverse},
    {Py_tp_clear, PyUpb_MessageMeta_Clear},
    {0, NULL}};

static PyType_Spec PyUpb_MessageMeta_Spec = {
    PYUPB_MODULE_NAME ".MessageMeta",  // tp_name
    0,  // To be filled in by size of base     // tp_basicsize
    0,  // tp_itemsize
    // TODO: remove BASETYPE, Python should just use MessageMeta
    // directly instead of subclassing it.
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,  // tp_flags
    PyUpb_MessageMeta_Slots,
};

static PyObject* PyUpb_MessageMeta_CreateType(void) {
  PyObject* bases = Py_BuildValue("(O)", &PyType_Type);
  if (!bases) return NULL;
  PyUpb_MessageMeta_Spec.basicsize =
      cpython_bits.type_basicsize + sizeof(PyUpb_MessageMeta);
  PyObject* type = PyType_FromSpecWithBases(&PyUpb_MessageMeta_Spec, bases);
  Py_DECREF(bases);
  return type;
}

bool PyUpb_InitMessage(PyObject* m) {
  if (!PyUpb_CPythonBits_Init(&cpython_bits)) return false;
  PyObject* message_meta_type = PyUpb_MessageMeta_CreateType();

  PyUpb_ModuleState* state = PyUpb_ModuleState_GetFromModule(m);
  state->cmessage_type = PyUpb_AddClass(m, &PyUpb_Message_Spec);
  state->message_meta_type = (PyTypeObject*)message_meta_type;

  if (!state->cmessage_type || !state->message_meta_type) return false;
  if (PyModule_AddObject(m, "MessageMeta", message_meta_type)) return false;
  state->listfields_item_key = PyObject_GetAttrString(
      (PyObject*)state->cmessage_type, "_ListFieldsItemKey");

  PyObject* mod =
      PyImport_ImportModule(PYUPB_PROTOBUF_PUBLIC_PACKAGE ".message");
  if (mod == NULL) return false;

  state->encode_error_class = PyObject_GetAttrString(mod, "EncodeError");
  state->decode_error_class = PyObject_GetAttrString(mod, "DecodeError");
  state->message_class = PyObject_GetAttrString(mod, "Message");
  state->frozen_instance_error_class =
      PyObject_GetAttrString(mod, "FrozenInstanceError");
  Py_DECREF(mod);

  PyObject* enum_type_wrapper = PyImport_ImportModule(
      PYUPB_PROTOBUF_INTERNAL_PACKAGE ".enum_type_wrapper");
  if (enum_type_wrapper == NULL) return false;

  state->enum_type_wrapper_class =
      PyObject_GetAttrString(enum_type_wrapper, "EnumTypeWrapper");
  Py_DECREF(enum_type_wrapper);

  if (!state->encode_error_class || !state->decode_error_class ||
      !state->message_class || !state->listfields_item_key ||
      !state->enum_type_wrapper_class || !state->frozen_instance_error_class) {
    return false;
  }

  return true;
}
