// 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

/*
 * lupb_Message -- Message/Array/Map objects in Lua/C that wrap upb
 */

#include <float.h>
#include <math.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

#include "lauxlib.h"
#include "lua/upb.h"
#include "upb/json/decode.h"
#include "upb/json/encode.h"
#include "upb/message/map.h"
#include "upb/message/message.h"
#include "upb/port/def.inc"
#include "upb/reflection/message.h"
#include "upb/text/encode.h"

/*
 * Message/Map/Array objects.  These objects form a directed graph: a message
 * can contain submessages, arrays, and maps, which can then point to other
 * messages.  This graph can technically be cyclic, though this is an error and
 * a cyclic graph cannot be serialized.  So it's better to think of this as a
 * tree of objects.
 *
 * The actual data exists at the upb level (upb_Message, upb_Map, upb_Array),
 * independently of Lua.  The upb objects contain all the canonical data and
 * edges between objects.  Lua wrapper objects expose the upb objects to Lua,
 * but ultimately they are just wrappers.  They pass through all reads and
 * writes to the underlying upb objects.
 *
 * Each upb object lives in a upb arena.  We have a Lua object to wrap the upb
 * arena, but arenas are never exposed to the user.  The Lua arena object just
 * serves to own the upb arena and free it at the proper time, once the Lua GC
 * has determined that there are no more references to anything that lives in
 * that arena.  All wrapper objects strongly reference the arena to which they
 * belong.
 *
 * A global object cache stores a mapping of C pointer (upb_Message*,
 * upb_Array*, upb_Map*) to a corresponding Lua wrapper.  These references are
 * weak so that the wrappers can be collected if they are no longer needed.  A
 * new wrapper object can always be recreated later.
 *
 *                          +-----+
 *            lupb_Arena    |cache|-weak-+
 *                 |  ^     +-----+      |
 *                 |  |                  V
 * Lua level       |  +------------lupb_Message
 * ----------------|-----------------|------------------------------------------
 * upb level       |                 |
 *                 |            +----V----------------------------------+
 *                 +->upb_Arena | upb_Message  ...(empty arena storage) |
 *                              +---------------------------------------+
 *
 * If the user creates a reference between two objects that have different
 * arenas, we need to fuse the two arenas together, so that the blocks will
 * outlive both arenas.
 *
 *                 +-------------------------->(fused)<----------------+
 *                 |                                                   |
 *                 V                           +-----+                 V
 *            lupb_Arena                +-weak-|cache|-weak-+     lupb_Arena
 *                 |  ^                 |      +-----+      |        ^  |
 *                 |  |                 V                   V        |  |
 * Lua level       |  +------------lupb_Message        lupb_Message--+  |
 * ----------------|-----------------|----------------------|-----------|------
 * upb level       |                 |                      |           |
 *                 |            +----V--------+        +----V--------+  V
 *                 +->upb_Arena | upb_Message |        | upb_Message | upb_Arena
 *                              +------|------+        +--^----------+
 *                                     +------------------+
 * Key invariants:
 *   1. every wrapper references the arena that contains it.
 *   2. every fused arena includes all arenas that own upb objects reachable
 *      from that arena.  In other words, when a wrapper references an arena,
 *      this is sufficient to ensure that any upb object reachable from that
 *      wrapper will stay alive.
 *
 * Additionally, every message object contains a strong reference to the
 * corresponding Descriptor object.  Likewise, array/map objects reference a
 * Descriptor object if they are typed to store message values.
 */

#define LUPB_ARENA "lupb.arena"
#define LUPB_ARRAY "lupb.array"
#define LUPB_MAP "lupb.map"
#define LUPB_MSG "lupb.msg"

#define LUPB_ARENA_INDEX 1
#define LUPB_MSGDEF_INDEX 2 /* For msg, and map/array that store msg */

static void lupb_Message_Newmsgwrapper(lua_State* L, int narg,
                                       upb_MessageValue val);
static upb_Message* lupb_msg_check(lua_State* L, int narg);

static upb_CType lupb_checkfieldtype(lua_State* L, int narg) {
  uint32_t n = lupb_checkuint32(L, narg);
  bool ok = n >= kUpb_CType_Bool && n <= kUpb_CType_Bytes;
  luaL_argcheck(L, ok, narg, "invalid field type");
  return n;
}

char cache_key;

/* lupb_cacheinit()
 *
 * Creates the global cache used by lupb_cacheget() and lupb_cacheset().
 */
static void lupb_cacheinit(lua_State* L) {
  /* Create our object cache. */
  lua_newtable(L);

  /* Cache metatable gives the cache weak values */
  lua_createtable(L, 0, 1);
  lua_pushstring(L, "v");
  lua_setfield(L, -2, "__mode");
  lua_setmetatable(L, -2);

  /* Set cache in the registry. */
  lua_rawsetp(L, LUA_REGISTRYINDEX, &cache_key);
}

