// 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/repeated.h"

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

#include "google/protobuf/breaking_changes.h"
#include "python/buffer_convert.h"
#include "python/convert.h"
#include "python/descriptor.h"
#include "python/message.h"
#include "python/protobuf.h"
#include "upb/base/descriptor_constants.h"
#include "upb/mem/arena.h"
#include "upb/message/array.h"
#include "upb/message/message.h"
#include "upb/mini_table/message.h"
#include "upb/port/overflow.h"
#include "upb/reflection/def.h"

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

#define PyUpb_SUPPORT_BUFFER_VIEW 0

static PyObject* PyUpb_RepeatedCompositeContainer_Append(PyObject* _self,
                                                         PyObject* value);
static PyObject* PyUpb_RepeatedScalarContainer_Append(PyObject* _self,
                                                      PyObject* value);

// Wrapper for a repeated field.
typedef struct {
  // clang-format off
  PyObject_HEAD
  PyObject* arena;
  // clang-format on
  // The field descriptor (PyObject*).
  // The low bit indicates whether the container is reified (see ptr below).
  //   - low bit set: repeated field is a stub (no underlying data).
  //   - low bit clear: repeated field is reified (points to upb_Array).
  uintptr_t field;
  union {
    PyObject* parent;  // stub: owning pointer to parent message.
    upb_Array* arr;    // reified: the data for this array.
  } ptr;
} PyUpb_RepeatedContainer;

static bool PyUpb_RepeatedContainer_IsStub(PyUpb_RepeatedContainer* self) {
  return self->field & 1;
}

static PyObject* PyUpb_RepeatedContainer_GetFieldDescriptor(
    PyUpb_RepeatedContainer* self) {
  return (PyObject*)(self->field & ~(uintptr_t)1);
}

static const upb_FieldDef* PyUpb_RepeatedContainer_GetField(
    PyUpb_RepeatedContainer* self) {
  return PyUpb_FieldDescriptor_GetDef(
      PyUpb_RepeatedContainer_GetFieldDescriptor(self));
}

// If the repeated field is reified, returns it.  Otherwise, returns NULL.
// If NULL is returned, the object is empty and has no underlying data.
static upb_Array* PyUpb_RepeatedContainer_GetIfReified(
    PyUpb_RepeatedContainer* self) {
  return PyUpb_RepeatedContainer_IsStub(self) ? NULL : self->ptr.arr;
}

upb_Array* PyUpb_RepeatedContainer_Reify(PyObject* _self, upb_Array* arr,
                                         PyUpb_WeakMap* subobj_map,
                                         intptr_t iter) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  assert(PyUpb_RepeatedContainer_IsStub(self));
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  if (!arr) {
    upb_Arena* arena = PyUpb_Arena_Get(self->arena);
    arr = upb_Array_New(arena, upb_FieldDef_CType(f));
    if (!arr) {
      PyErr_SetNone(PyExc_MemoryError);
      return NULL;
    }
  }
  if (subobj_map) {
    PyUpb_WeakMap_DeleteIter(subobj_map, &iter);
  } else {
    if (!PyUpb_Message_SetConcreteSubobj(
            self->ptr.parent, f, (upb_MessageValue){.array_val = arr})) {
      return NULL;
    }
  }
  if (!PyUpb_ObjCache_Add(arr, &self->ob_base)) {
    return NULL;
  }
  Py_DECREF(self->ptr.parent);
  self->ptr.arr = arr;  // Overwrites self->ptr.parent.
  self->field &= ~(uintptr_t)1;
  assert(!PyUpb_RepeatedContainer_IsStub(self));
  return arr;
}

bool PyUpb_RepeatedContainer_IsFrozen(PyUpb_RepeatedContainer* self) {
  if (PyUpb_RepeatedContainer_IsStub(self)) {
    return PyUpb_Message_IsFrozen(self->ptr.parent);
  } else {
    return upb_Array_IsFrozen(self->ptr.arr) ||
           PyUpb_Arena_IsFrozen(self->arena);
  }
}

upb_Array* PyUpb_RepeatedContainer_AssureWritable(PyObject* _self) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  if (PyUpb_RepeatedContainer_IsFrozen(self)) {
    if (!PyUpb_CheckFrozen(true, "Container is immutable")) {
      return NULL;
    }
  }

  upb_Array* arr = PyUpb_RepeatedContainer_GetIfReified(self);
  if (arr) return arr;  // Already writable.

  return PyUpb_RepeatedContainer_Reify((PyObject*)self, NULL, NULL, 0);
}

static void PyUpb_RepeatedContainer_Dealloc(PyObject* _self) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  Py_DECREF(self->arena);
  if (PyUpb_RepeatedContainer_IsStub(self)) {
    PyUpb_Message_CacheDelete(self->ptr.parent,
                              PyUpb_RepeatedContainer_GetField(self));
    Py_DECREF(self->ptr.parent);
  } else {
    PyUpb_ObjCache_Delete(self->ptr.arr);
  }
  Py_DECREF(PyUpb_RepeatedContainer_GetFieldDescriptor(self));
  PyUpb_Dealloc(self);
}

static PyTypeObject* PyUpb_RepeatedContainer_GetClass(const upb_FieldDef* f) {
  assert(upb_FieldDef_IsRepeated(f) && !upb_FieldDef_IsMap(f));
  PyUpb_ModuleState* state = PyUpb_ModuleState_MaybeGet();
  if (!state) return NULL;
  return upb_FieldDef_IsSubMessage(f) ? state->repeated_composite_container_type
                                      : state->repeated_scalar_container_type;
}

static Py_ssize_t PyUpb_RepeatedContainer_Length(PyObject* self) {
  upb_Array* arr =
      PyUpb_RepeatedContainer_GetIfReified((PyUpb_RepeatedContainer*)self);
  return arr ? upb_Array_Size(arr) : 0;
}

PyObject* PyUpb_RepeatedContainer_NewStub(PyObject* parent,
                                          const upb_FieldDef* f,
                                          PyObject* arena) {
  PyTypeObject* cls = PyUpb_RepeatedContainer_GetClass(f);
  if (!cls) {
    PyErr_SetString(PyExc_RuntimeError, "Interpreter is finalizing");
    return NULL;
  }
  PyUpb_RepeatedContainer* repeated = (void*)PyType_GenericAlloc(cls, 0);
  if (repeated == NULL) return NULL;
  repeated->arena = arena;
  repeated->field = (uintptr_t)PyUpb_FieldDescriptor_Get(f) | 1;
  repeated->ptr.parent = parent;
  Py_INCREF(arena);
  Py_INCREF(parent);
  return &repeated->ob_base;
}

PyObject* PyUpb_RepeatedContainer_GetOrCreateWrapper(upb_Array* arr,
                                                     const upb_FieldDef* f,
                                                     PyObject* arena) {
  PyObject* ret = PyUpb_ObjCache_Get(arr);
  if (ret) return ret;

  PyTypeObject* cls = PyUpb_RepeatedContainer_GetClass(f);
  if (!cls) {
    PyErr_SetString(PyExc_RuntimeError, "Interpreter is finalizing");
    return NULL;
  }
  PyUpb_RepeatedContainer* repeated = (void*)PyType_GenericAlloc(cls, 0);
  if (repeated == NULL) return NULL;
  repeated->arena = arena;
  repeated->field = (uintptr_t)PyUpb_FieldDescriptor_Get(f);
  repeated->ptr.arr = arr;
  ret = &repeated->ob_base;
  Py_INCREF(arena);
  if (!PyUpb_ObjCache_Add(arr, ret)) {
    Py_DECREF(ret);
    return NULL;
  }
  return ret;
}