/* lupb_cacheget()
 *
 * Pushes cache[key] and returns true if this key is present in the cache.
 * Otherwise returns false and leaves nothing on the stack.
 */
static bool lupb_cacheget(lua_State* L, const void* key) {
  if (key == NULL) {
    lua_pushnil(L);
    return true;
  }

  lua_rawgetp(L, LUA_REGISTRYINDEX, &cache_key);
  lua_rawgetp(L, -1, key);
  if (lua_isnil(L, -1)) {
    lua_pop(L, 2); /* Pop table, nil. */
    return false;
  } else {
    lua_replace(L, -2); /* Replace cache table. */
    return true;
  }
}

/* lupb_cacheset()
 *
 * Sets cache[key] = val, where "val" is the value at the top of the stack.
 * Does not pop the value.
 */
static void lupb_cacheset(lua_State* L, const void* key) {
  lua_rawgetp(L, LUA_REGISTRYINDEX, &cache_key);
  lua_pushvalue(L, -2);
  lua_rawsetp(L, -2, key);
  lua_pop(L, 1); /* Pop table. */
}

/* lupb_Arena *****************************************************************/

/* lupb_Arena only exists to wrap a upb_Arena.  It is never exposed to users; it
 * is an internal memory management detail.  Other wrapper objects refer to this
 * object from their userdata to keep the arena-owned data alive.
 */

typedef struct {
  upb_Arena* arena;
} lupb_Arena;

static upb_Arena* lupb_Arena_check(lua_State* L, int narg) {
  lupb_Arena* a = luaL_checkudata(L, narg, LUPB_ARENA);
  return a->arena;
}

upb_Arena* lupb_Arena_pushnew(lua_State* L) {
  lupb_Arena* a = lupb_newuserdata(L, sizeof(lupb_Arena), 1, LUPB_ARENA);
  a->arena = upb_Arena_New();
  return a->arena;
}

/**
 * lupb_Arena_Fuse()
 *
 * Merges |from| into |to| so that there is a single arena group that contains
 * both, and both arenas will point at this new table. */
static void lupb_Arena_Fuse(lua_State* L, int to, int from) {
  upb_Arena* to_arena = lupb_Arena_check(L, to);
  upb_Arena* from_arena = lupb_Arena_check(L, from);
  upb_Arena_Fuse(to_arena, from_arena);
}

static void lupb_Arena_Fuseobjs(lua_State* L, int to, int from) {
  lua_getiuservalue(L, to, LUPB_ARENA_INDEX);
  lua_getiuservalue(L, from, LUPB_ARENA_INDEX);
  lupb_Arena_Fuse(L, lua_absindex(L, -2), lua_absindex(L, -1));
  lua_pop(L, 2);
}

static int lupb_Arena_gc(lua_State* L) {
  upb_Arena* a = lupb_Arena_check(L, 1);
  upb_Arena_Free(a);
  return 0;
}

static const struct luaL_Reg lupb_Arena_mm[] = {{"__gc", lupb_Arena_gc},
                                                {NULL, NULL}};

/* lupb_Arenaget()
 *
 * Returns the arena from the given message, array, or map object.
 */
static upb_Arena* lupb_Arenaget(lua_State* L, int narg) {
  upb_Arena* arena;
  lua_getiuservalue(L, narg, LUPB_ARENA_INDEX);
  arena = lupb_Arena_check(L, -1);
  lua_pop(L, 1);
  return arena;
}

/* upb <-> Lua type conversion ************************************************/

/* Whether string data should be copied into the containing arena.  We can
 * avoid a copy if the string data is only needed temporarily (like for a map
 * lookup).
 */
typedef enum {
  LUPB_COPY, /* Copy string data into the arena. */
  LUPB_REF   /* Reference the Lua copy of the string data. */
} lupb_copy_t;

/**
 * lupb_tomsgval()
 *
 * Converts the given Lua value |narg| to a upb_MessageValue.
 */
static upb_MessageValue lupb_tomsgval(lua_State* L, upb_CType type, int narg,
                                      int container, lupb_copy_t copy) {
  upb_MessageValue ret;
  switch (type) {
    case kUpb_CType_Int32:
    case kUpb_CType_Enum:
      ret.int32_val = lupb_checkint32(L, narg);
      break;
    case kUpb_CType_Int64:
      ret.int64_val = lupb_checkint64(L, narg);
      break;
    case kUpb_CType_UInt32:
      ret.uint32_val = lupb_checkuint32(L, narg);
      break;
    case kUpb_CType_UInt64:
      ret.uint64_val = lupb_checkuint64(L, narg);
      break;
    case kUpb_CType_Double:
      ret.double_val = lupb_checkdouble(L, narg);
      break;
    case kUpb_CType_Float:
      ret.float_val = lupb_checkfloat(L, narg);
      break;
    case kUpb_CType_Bool:
      ret.bool_val = lupb_checkbool(L, narg);
      break;
    case kUpb_CType_String:
    case kUpb_CType_Bytes: {
      size_t len;
      const char* ptr = lupb_checkstring(L, narg, &len);
      switch (copy) {
        case LUPB_COPY: {
          upb_Arena* arena = lupb_Arenaget(L, container);
          char* data = upb_Arena_Malloc(arena, len);
          memcpy(data, ptr, len);
          ret.str_val = upb_StringView_FromDataAndSize(data, len);
          break;
        }
        case LUPB_REF:
          ret.str_val = upb_StringView_FromDataAndSize(ptr, len);
          break;
      }
      break;
    }
    case kUpb_CType_Message:
      ret.msg_val = lupb_msg_check(L, narg);
      /* Typecheck message. */
      lua_getiuservalue(L, container, LUPB_MSGDEF_INDEX);
      lua_getiuservalue(L, narg, LUPB_MSGDEF_INDEX);
      luaL_argcheck(L, lua_rawequal(L, -1, -2), narg, "message type mismatch");
      lua_pop(L, 2);
      break;
  }
  return ret;
}

void lupb_pushmsgval(lua_State* L, int container, upb_CType type,
                     upb_MessageValue val) {
  switch (type) {
    case kUpb_CType_Int32:
    case kUpb_CType_Enum:
      lupb_pushint32(L, val.int32_val);
      return;
    case kUpb_CType_Int64:
      lupb_pushint64(L, val.int64_val);
      return;
    case kUpb_CType_UInt32:
      lupb_pushuint32(L, val.uint32_val);
      return;
    case kUpb_CType_UInt64:
      lupb_pushuint64(L, val.uint64_val);
      return;
    case kUpb_CType_Double:
      lua_pushnumber(L, val.double_val);
      return;
    case kUpb_CType_Float:
      lua_pushnumber(L, val.float_val);
      return;
    case kUpb_CType_Bool:
      lua_pushboolean(L, val.bool_val);
      return;
    case kUpb_CType_String:
    case kUpb_CType_Bytes:
      lua_pushlstring(L, val.str_val.data, val.str_val.size);
      return;
    case kUpb_CType_Message:
      assert(container);
      if (!lupb_cacheget(L, val.msg_val)) {
        lupb_Message_Newmsgwrapper(L, container, val);
      }
      return;
  }
  LUPB_UNREACHABLE();
}

/* lupb_array *****************************************************************/

typedef struct {
  upb_Array* arr;
  upb_CType type;
} lupb_array;

static lupb_array* lupb_array_check(lua_State* L, int narg) {
  return luaL_checkudata(L, narg, LUPB_ARRAY);
}

/**
 * lupb_array_checkindex()
 *
 * Checks the array index at Lua stack index |narg| to verify that it is an
 * integer between 1 and |max|, inclusively.  Also corrects it to be zero-based
 * for C.
 */
static int lupb_array_checkindex(lua_State* L, int narg, uint32_t max) {
  uint32_t n = lupb_checkuint32(L, narg);
  luaL_argcheck(L, n != 0 && n <= max, narg, "invalid array index");
  return n - 1; /* Lua uses 1-based indexing. */
}

/* lupb_array Public API */

/* lupb_Array_New():
 *
 * Handles:
 *   Array(upb.TYPE_INT32)
 *   Array(message_type)
 */
static int lupb_Array_New(lua_State* L) {
  int arg_count = lua_gettop(L);
  lupb_array* larray;
  upb_Arena* arena;

  if (lua_type(L, 1) == LUA_TNUMBER) {
    upb_CType type = lupb_checkfieldtype(L, 1);
    larray = lupb_newuserdata(L, sizeof(*larray), 1, LUPB_ARRAY);
    larray->type = type;
  } else {
    lupb_MessageDef_check(L, 1);
    larray = lupb_newuserdata(L, sizeof(*larray), 2, LUPB_ARRAY);
    larray->type = kUpb_CType_Message;
    lua_pushvalue(L, 1);
    lua_setiuservalue(L, -2, LUPB_MSGDEF_INDEX);
  }

  arena = lupb_Arena_pushnew(L);
  lua_setiuservalue(L, -2, LUPB_ARENA_INDEX);

  larray->arr = upb_Array_New(arena, larray->type);
  lupb_cacheset(L, larray->arr);

  if (arg_count > 1) {
    /* Set initial fields from table. */
    int msg = arg_count + 1;
    lua_pushnil(L);
    while (lua_next(L, 2) != 0) {
      lua_pushvalue(L, -2); /* now stack is key, val, key */
      lua_insert(L, -3);    /* now stack is key, key, val */
      lua_settable(L, msg);
    }
  }

  return 1;
}

/* lupb_Array_Newindex():
 *
 * Handles:
 *   array[idx] = val
 *
 * idx can be within the array or one past the end to extend.
 */