static PyObject* PyUpb_RepeatedContainer_MergeFrom(PyObject* _self,
                                                   PyObject* args);

PyObject* PyUpb_RepeatedContainer_DeepCopy(PyObject* _self, PyObject* value) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  PyUpb_RepeatedContainer* clone =
      (void*)PyType_GenericAlloc(Py_TYPE(_self), 0);
  if (clone == NULL) return NULL;
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  clone->arena = PyUpb_Arena_New();
  if (clone->arena == NULL) goto err;
  clone->field = (uintptr_t)PyUpb_FieldDescriptor_Get(f);
  clone->ptr.arr =
      upb_Array_New(PyUpb_Arena_Get(clone->arena), upb_FieldDef_CType(f));
  if (clone->ptr.arr == NULL) {
    PyErr_SetNone(PyExc_MemoryError);
    goto err;
  }
  if (!PyUpb_ObjCache_Add(clone->ptr.arr, (PyObject*)clone)) {
    goto err;
  }
  PyObject* result = PyUpb_RepeatedContainer_MergeFrom((PyObject*)clone, _self);
  if (!result) {
    goto err;
  }
  Py_DECREF(result);
  return (PyObject*)clone;

err:
  Py_DECREF(clone);
  return NULL;
}

#if PyUpb_SUPPORT_BUFFER_VIEW
static bool IsContiguous1D(const Py_buffer* view) {
  return view->ndim == 1 &&
         (view->strides == NULL || view->itemsize == view->strides[0]);
}
#endif

// When `size_cb_accurate` is true, it is invoked exactly once with
// the accurate size. Otherwise, it is invoked in a best-effort manner where the
// size may be smaller/larger than the actual size of the input or not called at
// all.
typedef bool (*PyUpb_SizeCb)(Py_ssize_t size, void* ctx);

// Callback invoked once per converted element during iteration.
// Returns false to stop iteration (caller should set a Python error first).
typedef bool (*PyUpb_ElemCb)(upb_MessageValue val, void* ctx);

// Callback invoked once with a contiguous raw buffer of matching type.
// `data` points to `count` elements each of size `itemsize`.
// Returns false on error.
typedef bool (*PyUpb_BulkCb)(const void* data, Py_ssize_t count,
                             Py_ssize_t itemsize, void* ctx);

static PyUpb_TryResult PyUpb_IterInputTryRepeatedContainer(
    PyObject* value, const upb_FieldDef* field, upb_Arena* arena,
    PyUpb_BulkCb bulk_cb, void* ctx) {
  // Detect if value is a repeated scalar container of a compatible field type.
  PyUpb_ModuleState* state = PyUpb_ModuleState_MaybeGet();
  if (state == NULL ||
      Py_TYPE(value) != state->repeated_scalar_container_type) {
    return kPyUpb_TryResult_NotSupported;
  }
  PyUpb_RepeatedContainer* src = (PyUpb_RepeatedContainer*)value;
  const upb_FieldDef* src_f = PyUpb_RepeatedContainer_GetField(src);
  const upb_CType src_type = upb_FieldDef_CType(src_f);
  const PyUpb_SourceKind src_kind = PyUpb_SourceKindFromCType(src_type);

  upb_Array* src_arr = PyUpb_RepeatedContainer_GetIfReified(src);
  size_t count = src_arr ? upb_Array_Size(src_arr) : 0;
  if (count == 0) {
    return bulk_cb(NULL, 0, 0, ctx) ? kPyUpb_TryResult_Success
                                    : kPyUpb_TryResult_Failure;
  }
  const void* src_data = upb_Array_DataPtr(src_arr);
  void* cast_data = NULL;
  PyUpb_TryResult res =
      PyUpb_TryConvertBuffer(field, src_kind, &src_data, count, &cast_data);
  if (res != kPyUpb_TryResult_Success) {
    return res;
  }

  const size_t target_item_size =
      PyUpb_GetTargetItemSize(upb_FieldDef_CType(field));
  bool ok = bulk_cb(src_data, count, target_item_size, ctx);

  if (cast_data != NULL) {
    PyMem_Free(cast_data);
  }

  return ok ? kPyUpb_TryResult_Success : kPyUpb_TryResult_Failure;
}

#if PyUpb_SUPPORT_BUFFER_VIEW
static PyUpb_TryResult PyUpb_IterInputTryBufferView(
    PyObject* value, const upb_FieldDef* field, upb_Arena* arena,
    PyUpb_SizeCb size_cb, PyUpb_ElemCb elem_cb, PyUpb_BulkCb bulk_cb,
    void* ctx) {
  Py_buffer view;
  if (PyObject_GetBuffer(value, &view, PyBUF_RECORDS_RO) != 0) {
    PyErr_Clear();
    return kPyUpb_TryResult_NotSupported;
  }
  if (!IsContiguous1D(&view)) {
    PyBuffer_Release(&view);
    return kPyUpb_TryResult_NotSupported;
  }
  const void* src_buf = view.buf;
  void* temp_buf = NULL;
  const char format = view.format == NULL ? 'B' : view.format[0];
  Py_ssize_t count = view.len / view.itemsize;
  if (count == 0) {
    PyBuffer_Release(&view);
    return bulk_cb(NULL, 0, 0, ctx) ? kPyUpb_TryResult_Success
                                    : kPyUpb_TryResult_Failure;
  }
  if (format == 'O') {
    PyObject** objs = (PyObject**)src_buf;
    if (!size_cb(count, ctx)) {
      goto error;
    }
    for (Py_ssize_t i = 0; i < count; i++) {
      PyObject* item = objs[i] ? objs[i] : Py_None;
      upb_MessageValue msgval;
      if (!PyUpb_PyToUpb(item, field, &msgval, arena)) {
        goto error;
      }
      if (!elem_cb(msgval, ctx)) {
        goto error;
      }
    }
    goto done;
  }
  const PyUpb_SourceKind src_kind =
      PyUpb_SourceKindFromFormat(view.itemsize, format);
  switch (PyUpb_TryConvertBuffer(field, src_kind, &src_buf, count, &temp_buf)) {
    case kPyUpb_TryResult_Success:
      break;
    case kPyUpb_TryResult_Failure:
      goto error;
    case kPyUpb_TryResult_NotSupported:
      goto not_supported;
  }
  const size_t target_item_size =
      PyUpb_GetTargetItemSize(upb_FieldDef_CType(field));
  if (bulk_cb(src_buf, count, target_item_size, ctx)) {
    goto done;
  } else {
    goto error;
  }

done:
  if (temp_buf) {
    PyMem_Free(temp_buf);
  }
  PyBuffer_Release(&view);
  return kPyUpb_TryResult_Success;
error:
  if (temp_buf) {
    PyMem_Free(temp_buf);
  }
  PyBuffer_Release(&view);
  return kPyUpb_TryResult_Failure;
not_supported:
  if (temp_buf) {
    PyMem_Free(temp_buf);
  }
  PyBuffer_Release(&view);
  return kPyUpb_TryResult_NotSupported;
}
#endif  // PyUpb_SUPPORT_BUFFER_VIEW