static int lupb_Array_Newindex(lua_State* L) {
  lupb_array* larray = lupb_array_check(L, 1);
  size_t size = upb_Array_Size(larray->arr);
  uint32_t n = lupb_array_checkindex(L, 2, size + 1);
  upb_MessageValue msgval = lupb_tomsgval(L, larray->type, 3, 1, LUPB_COPY);

  if (n == size) {
    upb_Array_Append(larray->arr, msgval, lupb_Arenaget(L, 1));
  } else {
    upb_Array_Set(larray->arr, n, msgval);
  }

  if (larray->type == kUpb_CType_Message) {
    lupb_Arena_Fuseobjs(L, 1, 3);
  }

  return 0; /* 1 for chained assignments? */
}

/* lupb_array_index():
 *
 * Handles:
 *   array[idx] -> val
 *
 * idx must be within the array.
 */
static int lupb_array_index(lua_State* L) {
  lupb_array* larray = lupb_array_check(L, 1);
  size_t size = upb_Array_Size(larray->arr);
  uint32_t n = lupb_array_checkindex(L, 2, size);
  upb_MessageValue val = upb_Array_Get(larray->arr, n);

  lupb_pushmsgval(L, 1, larray->type, val);

  return 1;
}

/* lupb_array_len():
 *
 * Handles:
 *   #array -> len
 */
static int lupb_array_len(lua_State* L) {
  lupb_array* larray = lupb_array_check(L, 1);
  lua_pushnumber(L, upb_Array_Size(larray->arr));
  return 1;
}

static const struct luaL_Reg lupb_array_mm[] = {
    {"__index", lupb_array_index},
    {"__len", lupb_array_len},
    {"__newindex", lupb_Array_Newindex},
    {NULL, NULL}};

/* lupb_map *******************************************************************/

typedef struct {
  upb_Map* map;
  upb_CType key_type;
  upb_CType value_type;
} lupb_map;

#define MAP_MSGDEF_INDEX 1

static lupb_map* lupb_map_check(lua_State* L, int narg) {
  return luaL_checkudata(L, narg, LUPB_MAP);
}

/* lupb_map Public API */

/**
 * lupb_Map_New
 *
 * Handles:
 *   new_map = upb.Map(key_type, value_type)
 *   new_map = upb.Map(key_type, value_msgdef)
 */
static int lupb_Map_New(lua_State* L) {
  upb_Arena* arena;
  lupb_map* lmap;

  if (lua_type(L, 2) == LUA_TNUMBER) {
    lmap = lupb_newuserdata(L, sizeof(*lmap), 1, LUPB_MAP);
    lmap->value_type = lupb_checkfieldtype(L, 2);
  } else {
    lupb_MessageDef_check(L, 2);
    lmap = lupb_newuserdata(L, sizeof(*lmap), 2, LUPB_MAP);
    lmap->value_type = kUpb_CType_Message;
    lua_pushvalue(L, 2);
    lua_setiuservalue(L, -2, MAP_MSGDEF_INDEX);
  }

  arena = lupb_Arena_pushnew(L);
  lua_setiuservalue(L, -2, LUPB_ARENA_INDEX);

  lmap->key_type = lupb_checkfieldtype(L, 1);
  lmap->map = upb_Map_New(arena, lmap->key_type, lmap->value_type);
  lupb_cacheset(L, lmap->map);

  return 1;
}

/**
 * lupb_map_index
 *
 * Handles:
 *   map[key]
 */
static int lupb_map_index(lua_State* L) {
  lupb_map* lmap = lupb_map_check(L, 1);
  upb_MessageValue key = lupb_tomsgval(L, lmap->key_type, 2, 1, LUPB_REF);
  upb_MessageValue val;

  if (upb_Map_Get(lmap->map, key, &val)) {
    lupb_pushmsgval(L, 1, lmap->value_type, val);
  } else {
    lua_pushnil(L);
  }

  return 1;
}

/**
 * lupb_map_len
 *
 * Handles:
 *   map_len = #map
 */
static int lupb_map_len(lua_State* L) {
  lupb_map* lmap = lupb_map_check(L, 1);
  lua_pushnumber(L, upb_Map_Size(lmap->map));
  return 1;
}

/**
 * lupb_Map_Newindex
 *
 * Handles:
 *   map[key] = val
 *   map[key] = nil  # to remove from map
 */
static int lupb_Map_Newindex(lua_State* L) {
  lupb_map* lmap = lupb_map_check(L, 1);
  upb_Map* map = lmap->map;
  upb_MessageValue key = lupb_tomsgval(L, lmap->key_type, 2, 1, LUPB_REF);

  if (lua_isnil(L, 3)) {
    upb_Map_Delete(map, key, NULL);
  } else {
    upb_MessageValue val = lupb_tomsgval(L, lmap->value_type, 3, 1, LUPB_COPY);
    upb_Map_Set(map, key, val, lupb_Arenaget(L, 1));
    if (lmap->value_type == kUpb_CType_Message) {
      lupb_Arena_Fuseobjs(L, 1, 3);
    }
  }

  return 0;
}

static int lupb_MapIterator_Next(lua_State* L) {
  int map = lua_upvalueindex(2);
  size_t* iter = lua_touserdata(L, lua_upvalueindex(1));
  lupb_map* lmap = lupb_map_check(L, map);

  upb_MessageValue key, val;
  if (upb_Map_Next(lmap->map, &key, &val, iter)) {
    lupb_pushmsgval(L, map, lmap->key_type, key);
    lupb_pushmsgval(L, map, lmap->value_type, val);
    return 2;
  } else {
    return 0;
  }
}

/**
 * lupb_map_pairs()
 *
 * Handles:
 *   pairs(map)
 */
static int lupb_map_pairs(lua_State* L) {
  size_t* iter = lua_newuserdata(L, sizeof(*iter));
  lupb_map_check(L, 1);

  *iter = kUpb_Map_Begin;
  lua_pushvalue(L, 1);

  /* Upvalues are [iter, lupb_map]. */
  lua_pushcclosure(L, &lupb_MapIterator_Next, 2);

  return 1;
}

/* upb_mapiter ]]] */

static const struct luaL_Reg lupb_map_mm[] = {{"__index", lupb_map_index},
                                              {"__len", lupb_map_len},
                                              {"__newindex", lupb_Map_Newindex},
                                              {"__pairs", lupb_map_pairs},
                                              {NULL, NULL}};

/* lupb_Message
 * *******************************************************************/

typedef struct {
  upb_Message* msg;
} lupb_Message;

/* lupb_Message helpers */

static upb_Message* lupb_msg_check(lua_State* L, int narg) {
  lupb_Message* msg = luaL_checkudata(L, narg, LUPB_MSG);
  return msg->msg;
}

static const upb_MessageDef* lupb_Message_Getmsgdef(lua_State* L, int msg) {
  lua_getiuservalue(L, msg, LUPB_MSGDEF_INDEX);
  const upb_MessageDef* m = lupb_MessageDef_check(L, -1);
  lua_pop(L, 1);
  return m;
}

static const upb_FieldDef* lupb_msg_tofield(lua_State* L, int msg, int field) {
  size_t len;
  const char* fieldname = luaL_checklstring(L, field, &len);
  const upb_MessageDef* m = lupb_Message_Getmsgdef(L, msg);
  return upb_MessageDef_FindFieldByNameWithSize(m, fieldname, len);
}

static const upb_FieldDef* lupb_msg_checkfield(lua_State* L, int msg,
                                               int field) {
  const upb_FieldDef* f = lupb_msg_tofield(L, msg, field);
  if (f == NULL) {
    luaL_error(L, "no such field '%s'", lua_tostring(L, field));
  }
  return f;
}

upb_Message* lupb_msg_pushnew(lua_State* L, int narg) {
  const upb_MessageDef* m = lupb_MessageDef_check(L, narg);
  lupb_Message* lmsg = lupb_newuserdata(L, sizeof(lupb_Message), 2, LUPB_MSG);
  upb_Arena* arena = lupb_Arena_pushnew(L);

  lua_setiuservalue(L, -2, LUPB_ARENA_INDEX);
  lua_pushvalue(L, 1);
  lua_setiuservalue(L, -2, LUPB_MSGDEF_INDEX);

  lmsg->msg = upb_Message_New(upb_MessageDef_MiniTable(m), arena);
  lupb_cacheset(L, lmsg->msg);
  return lmsg->msg;
}

/**
 * lupb_Message_Newmsgwrapper()
 *
 * Creates a new wrapper for a message, copying the arena and msgdef references
 * from |narg| (which should be an array or map).
 */
static void lupb_Message_Newmsgwrapper(lua_State* L, int narg,
                                       upb_MessageValue val) {
  lupb_Message* lmsg = lupb_newuserdata(L, sizeof(*lmsg), 2, LUPB_MSG);
  lmsg->msg = (upb_Message*)val.msg_val; /* XXX: cast isn't great. */
  lupb_cacheset(L, lmsg->msg);

  /* Copy both arena and msgdef into the wrapper. */
  lua_getiuservalue(L, narg, LUPB_ARENA_INDEX);
  lua_setiuservalue(L, -2, LUPB_ARENA_INDEX);
  lua_getiuservalue(L, narg, LUPB_MSGDEF_INDEX);
  lua_setiuservalue(L, -2, LUPB_MSGDEF_INDEX);
}

/**
 * lupb_Message_Newud()
 *
 * Creates the Lua userdata for a new wrapper object, adding a reference to
 * the msgdef if necessary.
 */
static void* lupb_Message_Newud(lua_State* L, int narg, size_t size,
                                const char* type, const upb_FieldDef* f) {
  if (upb_FieldDef_CType(f) == kUpb_CType_Message) {
    /* Wrapper needs a reference to the msgdef. */
    void* ud = lupb_newuserdata(L, size, 2, type);
    lua_getiuservalue(L, narg, LUPB_MSGDEF_INDEX);
    lupb_MessageDef_pushsubmsgdef(L, f);
    lua_setiuservalue(L, -2, LUPB_MSGDEF_INDEX);
    return ud;
  } else {
    return lupb_newuserdata(L, size, 1, type);
  }
}