// Iterates the elements of a Python iterable `value`, converting each to
// upb_MessageValue via PyUpb_PyToUpb, and invoking `elem_cb` per element.
//
// When PyUpb_SUPPORT_BUFFER_VIEW is enabled and if `bulk_cb` is non-NULL and
// `value` exposes a contiguous buffer whose element type matches `field`,
// `bulk_cb` is called once with the raw data pointer. Otherwise size_cb is
// called once with the number of elements in `value`, and then `elem_cb` is
// called for each element.
//
// Returns whether a Python error occurred.
static bool PyUpb_IterInput(PyObject* value, const upb_FieldDef* field,
                            upb_Arena* arena, PyUpb_SizeCb size_cb,
                            PyUpb_ElemCb elem_cb, PyUpb_BulkCb bulk_cb,
                            void* ctx) {
  switch (
      PyUpb_IterInputTryRepeatedContainer(value, field, arena, bulk_cb, ctx)) {
    case kPyUpb_TryResult_Success:
      return true;
    case kPyUpb_TryResult_Failure:
      return false;
    case kPyUpb_TryResult_NotSupported:
      break;
  }

#if PyUpb_SUPPORT_BUFFER_VIEW
  switch (PyUpb_IterInputTryBufferView(value, field, arena, size_cb, elem_cb,
                                       bulk_cb, ctx)) {
    case kPyUpb_TryResult_Success:
      return true;
    case kPyUpb_TryResult_Failure:
      return false;
    case kPyUpb_TryResult_NotSupported:
      break;
  }
#endif
  PyObject* iter = NULL;
  PyObject* materialized = PySequence_Fast(value, "must assign iterable");
  if (!materialized) goto done;
  Py_ssize_t size = PyObject_Length(materialized);
  if (!size_cb(size, ctx)) goto done;

  iter = PyObject_GetIter(materialized);
  if (!iter) goto done;

  PyObject* item;
  while ((item = PyIter_Next(iter)) != NULL) {
    upb_MessageValue msgval;
    bool ok = PyUpb_PyToUpb(item, field, &msgval, arena);
    Py_DECREF(item);
    if (!ok) {
      goto done;
    }
    if (!elem_cb(msgval, ctx)) {
      goto done;
    }
  }
done:
  Py_XDECREF(materialized);
  Py_XDECREF(iter);
  return !PyErr_Occurred();
}

typedef struct {
  upb_Array* arr;
  upb_Arena* arena;
  Py_ssize_t size_hint;
} PyUpb_ExtendCtx;

static bool PyUpb_ExtendSizeCb(Py_ssize_t size, void* vctx) {
  PyUpb_ExtendCtx* ctx = (PyUpb_ExtendCtx*)vctx;
  ctx->size_hint = size;
  size_t old_size = upb_Array_Size(ctx->arr);
  size_t new_size;
  if (size > 0 && !upb_AddOverflow(old_size, (size_t)size, &new_size)) {
    if (!upb_Array_Reserve(ctx->arr, new_size, ctx->arena)) {
      PyErr_SetNone(PyExc_MemoryError);
      return false;
    }
  }
  return true;
}

static bool PyUpb_ExtendElemCb(upb_MessageValue val, void* vctx) {
  PyUpb_ExtendCtx* ctx = (PyUpb_ExtendCtx*)vctx;
  if (!upb_Array_Append(ctx->arr, val, ctx->arena)) {
    PyErr_SetNone(PyExc_MemoryError);
    return false;
  }
  return true;
}

typedef enum {
  kDisjoint,
  kSubset,
  kOverlap,
} PyUpb_OverlapType;

static PyUpb_OverlapType PyUpb_ArrayOverlaps(const upb_Array* arr,
                                             const void* range_start,
                                             size_t range_size,
                                             size_t itemsize) {
  const char* src_start = upb_Array_DataPtr(arr);
  const char* src_end = src_start + upb_Array_Size(arr) * itemsize;
  const char* dst_start = (const char*)range_start;
  const char* dst_end = dst_start + range_size * itemsize;
  if (src_end <= dst_start || src_start >= dst_end) {
    return kDisjoint;
  }
  if (src_start >= dst_start && src_end <= dst_end) {
    return kSubset;
  }
  return kOverlap;
}

static bool PyUpb_ExtendBulkCb(const void* data, Py_ssize_t count,
                               Py_ssize_t itemsize, void* vctx) {
  PyUpb_ExtendCtx* ctx = (PyUpb_ExtendCtx*)vctx;
  size_t old_size = upb_Array_Size(ctx->arr);
  char* dst;
  switch (PyUpb_ArrayOverlaps(ctx->arr, data, count, itemsize)) {
    case kDisjoint:
      if (!upb_Array_Resize(ctx->arr, old_size + count, ctx->arena)) {
        PyErr_SetNone(PyExc_MemoryError);
        return false;
      }
      dst = upb_Array_MutableDataPtr(ctx->arr);
      break;
    case kSubset: {
      char* old_dst = upb_Array_MutableDataPtr(ctx->arr);
      if (!upb_Array_Resize(ctx->arr, old_size + count, ctx->arena)) {
        PyErr_SetNone(PyExc_MemoryError);
        return false;
      }
      dst = upb_Array_MutableDataPtr(ctx->arr);
      if (old_dst != dst) {
        data = dst + ((const char*)data - old_dst);
      }
    } break;
    case kOverlap:
      PyErr_SetString(PyExc_ValueError,
                      "Extending with overlapping sequence not supported");
      return false;
  }
  memcpy(dst + old_size * itemsize, data, count * itemsize);
  return true;
}

PyObject* PyUpb_RepeatedContainer_Extend(PyObject* _self, PyObject* value) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  upb_Array* arr = PyUpb_RepeatedContainer_AssureWritable(_self);
  if (!arr) return NULL;
  upb_Arena* arena = PyUpb_Arena_Get(self->arena);

  if (upb_FieldDef_IsSubMessage(f)) {
    // Composite fields: iterate and append via MergeFrom.
    // Buffer views don't apply to sub-messages.
    PyObject* iter = PyObject_GetIter(value);
    if (!iter) return NULL;
    PyObject* item;
    while ((item = PyIter_Next(iter)) != NULL) {
      PyObject* ret = PyUpb_RepeatedCompositeContainer_Append(_self, item);
      Py_DECREF(item);
      if (!ret) {
        Py_DECREF(iter);
        return NULL;
      }
      Py_DECREF(ret);
    }
    Py_DECREF(iter);
    if (PyErr_Occurred()) return NULL;
    Py_RETURN_NONE;
  }
  size_t old_size = upb_Array_Size(arr);
  PyUpb_ExtendCtx ctx = {arr, arena};
  if (!PyUpb_IterInput(value, f, arena, PyUpb_ExtendSizeCb, PyUpb_ExtendElemCb,
                       PyUpb_ExtendBulkCb, &ctx)) {
    bool ok = upb_Array_Resize(arr, old_size, NULL);
    UPB_ASSERT(ok);
    return NULL;
  }
  Py_RETURN_NONE;
}

static PyObject* PyUpb_RepeatedContainer_Item(PyObject* _self,
                                              Py_ssize_t index) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  upb_Array* arr = PyUpb_RepeatedContainer_GetIfReified(self);
  Py_ssize_t size = arr ? upb_Array_Size(arr) : 0;
  if (index < 0 || index >= size) {
    PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index);
    return NULL;
  }
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  return PyUpb_UpbToPy(upb_Array_Get(arr, index), f, self->arena);
}

PyObject* PyUpb_RepeatedContainer_ToList(PyObject* _self) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  upb_Array* arr = PyUpb_RepeatedContainer_GetIfReified(self);
  if (!arr) return PyList_New(0);

  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  size_t n = upb_Array_Size(arr);
  PyObject* list = PyList_New(n);
  for (size_t i = 0; i < n; i++) {
    PyObject* val = PyUpb_UpbToPy(upb_Array_Get(arr, i), f, self->arena);
    if (!val) {
      Py_DECREF(list);
      return NULL;
    }
    PyList_SetItem(list, i, val);
  }
  return list;
}

static PyObject* PyUpb_RepeatedContainer_Repr(PyObject* _self) {
  PyObject* list = PyUpb_RepeatedContainer_ToList(_self);
  if (!list) return NULL;
  assert(!PyErr_Occurred());
  PyObject* repr = PyObject_Repr(list);
  Py_DECREF(list);
  return repr;
}

static PyObject* PyUpb_RepeatedContainer_RichCompare(PyObject* _self,
                                                     PyObject* _other,
                                                     int opid) {
  if (opid != Py_EQ && opid != Py_NE) {
    Py_INCREF(Py_NotImplemented);
    return Py_NotImplemented;
  }
  PyObject* list1 = PyUpb_RepeatedContainer_ToList(_self);
  PyObject* list2 = _other;
  PyObject* del = NULL;
  if (PyObject_TypeCheck(_other, _self->ob_type)) {
    del = list2 = PyUpb_RepeatedContainer_ToList(_other);
  }
  PyObject* ret = PyObject_RichCompare(list1, list2, opid);
  Py_DECREF(list1);
  Py_XDECREF(del);
  return ret;
}

static PyObject* PyUpb_RepeatedContainer_Subscript(PyObject* _self,
                                                   PyObject* key) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  upb_Array* arr = PyUpb_RepeatedContainer_GetIfReified(self);
  Py_ssize_t size = arr ? upb_Array_Size(arr) : 0;
  Py_ssize_t idx, count, step;
  if (!PyUpb_IndexToRange(key, size, &idx, &count, &step)) return NULL;
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  if (step == 0) {
    return PyUpb_UpbToPy(upb_Array_Get(arr, idx), f, self->arena);
  } else {
    PyObject* list = PyList_New(count);
    for (Py_ssize_t i = 0; i < count; i++, idx += step) {
      upb_MessageValue msgval = upb_Array_Get(self->ptr.arr, idx);
      PyObject* item = PyUpb_UpbToPy(msgval, f, self->arena);
      if (!item) {
        Py_DECREF(list);
        return NULL;
      }
      PyList_SetItem(list, i, item);
    }
    return list;
  }
}

typedef struct {
  upb_Array* arr;
  upb_Arena* arena;
  Py_ssize_t index;
  Py_ssize_t step;
  Py_ssize_t count;
} PyUpb_SetSubscriptCtx;

static bool PyUpb_SetSubscriptSizeCb(Py_ssize_t seq_size, void* vctx) {
  PyUpb_SetSubscriptCtx* ctx = (PyUpb_SetSubscriptCtx*)vctx;
  if (seq_size != ctx->count) {
    if (ctx->step == 1) {
      // We must shift the tail elements (either right or left).
      size_t tail = upb_Array_Size(ctx->arr) - (ctx->index + ctx->count);
      if (!upb_Array_Resize(ctx->arr, ctx->index + seq_size + tail,
                            ctx->arena)) {
        PyErr_SetNone(PyExc_MemoryError);
        return false;
      }
      upb_Array_Move(ctx->arr, ctx->index + seq_size, ctx->index + ctx->count,
                     tail);
      ctx->count = seq_size;
    } else {
      PyErr_Format(PyExc_ValueError,
                   "attempt to assign sequence of  %zd to extended slice "
                   "of size %zd",
                   seq_size, ctx->count);
      return false;
    }
  }
  return true;
}

static bool PyUpb_SetSubscriptElemCb(upb_MessageValue val, void* vctx) {
  PyUpb_SetSubscriptCtx* ctx = (PyUpb_SetSubscriptCtx*)vctx;
  upb_Array_Set(ctx->arr, ctx->index, val);
  ctx->index += ctx->step;
  return true;
}

static void PyUpb_Reverse(char* start, char* end, size_t itemsize) {
  char tmp[16];
  assert(itemsize <= sizeof(tmp));
  while (start < end) {
    memcpy(tmp, start, itemsize);
    memcpy(start, end, itemsize);
    memcpy(end, tmp, itemsize);
    start += itemsize;
    end -= itemsize;
  }
}

static void PyUpb_Rotate(char* first, char* middle, char* last,
                         size_t itemsize) {
  if (first == middle || middle == last) return;
  PyUpb_Reverse(first, middle - itemsize, itemsize);
  PyUpb_Reverse(middle, last - itemsize, itemsize);
  PyUpb_Reverse(first, last - itemsize, itemsize);
}

static bool PyUpb_SetSubscriptBulkCb(const void* data, Py_ssize_t count,
                                     Py_ssize_t itemsize, void* vctx) {
  PyUpb_SetSubscriptCtx* ctx = (PyUpb_SetSubscriptCtx*)vctx;
  PyUpb_OverlapType overlap =
      PyUpb_ArrayOverlaps(ctx->arr, data, count, itemsize);

  if (overlap == kOverlap) {
    PyErr_SetString(PyExc_ValueError,
                    "Assigning with overlapping sequence not supported");
    return false;
  }

  size_t old_size = upb_Array_Size(ctx->arr);
  size_t tail = old_size - (ctx->index + ctx->count);
  char* dst = upb_Array_MutableDataPtr(ctx->arr);
  char* target = dst + ctx->index * itemsize;

  if (overlap == kDisjoint) {
    if (count != ctx->count) {
      if (ctx->step != 1) {
        PyErr_Format(
            PyExc_ValueError,
            "attempt to assign sequence of %zd to extended slice of size %zd",
            count, ctx->count);
        return false;
      }
      if (!upb_Array_Resize(ctx->arr, ctx->index + count + tail, ctx->arena)) {
        PyErr_SetNone(PyExc_MemoryError);
        return false;
      }
      dst = upb_Array_MutableDataPtr(ctx->arr);
      upb_Array_Move(ctx->arr, ctx->index + count, ctx->index + ctx->count,
                     tail);
    }
    if (ctx->step == 1) {
      memcpy(dst + ctx->index * itemsize, data, count * itemsize);
    } else {
      const char* src = (const char*)data;
      for (Py_ssize_t i = 0; i < count; i++) {
        memcpy(dst + (ctx->index + i * ctx->step) * itemsize,
               src + i * itemsize, itemsize);
      }
    }
    return true;
  }

  if (count != ctx->count && ctx->step != 1) {
    PyErr_Format(
        PyExc_ValueError,
        "attempt to assign sequence of %zd to extended slice of size %zd",
        count, ctx->count);
    return false;
  }

  // Fast paths for subset assignment when not growing the array
  // (count <= ctx->count).
  if (count <= ctx->count) {
    if (data != target) {
      memmove(target, data, count * itemsize);
    }
    if (count < ctx->count) {
      upb_Array_Move(ctx->arr, ctx->index + count, ctx->index + ctx->count,
                     tail);
      bool ok =
          upb_Array_Resize(ctx->arr, ctx->index + count + tail, ctx->arena);
      UPB_UNUSED(ok);
    }
    return true;
  }

  // General case (growing subset assignment: append + rotate + memmove +
  // truncate).

  // Append to the end of the array.
  char* old_dst = upb_Array_MutableDataPtr(ctx->arr);
  if (!upb_Array_Resize(ctx->arr, old_size + count, ctx->arena)) {
    PyErr_SetNone(PyExc_MemoryError);
    return false;
  }
  dst = upb_Array_MutableDataPtr(ctx->arr);
  if (old_dst != dst) {
    data = dst + ((const char*)data - old_dst);
  }
  memcpy(dst + old_size * itemsize, data, count * itemsize);

  //
  if (ctx->step == 1) {
    char* first = dst + (ctx->index + ctx->count) * itemsize;
    char* middle = dst + old_size * itemsize;
    char* last = dst + (old_size + count) * itemsize;

    PyUpb_Rotate(first, middle, last, itemsize);

    if (ctx->count > 0) {
      memmove(dst + ctx->index * itemsize,
              dst + (ctx->index + ctx->count) * itemsize,
              (count + tail) * itemsize);
    }
  } else {
    const char* src = dst + old_size * itemsize;
    for (Py_ssize_t i = 0; i < count; i++) {
      memcpy(dst + (ctx->index + i * ctx->step) * itemsize, src + i * itemsize,
             itemsize);
    }
  }

  bool ok = upb_Array_Resize(ctx->arr, ctx->index + count + tail, ctx->arena);
  UPB_UNUSED(ok);
  return true;
}