/**
 * lupb_Message_Newwrapper()
 *
 * Creates a new Lua wrapper object to wrap the given array, map, or message.
 */
static void lupb_Message_Newwrapper(lua_State* L, int narg,
                                    const upb_FieldDef* f,
                                    upb_MutableMessageValue val) {
  if (upb_FieldDef_IsMap(f)) {
    const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f);
    const upb_FieldDef* key_f =
        upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_KeyFieldNumber);
    const upb_FieldDef* val_f =
        upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_ValueFieldNumber);
    lupb_map* lmap =
        lupb_Message_Newud(L, narg, sizeof(*lmap), LUPB_MAP, val_f);
    lmap->key_type = upb_FieldDef_CType(key_f);
    lmap->value_type = upb_FieldDef_CType(val_f);
    lmap->map = val.map;
  } else if (upb_FieldDef_IsRepeated(f)) {
    lupb_array* larr =
        lupb_Message_Newud(L, narg, sizeof(*larr), LUPB_ARRAY, f);
    larr->type = upb_FieldDef_CType(f);
    larr->arr = val.array;
  } else {
    lupb_Message* lmsg =
        lupb_Message_Newud(L, narg, sizeof(*lmsg), LUPB_MSG, f);
    lmsg->msg = val.msg;
  }

  /* Copy arena ref to new wrapper.  This may be a different arena than the
   * underlying data was originally constructed from, but if so both arenas
   * must be in the same group. */
  lua_getiuservalue(L, narg, LUPB_ARENA_INDEX);
  lua_setiuservalue(L, -2, LUPB_ARENA_INDEX);

  lupb_cacheset(L, val.msg);
}

/**
 * lupb_msg_typechecksubmsg()
 *
 * Typechecks the given array, map, or msg against this upb_FieldDef.
 */
static void lupb_msg_typechecksubmsg(lua_State* L, int narg, int msgarg,
                                     const upb_FieldDef* f) {
  /* Typecheck this map's msgdef against this message field. */
  lua_getiuservalue(L, narg, LUPB_MSGDEF_INDEX);
  lua_getiuservalue(L, msgarg, LUPB_MSGDEF_INDEX);
  lupb_MessageDef_pushsubmsgdef(L, f);
  luaL_argcheck(L, lua_rawequal(L, -1, -2), narg, "message type mismatch");
  lua_pop(L, 2);
}

/* lupb_Message Public API */

/**
 * lupb_MessageDef_call
 *
 * Handles:
 *   new_msg = MessageClass()
 *   new_msg = MessageClass{foo = "bar", baz = 3, quux = {foo = 3}}
 */
int lupb_MessageDef_call(lua_State* L) {
  int arg_count = lua_gettop(L);
  lupb_msg_pushnew(L, 1);

  if (arg_count > 1) {
    /* Set initial fields from table. */
    int msg = arg_count + 1;
    lua_pushnil(L);
    while (lua_next(L, 2) != 0) {
      lua_pushvalue(L, -2); /* now stack is key, val, key */
      lua_insert(L, -3);    /* now stack is key, key, val */
      lua_settable(L, msg);
    }
  }

  return 1;
}

/**
 * lupb_msg_index
 *
 * Handles:
 *   msg.foo
 *   msg["foo"]
 *   msg[field_descriptor]  # (for extensions) (TODO)
 */
static int lupb_msg_index(lua_State* L) {
  upb_Message* msg = lupb_msg_check(L, 1);
  const upb_FieldDef* f = lupb_msg_checkfield(L, 1, 2);

  if (upb_FieldDef_IsRepeated(f) || upb_FieldDef_IsSubMessage(f)) {
    /* Wrapped type; get or create wrapper. */
    upb_Arena* arena = upb_FieldDef_IsRepeated(f) ? lupb_Arenaget(L, 1) : NULL;
    upb_MutableMessageValue val = upb_Message_Mutable(msg, f, arena);
    if (!lupb_cacheget(L, val.msg)) {
      lupb_Message_Newwrapper(L, 1, f, val);
    }
  } else {
    /* Value type, just push value and return .*/
    upb_MessageValue val = upb_Message_GetFieldByDef(msg, f);
    lupb_pushmsgval(L, 0, upb_FieldDef_CType(f), val);
  }

  return 1;
}

/**
 * lupb_Message_Newindex()
 *
 * Handles:
 *   msg.foo = bar
 *   msg["foo"] = bar
 *   msg[field_descriptor] = bar  # (for extensions) (TODO)
 */