static int PyUpb_RepeatedContainer_SetSubscript(
    PyUpb_RepeatedContainer* self, upb_Array* arr, const upb_FieldDef* f,
    Py_ssize_t idx, Py_ssize_t count, Py_ssize_t step, PyObject* value) {
  upb_Arena* arena = PyUpb_Arena_Get(self->arena);
  if (upb_FieldDef_IsSubMessage(f)) {
    PyErr_SetString(PyExc_TypeError, "does not support assignment");
    return -1;
  }

  if (step == 0) {
    // Set single value.
    upb_MessageValue msgval;
    if (!PyUpb_PyToUpb(value, f, &msgval, arena)) return -1;
    upb_Array_Set(arr, idx, msgval);
    return 0;
  }
  Py_ssize_t old_size = (Py_ssize_t)upb_Array_Size(arr);
  Py_ssize_t tail = old_size - (idx + count);
  if (step == 1 && count == 0 && tail == 0) {
    PyObject* ret = PyUpb_RepeatedContainer_Extend((PyObject*)self, value);
    if (!ret) return -1;
    Py_DECREF(ret);
    return 0;
  }
  PyUpb_SetSubscriptCtx ctx = {arr, arena, idx, step, count};
  if (!PyUpb_IterInput(value, f, arena, PyUpb_SetSubscriptSizeCb,
                       PyUpb_SetSubscriptElemCb, PyUpb_SetSubscriptBulkCb,
                       &ctx)) {
    return -1;
  }
  return 0;
}

static int PyUpb_RepeatedContainer_DeleteSubscript(upb_Array* arr,
                                                   Py_ssize_t idx,
                                                   Py_ssize_t count,
                                                   Py_ssize_t step) {
  // Normalize direction: deletion is order-independent.
  Py_ssize_t start = idx;
  if (step < 0) {
    Py_ssize_t end = start + step * (count - 1);
    start = end;
    step = -step;
  }

  size_t dst = start;
  size_t src;
  if (step > 1) {
    // Move elements between steps:
    //
    //        src
    //         |
    // |------X---X---X---X------------------------------|
    //        |
    //       dst           <-------- tail -------------->
    src = start + 1;
    for (Py_ssize_t i = 1; i < count; i++, dst += step - 1, src += step) {
      upb_Array_Move(arr, dst, src, step);
    }
  } else {
    src = start + count;
  }

  // Move tail.
  size_t tail = upb_Array_Size(arr) - src;
  size_t new_size = dst + tail;
  assert(new_size == upb_Array_Size(arr) - count);
  upb_Array_Move(arr, dst, src, tail);
  bool ok = upb_Array_Resize(arr, new_size, NULL);
  UPB_UNUSED(ok);
  return 0;
}

static int PyUpb_RepeatedContainer_AssignSubscript(PyObject* _self,
                                                   PyObject* key,
                                                   PyObject* value) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  upb_Array* arr = PyUpb_RepeatedContainer_AssureWritable(_self);
  if (!arr) return -1;
  Py_ssize_t size = arr ? upb_Array_Size(arr) : 0;
  Py_ssize_t idx, count, step;
  if (!PyUpb_IndexToRange(key, size, &idx, &count, &step)) return -1;
  if (value) {
    return PyUpb_RepeatedContainer_SetSubscript(self, arr, f, idx, count, step,
                                                value);
  } else {
    return PyUpb_RepeatedContainer_DeleteSubscript(arr, idx, count, step);
  }
}

static PyObject* PyUpb_RepeatedContainer_Pop(PyObject* _self, PyObject* args) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  Py_ssize_t index = -1;
  if (!PyArg_ParseTuple(args, "|n", &index)) return NULL;
  upb_Array* arr = PyUpb_RepeatedContainer_AssureWritable(_self);
  if (!arr) return NULL;
  size_t size = upb_Array_Size(arr);
  if (index < 0) index += size;
#if PROTOBUF_PY_FUTURE_REMOVE_POP_CLAMP
#else
  if (index >= size) {
    PyErr_WarnEx(PyExc_FutureWarning, "pop index out of range", 1);
    index = size - 1;
  }
#endif  // PROTOBUF_PY_FUTURE_REMOVE_POP_CLAMP
  PyObject* ret = PyUpb_RepeatedContainer_Item(_self, index);
  if (!ret) return NULL;
  upb_Array_Delete(self->ptr.arr, index, 1);
  return ret;
}

static PyObject* PyUpb_RepeatedContainer_Remove(PyObject* _self,
                                                PyObject* value) {
  upb_Array* arr = PyUpb_RepeatedContainer_AssureWritable(_self);
  if (!arr) return NULL;
  Py_ssize_t match_index = -1;
  Py_ssize_t n = PyUpb_RepeatedContainer_Length(_self);
  for (Py_ssize_t i = 0; i < n; ++i) {
    PyObject* elem = PyUpb_RepeatedContainer_Item(_self, i);
    if (!elem) return NULL;
    int eq = PyObject_RichCompareBool(elem, value, Py_EQ);
    Py_DECREF(elem);
    if (eq) {
      match_index = i;
      break;
    }
  }
  if (match_index == -1) {
    PyErr_SetString(PyExc_ValueError, "remove(x): x not in container");
    return NULL;
  }
  if (PyUpb_RepeatedContainer_DeleteSubscript(arr, match_index, 1, 1) < 0) {
    return NULL;
  }
  Py_RETURN_NONE;
}

// A helper function used only for Sort().
static bool PyUpb_RepeatedContainer_Assign(PyObject* _self, PyObject* list) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  upb_Array* arr = PyUpb_RepeatedContainer_AssureWritable(_self);
  Py_ssize_t size = PyList_Size(list);
  bool submsg = upb_FieldDef_IsSubMessage(f);
  upb_Arena* arena = PyUpb_Arena_Get(self->arena);
  for (Py_ssize_t i = 0; i < size; ++i) {
    PyObject* obj = PyList_GetItem(list, i);
    upb_MessageValue msgval;
    if (submsg) {
      msgval.msg_val = PyUpb_Message_GetIfReified(obj);
      assert(msgval.msg_val);
    } else {
      if (!PyUpb_PyToUpb(obj, f, &msgval, arena)) return false;
    }
    upb_Array_Set(arr, i, msgval);
  }
  return true;
}

static PyObject* PyUpb_RepeatedContainer_Sort(PyObject* pself, PyObject* args,
                                              PyObject* kwds) {
  // Support the old sort_function argument for backwards
  // compatibility.
  if (kwds != NULL) {
    PyObject* sort_func = PyDict_GetItemString(kwds, "sort_function");
    if (sort_func != NULL) {
      // Must set before deleting as sort_func is a borrowed reference
      // and kwds might be the only thing keeping it alive.
      if (PyDict_SetItemString(kwds, "cmp", sort_func) == -1) return NULL;
      if (PyDict_DelItemString(kwds, "sort_function") == -1) return NULL;
    }
  }

  if (PyUpb_RepeatedContainer_IsFrozen((PyUpb_RepeatedContainer*)pself)) {
    if (!PyUpb_CheckFrozen(true, "Container is immutable")) {
      return NULL;
    }
  }

  // TODO:b/517235198 - Reify even for empty sequences.
  if (PyUpb_RepeatedContainer_Length(pself) == 0) Py_RETURN_NONE;

  upb_Array* arr = PyUpb_RepeatedContainer_AssureWritable(pself);
  if (!arr) return NULL;

  PyObject* ret = NULL;
  PyObject* full_slice = NULL;
  PyObject* list = NULL;
  PyObject* m = NULL;
  PyObject* res = NULL;

  if ((full_slice = PySlice_New(NULL, NULL, NULL)) &&
      (list = PyUpb_RepeatedContainer_Subscript(pself, full_slice)) &&
      (m = PyObject_GetAttrString(list, "sort")) &&
      (res = PyObject_Call(m, args, kwds)) &&
      PyUpb_RepeatedContainer_Assign(pself, list)) {
    Py_INCREF(Py_None);
    ret = Py_None;
  }

  Py_XDECREF(full_slice);
  Py_XDECREF(list);
  Py_XDECREF(m);
  Py_XDECREF(res);
  return ret;
}

static PyObject* PyUpb_RepeatedContainer_Reverse(PyObject* _self) {
  upb_Array* arr = PyUpb_RepeatedContainer_AssureWritable(_self);
  if (!arr) return NULL;
  size_t n = upb_Array_Size(arr);
  size_t half = n / 2;  // Rounds down.
  for (size_t i = 0; i < half; i++) {
    size_t i2 = n - i - 1;
    upb_MessageValue val1 = upb_Array_Get(arr, i);
    upb_MessageValue val2 = upb_Array_Get(arr, i2);
    upb_Array_Set(arr, i, val2);
    upb_Array_Set(arr, i2, val1);
  }
  Py_RETURN_NONE;
}

static PyObject* PyUpb_RepeatedContainer_Clear(PyObject* _self) {
  Py_ssize_t size = PyUpb_RepeatedContainer_Length(_self);
  // TODO: b/517235198 - Reify even for empty sequences.
  if (size == 0) Py_RETURN_NONE;

  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  upb_Array* arr = PyUpb_RepeatedContainer_AssureWritable(_self);
  if (!arr) return NULL;
  upb_Array_Delete(self->ptr.arr, 0, size);
  Py_RETURN_NONE;
}

static PyObject* PyUpb_RepeatedContainer_MergeFrom(PyObject* _self,
                                                   PyObject* args) {
  return PyUpb_RepeatedContainer_Extend(_self, args);
}

// -----------------------------------------------------------------------------
// RepeatedCompositeContainer
// -----------------------------------------------------------------------------

static PyObject* PyUpb_RepeatedCompositeContainer_AppendNew(PyObject* _self) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  upb_Array* arr = PyUpb_RepeatedContainer_AssureWritable(_self);
  if (!arr) return NULL;
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  upb_Arena* arena = PyUpb_Arena_Get(self->arena);
  const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f);
  const upb_MiniTable* layout = upb_MessageDef_MiniTable(m);
  upb_Message* msg = upb_Message_New(layout, arena);
  if (!msg) {
    PyErr_SetNone(PyExc_MemoryError);
    return NULL;
  }
  upb_MessageValue msgval = {.msg_val = msg};
  if (!upb_Array_Append(arr, msgval, arena)) {
    PyErr_SetNone(PyExc_MemoryError);
    return NULL;
  }
  return PyUpb_Message_Get(msg, m, self->arena);
}

PyObject* PyUpb_RepeatedCompositeContainer_Add(PyObject* _self, PyObject* args,
                                               PyObject* kwargs) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  PyObject* py_msg = PyUpb_RepeatedCompositeContainer_AppendNew(_self);
  if (!py_msg) return NULL;
  if (PyUpb_Message_InitAttributes(py_msg, args, kwargs) < 0) {
    Py_DECREF(py_msg);
    upb_Array_Delete(self->ptr.arr, upb_Array_Size(self->ptr.arr) - 1, 1);
    return NULL;
  }
  return py_msg;
}

static PyObject* PyUpb_RepeatedCompositeContainer_Append(PyObject* _self,
                                                         PyObject* value) {
  if (!PyUpb_Message_Verify(value)) return NULL;
  PyObject* py_msg = PyUpb_RepeatedCompositeContainer_AppendNew(_self);
  if (!py_msg) return NULL;
  PyObject* none = PyUpb_Message_MergeFrom(py_msg, value);
  if (!none) {
    Py_DECREF(py_msg);
    return NULL;
  }
  Py_DECREF(none);
  return py_msg;
}

static PyObject* PyUpb_RepeatedContainer_Insert(PyObject* _self,
                                                PyObject* args) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  Py_ssize_t index;
  PyObject* value;
  if (!PyArg_ParseTuple(args, "nO", &index, &value)) return NULL;
  upb_Array* arr = PyUpb_RepeatedContainer_AssureWritable(_self);
  if (!arr) return NULL;

  // Normalize index.
  Py_ssize_t size = upb_Array_Size(arr);
  if (index < 0) index += size;
  if (index < 0) index = 0;
  if (index > size) index = size;

  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  upb_MessageValue msgval;
  upb_Arena* arena = PyUpb_Arena_Get(self->arena);
  if (upb_FieldDef_IsSubMessage(f)) {
    // Create message.
    const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f);
    const upb_MiniTable* layout = upb_MessageDef_MiniTable(m);
    upb_Message* msg = upb_Message_New(layout, arena);
    if (!msg) {
      PyErr_SetNone(PyExc_MemoryError);
      return NULL;
    }
    PyObject* py_msg = PyUpb_Message_Get(msg, m, self->arena);
    PyObject* ret = PyUpb_Message_MergeFrom(py_msg, value);
    Py_DECREF(py_msg);
    if (!ret) return NULL;
    Py_DECREF(ret);
    msgval.msg_val = msg;
  } else {
    if (!PyUpb_PyToUpb(value, f, &msgval, arena)) return NULL;
  }

  if (!upb_Array_Insert(arr, index, 1, arena)) {
    PyErr_SetNone(PyExc_MemoryError);
    return NULL;
  }
  upb_Array_Set(arr, index, msgval);

  Py_RETURN_NONE;
}

static PyMethodDef PyUpb_RepeatedCompositeContainer_Methods[] = {
    {"__deepcopy__", PyUpb_RepeatedContainer_DeepCopy, METH_VARARGS,
     "Makes a deep copy of the class."},
    {"add", (PyCFunction)PyUpb_RepeatedCompositeContainer_Add,
     METH_VARARGS | METH_KEYWORDS, "Adds an object to the repeated container."},
    {"append", PyUpb_RepeatedCompositeContainer_Append, METH_O,
     "Appends a message to the end of the repeated container."},
    {"insert", PyUpb_RepeatedContainer_Insert, METH_VARARGS,
     "Inserts a message before the specified index."},
    {"extend", PyUpb_RepeatedContainer_Extend, METH_O,
     "Adds objects to the repeated container."},
    {"pop", PyUpb_RepeatedContainer_Pop, METH_VARARGS,
     "Removes an object from the repeated container and returns it."},
    {"remove", PyUpb_RepeatedContainer_Remove, METH_O,
     "Removes an object from the repeated container."},
    {"sort", (PyCFunction)PyUpb_RepeatedContainer_Sort,
     METH_VARARGS | METH_KEYWORDS, "Sorts the repeated container."},
    {"reverse", (PyCFunction)PyUpb_RepeatedContainer_Reverse, METH_NOARGS,
     "Reverses elements order of the repeated container."},
    {"clear", (PyCFunction)PyUpb_RepeatedContainer_Clear, METH_NOARGS,
     "Clears repeated container."},
    {"MergeFrom", PyUpb_RepeatedContainer_MergeFrom, METH_O,
     "Adds objects to the repeated container."},
    {NULL, NULL}};