static int lupb_Message_Newindex(lua_State* L) {
  upb_Message* msg = lupb_msg_check(L, 1);
  const upb_FieldDef* f = lupb_msg_checkfield(L, 1, 2);
  upb_MessageValue msgval;
  bool merge_arenas = true;

  if (upb_FieldDef_IsMap(f)) {
    lupb_map* lmap = lupb_map_check(L, 3);
    const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f);
    const upb_FieldDef* key_f =
        upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_KeyFieldNumber);
    const upb_FieldDef* val_f =
        upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_ValueFieldNumber);
    upb_CType key_type = upb_FieldDef_CType(key_f);
    upb_CType value_type = upb_FieldDef_CType(val_f);
    luaL_argcheck(L, lmap->key_type == key_type, 3, "key type mismatch");
    luaL_argcheck(L, lmap->value_type == value_type, 3, "value type mismatch");
    if (value_type == kUpb_CType_Message) {
      lupb_msg_typechecksubmsg(L, 3, 1, val_f);
    }
    msgval.map_val = lmap->map;
  } else if (upb_FieldDef_IsRepeated(f)) {
    lupb_array* larr = lupb_array_check(L, 3);
    upb_CType type = upb_FieldDef_CType(f);
    luaL_argcheck(L, larr->type == type, 3, "array type mismatch");
    if (type == kUpb_CType_Message) {
      lupb_msg_typechecksubmsg(L, 3, 1, f);
    }
    msgval.array_val = larr->arr;
  } else if (upb_FieldDef_IsSubMessage(f)) {
    upb_Message* msg = lupb_msg_check(L, 3);
    lupb_msg_typechecksubmsg(L, 3, 1, f);
    msgval.msg_val = msg;
  } else {
    msgval = lupb_tomsgval(L, upb_FieldDef_CType(f), 3, 1, LUPB_COPY);
    merge_arenas = false;
  }

  if (merge_arenas) {
    lupb_Arena_Fuseobjs(L, 1, 3);
  }

  upb_Message_SetFieldByDef(msg, f, msgval, lupb_Arenaget(L, 1));

  /* Return the new value for chained assignments. */
  lua_pushvalue(L, 3);
  return 1;
}

/**
 * lupb_msg_tostring()
 *
 * Handles:
 *   tostring(msg)
 *   print(msg)
 *   etc.
 */
static int lupb_msg_tostring(lua_State* L) {
  upb_Message* msg = lupb_msg_check(L, 1);
  const upb_MessageDef* m;
  char buf[1024];
  size_t size;

  lua_getiuservalue(L, 1, LUPB_MSGDEF_INDEX);
  m = lupb_MessageDef_check(L, -1);

  size = upb_TextEncode(msg, m, NULL, 0, buf, sizeof(buf));

  if (size < sizeof(buf)) {
    lua_pushlstring(L, buf, size);
  } else {
    char* ptr = malloc(size + 1);
    upb_TextEncode(msg, m, NULL, 0, ptr, size + 1);
    lua_pushlstring(L, ptr, size);
    free(ptr);
  }

  return 1;
}

static const struct luaL_Reg lupb_msg_mm[] = {
    {"__index", lupb_msg_index},
    {"__newindex", lupb_Message_Newindex},
    {"__tostring", lupb_msg_tostring},
    {NULL, NULL}};

/* lupb_Message toplevel
 * **********************************************************/

static int lupb_getoptions(lua_State* L, int narg) {
  int options = 0;
  if (lua_gettop(L) >= narg) {
    size_t len = lua_rawlen(L, narg);
    for (size_t i = 1; i <= len; i++) {
      lua_rawgeti(L, narg, i);
      options |= lupb_checkuint32(L, -1);
      lua_pop(L, 1);
    }
  }
  return options;
}

/**
 * lupb_decode()
 *
 * Handles:
 *   msg = upb.decode(MessageClass, bin_string)
 */
static int lupb_decode(lua_State* L) {
  size_t len;
  const upb_MessageDef* m = lupb_MessageDef_check(L, 1);
  const char* pb = lua_tolstring(L, 2, &len);
  const upb_MiniTable* layout = upb_MessageDef_MiniTable(m);
  upb_Message* msg = lupb_msg_pushnew(L, 1);
  upb_Arena* arena = lupb_Arenaget(L, -1);
  char* buf;

  /* Copy input data to arena, message will reference it. */
  buf = upb_Arena_Malloc(arena, len);
  memcpy(buf, pb, len);

  upb_DecodeStatus status = upb_Decode(buf, len, msg, layout, NULL,
                                       kUpb_DecodeOption_AliasString, arena);

  if (status != kUpb_DecodeStatus_Ok) {
    lua_pushstring(L, "Error decoding protobuf.");
    return lua_error(L);
  }

  return 1;
}

/**
 * lupb_Encode()
 *
 * Handles:
 *   bin_string = upb.encode(msg)
 */
static int lupb_Encode(lua_State* L) {
  const upb_Message* msg = lupb_msg_check(L, 1);
  const upb_MessageDef* m = lupb_Message_Getmsgdef(L, 1);
  const upb_MiniTable* layout = upb_MessageDef_MiniTable(m);
  int options = lupb_getoptions(L, 2);
  upb_Arena* arena = lupb_Arena_pushnew(L);
  char* buf;
  size_t size;
  upb_EncodeStatus status =
      upb_Encode(msg, (const void*)layout, options, arena, &buf, &size);
  if (status != kUpb_EncodeStatus_Ok) {
    lua_pushstring(L, "Error encoding protobuf.");
    return lua_error(L);
  }

  lua_pushlstring(L, buf, size);

  return 1;
}