static PyType_Slot PyUpb_RepeatedCompositeContainer_Slots[] = {
    {Py_tp_dealloc, PyUpb_RepeatedContainer_Dealloc},
    {Py_tp_methods, PyUpb_RepeatedCompositeContainer_Methods},
    {Py_sq_length, PyUpb_RepeatedContainer_Length},
    {Py_sq_item, PyUpb_RepeatedContainer_Item},
    {Py_mp_length, PyUpb_RepeatedContainer_Length},
    {Py_tp_repr, PyUpb_RepeatedContainer_Repr},
    {Py_mp_subscript, PyUpb_RepeatedContainer_Subscript},
    {Py_mp_ass_subscript, PyUpb_RepeatedContainer_AssignSubscript},
    {Py_tp_new, PyUpb_Forbidden_New},
    {Py_tp_richcompare, PyUpb_RepeatedContainer_RichCompare},
    {Py_tp_hash, PyObject_HashNotImplemented},
    {0, NULL}};

static PyType_Spec PyUpb_RepeatedCompositeContainer_Spec = {
    PYUPB_MODULE_NAME ".RepeatedCompositeContainer",
    sizeof(PyUpb_RepeatedContainer),
    0,  // tp_itemsize
    Py_TPFLAGS_DEFAULT,
    PyUpb_RepeatedCompositeContainer_Slots,
};

// -----------------------------------------------------------------------------
// RepeatedScalarContainer
// -----------------------------------------------------------------------------

static PyObject* PyUpb_RepeatedScalarContainer_Append(PyObject* _self,
                                                      PyObject* value) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  upb_Array* arr = PyUpb_RepeatedContainer_AssureWritable(_self);
  if (!arr) return NULL;
  upb_Arena* arena = PyUpb_Arena_Get(self->arena);
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  upb_MessageValue msgval;
  if (!PyUpb_PyToUpb(value, f, &msgval, arena)) {
    return NULL;
  }
  if (!upb_Array_Append(arr, msgval, arena)) {
    PyErr_SetNone(PyExc_MemoryError);
    return NULL;
  }
  Py_RETURN_NONE;
}

static int PyUpb_RepeatedScalarContainer_AssignItem(PyObject* _self,
                                                    Py_ssize_t index,
                                                    PyObject* item) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  upb_Array* arr = PyUpb_RepeatedContainer_AssureWritable(_self);
  if (!arr) return -1;
  Py_ssize_t size = upb_Array_Size(arr);
  if (index < 0 || index >= size) {
    PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index);
    return -1;
  }
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  upb_MessageValue msgval;
  upb_Arena* arena = PyUpb_Arena_Get(self->arena);
  if (!PyUpb_PyToUpb(item, f, &msgval, arena)) {
    return -1;
  }
  upb_Array_Set(self->ptr.arr, index, msgval);
  return 0;
}

static PyObject* PyUpb_RepeatedScalarContainer_Reduce(PyObject* unused_self,
                                                      PyObject* unused_other) {
  PyObject* pickle_module = PyImport_ImportModule("pickle");
  if (!pickle_module) return NULL;
  PyObject* pickle_error = PyObject_GetAttrString(pickle_module, "PickleError");
  Py_DECREF(pickle_module);
  if (!pickle_error) return NULL;
  PyErr_Format(pickle_error,
               "can't pickle repeated message fields, convert to list first");
  Py_DECREF(pickle_error);
  return NULL;
}

char* GetDefaultDTypeStr(upb_CType cpp_type) {
  switch (cpp_type) {
    case kUpb_CType_Float:
      return "f4";
    case kUpb_CType_Int32:
      return "i4";
    case kUpb_CType_Int64:
      return "i8";
    case kUpb_CType_UInt32:
      return "u4";
    case kUpb_CType_UInt64:
      return "u8";
    case kUpb_CType_Double:
      return "f8";
    case kUpb_CType_Bool:
      return "?";  // Boolean is '?' per official docs.
    case kUpb_CType_Enum:
      return "i4";
    case kUpb_CType_String:
    case kUpb_CType_Bytes:
    case kUpb_CType_Message:
      return NULL;
  }
  return NULL;
}

PyObject* CreateArrayFromView(PyObject* _self, PyObject* np_module) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)(_self);
  upb_Array* arr = PyUpb_RepeatedContainer_GetIfReified(self);
  size_t size = arr ? upb_Array_Size(arr) : 0;
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  Py_ssize_t out_buffer_size_bytes;
  const char* out_dtype = GetDefaultDTypeStr(upb_FieldDef_CType(f));
  switch (upb_FieldDef_CType(f)) {
    case kUpb_CType_Float: {
      out_buffer_size_bytes = sizeof(float) * size;
      break;
    }
    case kUpb_CType_Int32: {
      out_buffer_size_bytes = 4 * size;
      break;
    }
    case kUpb_CType_Int64: {
      out_buffer_size_bytes = 8 * size;
      break;
    }
    case kUpb_CType_UInt32: {
      out_buffer_size_bytes = 4 * size;
      break;
    }
    case kUpb_CType_UInt64: {
      out_buffer_size_bytes = 8 * size;
      break;
    }
    case kUpb_CType_Double: {
      out_buffer_size_bytes = sizeof(double) * size;
      break;
    }
    case kUpb_CType_Bool: {
      out_buffer_size_bytes = sizeof(bool) * size;
      break;
    }
    case kUpb_CType_Enum: {
      out_buffer_size_bytes = 4 * size;
      break;
    }
    case kUpb_CType_Message:
    case kUpb_CType_Bytes:
    case kUpb_CType_String: {
      PyErr_Format(PyExc_SystemError,
                   "Code should never reach here: cpp type "
                   "should not be message nor string in CreateArrayFromView.");
      return NULL;
    }
  }
  if (out_buffer_size_bytes == 0) {
    return PyObject_CallMethod(np_module, "empty", "is", 0, out_dtype);
  }
  const void* out_ptr = upb_Array_DataPtr(arr);
  PyObject* view = PyMemoryView_FromMemory(
      (char*)(const char*)out_ptr, out_buffer_size_bytes, 0x100 /*PyBUF_READ*/);
  PyObject* return_value =
      PyObject_CallMethod(np_module, "frombuffer", "Os", view, out_dtype);
  Py_DECREF(view);
  return return_value;
}

// CPython equivalent of nparray.astype(dtype_requested, copy=copy).
PyObject* NpArrayAsType(PyObject* nparray, PyObject* dtype_requested,
                        bool copy) {
  PyObject* astype_args = Py_BuildValue("(O)", dtype_requested);
  PyObject* keywords = PyDict_New();
  PyDict_SetItemString(keywords, "copy", copy ? Py_True : Py_False);
  PyObject* np_array_astype = PyObject_GetAttrString(nparray, "astype");

  PyObject* return_value =
      PyObject_Call(np_array_astype, astype_args, keywords);
  Py_DECREF(np_array_astype);
  Py_DECREF(keywords);
  Py_DECREF(astype_args);
  return return_value;
}

PyObject* ConstructArrayByIteration(PyObject* _self, PyObject* np_module) {
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
  upb_Array* arr = PyUpb_RepeatedContainer_GetIfReified(self);
  Py_ssize_t array_length = PyUpb_RepeatedContainer_Length(_self);
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  PyObject* nparray =
      PyObject_CallMethod(np_module, "empty", "is", array_length, "O");
  PyObject* arena = self->arena;
  for (Py_ssize_t i = 0; i < array_length; ++i) {
    upb_MessageValue msgval = upb_Array_Get(arr, i);
    PyObject* item = PyUpb_UpbToPy(msgval, f, arena);
    PySequence_SetItem(nparray, i, item);
    Py_DECREF(item);
  }
  return nparray;
}

static PyObject* PyUpb_RepeatedScalarContainer_AsNpArray(PyObject* _self,
                                                         PyObject* args,
                                                         PyObject* kwargs) {
  static const char* kwlist[] = {"dtype", "copy", NULL};
  PyObject* dtype_requested = NULL;
  PyObject* copy = NULL;
  PyObject* return_value = NULL;
  PyObject* default_dtype = NULL;
  PyObject* nparray = NULL;
  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", (char**)kwlist,
                                   &dtype_requested, &copy)) {
    return NULL;
  }

  PyObject* np_module = PyImport_ImportModule("numpy");
  if (np_module == NULL) {
    PyErr_Format(PyExc_ImportError, "Unable to import numpy.");
    return NULL;
  }
  PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)(_self);
  const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
  upb_CType c_type = upb_FieldDef_CType(f);

  // string repeated
  if (c_type == kUpb_CType_String || c_type == kUpb_CType_Bytes) {
    nparray = ConstructArrayByIteration(_self, np_module);
    if (dtype_requested == NULL) {
      if (c_type == kUpb_CType_String) {
        dtype_requested = PyObject_CallMethod(np_module, "dtype", "s", "str");
      } else {
        dtype_requested = PyObject_CallMethod(np_module, "dtype", "s", "S");
      }
      default_dtype = dtype_requested;
    }
    return_value = NpArrayAsType(nparray, dtype_requested, false);
    goto ret;
  }

  // non-string scalar repeated
  if (dtype_requested == NULL) {
    char* returned_dtype = GetDefaultDTypeStr(c_type);
    if (returned_dtype == NULL) {
      PyErr_SetString(PyExc_SystemError,
                      "Implementation error: Unhandled case in AsNpArray.");
      return NULL;
    }
    if (PyUpb_RepeatedContainer_Length(_self) == 0) {
      return_value =
          PyObject_CallMethod(np_module, "empty", "is", 0, returned_dtype);
      goto ret;
    }

    dtype_requested =
        PyObject_CallMethod(np_module, "dtype", "s", returned_dtype);
    // For ref-counting.
    default_dtype = dtype_requested;
  }
  nparray = CreateArrayFromView(_self, np_module);
  if (nparray == NULL) {
    goto ret;
  }

  return_value = NpArrayAsType(nparray, dtype_requested, true);

ret:
  Py_XDECREF(default_dtype);
  Py_XDECREF(nparray);
  Py_DECREF(np_module);
  return return_value;
}

static PyMethodDef PyUpb_RepeatedScalarContainer_Methods[] = {
    {"__deepcopy__", PyUpb_RepeatedContainer_DeepCopy, METH_VARARGS,
     "Makes a deep copy of the class."},
    {"__array__", (PyCFunction)PyUpb_RepeatedScalarContainer_AsNpArray,
     METH_VARARGS | METH_KEYWORDS, "Returns a np.array."},
    {"__reduce__", PyUpb_RepeatedScalarContainer_Reduce, METH_NOARGS,
     "Outputs picklable representation of the repeated field."},
    {"append", PyUpb_RepeatedScalarContainer_Append, METH_O,
     "Appends an object to the repeated container."},
    {"extend", PyUpb_RepeatedContainer_Extend, METH_O,
     "Appends objects to the repeated container."},
    {"insert", PyUpb_RepeatedContainer_Insert, METH_VARARGS,
     "Inserts an object at the specified position in the container."},
    {"pop", PyUpb_RepeatedContainer_Pop, METH_VARARGS,
     "Removes an object from the repeated container and returns it."},
    {"remove", PyUpb_RepeatedContainer_Remove, METH_O,
     "Removes an object from the repeated container."},
    {"sort", (PyCFunction)PyUpb_RepeatedContainer_Sort,
     METH_VARARGS | METH_KEYWORDS, "Sorts the repeated container."},
    {"reverse", (PyCFunction)PyUpb_RepeatedContainer_Reverse, METH_NOARGS,
     "Reverses elements order of the repeated container."},
    {"clear", (PyCFunction)PyUpb_RepeatedContainer_Clear, METH_NOARGS,
     "Clears repeated container."},
    {"MergeFrom", PyUpb_RepeatedContainer_MergeFrom, METH_O,
     "Merges a repeated container into the current container."},
    {NULL, NULL}};

static PyType_Slot PyUpb_RepeatedScalarContainer_Slots[] = {
    {Py_tp_dealloc, PyUpb_RepeatedContainer_Dealloc},
    {Py_tp_methods, PyUpb_RepeatedScalarContainer_Methods},
    {Py_tp_new, PyUpb_Forbidden_New},
    {Py_tp_repr, PyUpb_RepeatedContainer_Repr},
    {Py_sq_length, PyUpb_RepeatedContainer_Length},
    {Py_sq_item, PyUpb_RepeatedContainer_Item},
    {Py_sq_ass_item, PyUpb_RepeatedScalarContainer_AssignItem},
    {Py_mp_length, PyUpb_RepeatedContainer_Length},
    {Py_mp_subscript, PyUpb_RepeatedContainer_Subscript},
    {Py_mp_ass_subscript, PyUpb_RepeatedContainer_AssignSubscript},
    {Py_tp_richcompare, PyUpb_RepeatedContainer_RichCompare},
    {Py_tp_hash, PyObject_HashNotImplemented},
    {0, NULL}};

static PyType_Spec PyUpb_RepeatedScalarContainer_Spec = {
    PYUPB_MODULE_NAME ".RepeatedScalarContainer",
    sizeof(PyUpb_RepeatedContainer),
    0,  // tp_itemsize
    Py_TPFLAGS_DEFAULT,
    PyUpb_RepeatedScalarContainer_Slots,
};

// -----------------------------------------------------------------------------
// Top Level
// -----------------------------------------------------------------------------

static bool PyUpb_Repeated_RegisterAsSequence(PyUpb_ModuleState* state) {
  PyObject* collections = NULL;
  PyObject* seq = NULL;
  PyObject* ret1 = NULL;
  PyObject* ret2 = NULL;
  PyTypeObject* type1 = state->repeated_scalar_container_type;
  PyTypeObject* type2 = state->repeated_composite_container_type;

  bool ok = (collections = PyImport_ImportModule("collections.abc")) &&
            (seq = PyObject_GetAttrString(collections, "MutableSequence")) &&
            (ret1 = PyObject_CallMethod(seq, "register", "O", type1)) &&
            (ret2 = PyObject_CallMethod(seq, "register", "O", type2));

  Py_XDECREF(collections);
  Py_XDECREF(seq);
  Py_XDECREF(ret1);
  Py_XDECREF(ret2);
  return ok;
}

bool PyUpb_Repeated_Init(PyObject* m) {
  PyUpb_ModuleState* state = PyUpb_ModuleState_GetFromModule(m);

  state->repeated_composite_container_type =
      PyUpb_AddClass(m, &PyUpb_RepeatedCompositeContainer_Spec);
  state->repeated_scalar_container_type =
      PyUpb_AddClass(m, &PyUpb_RepeatedScalarContainer_Spec);

  return state->repeated_composite_container_type &&
         state->repeated_scalar_container_type &&
         PyUpb_Repeated_RegisterAsSequence(state);
}

#include "upb/port/undef.inc"