/**
 * lupb_jsondecode()
 *
 * Handles:
 *   text_string = upb.json_decode(MessageClass, json_str,
 * {upb.JSONDEC_IGNOREUNKNOWN})
 */
static int lupb_jsondecode(lua_State* L) {
  size_t len;
  const upb_MessageDef* m = lupb_MessageDef_check(L, 1);
  const char* json = lua_tolstring(L, 2, &len);
  int options = lupb_getoptions(L, 3);
  upb_Message* msg;
  upb_Arena* arena;
  upb_Status status;

  msg = lupb_msg_pushnew(L, 1);
  arena = lupb_Arenaget(L, -1);
  upb_Status_Clear(&status);
  upb_JsonDecode(json, len, msg, m, NULL, options, arena, &status);
  lupb_checkstatus(L, &status);

  return 1;
}

/**
 * lupb_jsonencode()
 *
 * Handles:
 *   text_string = upb.json_encode(msg, {upb.JSONENC_EMITDEFAULTS})
 */
static int lupb_jsonencode(lua_State* L) {
  upb_Message* msg = lupb_msg_check(L, 1);
  const upb_MessageDef* m = lupb_Message_Getmsgdef(L, 1);
  int options = lupb_getoptions(L, 2);
  char buf[1024];
  size_t size;
  upb_Status status;

  upb_Status_Clear(&status);
  size = upb_JsonEncode(msg, m, NULL, options, buf, sizeof(buf), &status);
  lupb_checkstatus(L, &status);

  if (size < sizeof(buf)) {
    lua_pushlstring(L, buf, size);
  } else {
    char* ptr = malloc(size + 1);
    upb_JsonEncode(msg, m, NULL, options, ptr, size + 1, &status);
    lupb_checkstatus(L, &status);
    lua_pushlstring(L, ptr, size);
    free(ptr);
  }

  return 1;
}

/**
 * lupb_textencode()
 *
 * Handles:
 *   text_string = upb.text_encode(msg, {upb.TXTENC_SINGLELINE})
 */
static int lupb_textencode(lua_State* L) {
  upb_Message* msg = lupb_msg_check(L, 1);
  const upb_MessageDef* m = lupb_Message_Getmsgdef(L, 1);
  int options = lupb_getoptions(L, 2);
  char buf[1024];
  size_t size;

  size = upb_TextEncode(msg, m, NULL, options, buf, sizeof(buf));

  if (size < sizeof(buf)) {
    lua_pushlstring(L, buf, size);
  } else {
    char* ptr = malloc(size + 1);
    upb_TextEncode(msg, m, NULL, options, ptr, size + 1);
    lua_pushlstring(L, ptr, size);
    free(ptr);
  }

  return 1;
}

static void lupb_setfieldi(lua_State* L, const char* field, int i) {
  lua_pushinteger(L, i);
  lua_setfield(L, -2, field);
}

static const struct luaL_Reg lupb_msg_toplevel_m[] = {
    {"Array", lupb_Array_New},        {"Map", lupb_Map_New},
    {"decode", lupb_decode},          {"encode", lupb_Encode},
    {"json_decode", lupb_jsondecode}, {"json_encode", lupb_jsonencode},
    {"text_encode", lupb_textencode}, {NULL, NULL}};

void lupb_msg_registertypes(lua_State* L) {
  lupb_setfuncs(L, lupb_msg_toplevel_m);

  lupb_register_type(L, LUPB_ARENA, NULL, lupb_Arena_mm);
  lupb_register_type(L, LUPB_ARRAY, NULL, lupb_array_mm);
  lupb_register_type(L, LUPB_MAP, NULL, lupb_map_mm);
  lupb_register_type(L, LUPB_MSG, NULL, lupb_msg_mm);

  lupb_setfieldi(L, "TXTENC_SINGLELINE", UPB_TXTENC_SINGLELINE);
  lupb_setfieldi(L, "TXTENC_SKIPUNKNOWN", UPB_TXTENC_SKIPUNKNOWN);
  lupb_setfieldi(L, "TXTENC_NOSORT", UPB_TXTENC_NOSORT);

  lupb_setfieldi(L, "ENCODE_DETERMINISTIC", kUpb_EncodeOption_Deterministic);
  lupb_setfieldi(L, "ENCODE_SKIPUNKNOWN", kUpb_EncodeOption_SkipUnknown);

  lupb_setfieldi(L, "JSONENC_EMITDEFAULTS", upb_JsonEncode_EmitDefaults);
  lupb_setfieldi(L, "JSONENC_PROTONAMES", upb_JsonEncode_UseProtoNames);

  lupb_setfieldi(L, "JSONDEC_IGNOREUNKNOWN", upb_JsonDecode_IgnoreUnknown);

  lupb_cacheinit(L);
}
