/*
 * Copyright 2023 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef parser_context_h
#define parser_context_h

#include "common.h"
#include "ir/names.h"
#include "lexer.h"
#include "support/name.h"
#include "support/result.h"
#include "support/string.h"
#include "wasm-builder.h"
#include "wasm-ir-builder.h"
#include "wasm.h"

namespace wasm::WATParser {

using IndexMap = std::unordered_map<Name, Index>;

inline std::vector<Type> getUnnamedTypes(const std::vector<NameType>& named) {
  std::vector<Type> types;
  types.reserve(named.size());
  for (auto& t : named) {
    types.push_back(t.type);
  }
  return types;
}

struct Limits {
  uint64_t initial;
  std::optional<uint64_t> max;
};

struct MemType {
  Type addressType;
  Limits limits;
  bool shared;
};

struct Memarg {
  uint64_t offset;
  uint32_t align;
};

struct TableType {
  Type addressType;
  Limits limits;
};

// The location, possible name, and index in the respective module index space
// of a module-level definition in the input.
struct DefPos {
  Name name;
  Index pos;
  Index index;
  std::vector<Annotation> annotations;
};

struct GlobalType {
  Mutability mutability;
  Type type;
};

// A signature type and parameter names (possibly empty), used for parsing
// function types.
struct TypeUse {
  HeapType type;
  std::vector<Name> names;
};

struct NullTypeParserCtx {
  using IndexT = Ok;
  using HeapTypeT = Ok;
  using TupleElemListT = Ok;
  using TypeT = Ok;
  using ParamsT = Ok;
  using ResultsT = size_t;
  using BlockTypeT = Ok;
  using SignatureT = Ok;
  using ContinuationT = Ok;
  using StorageT = Ok;
  using FieldT = Ok;
  using FieldsT = Ok;
  using StructT = Ok;
  using ArrayT = Ok;
  using LimitsT = Ok;
  using MemTypeT = Ok;
  using GlobalTypeT = Ok;
  using TypeUseT = Ok;
  using LocalsT = Ok;
  using ElemListT = Ok;
  using DataStringT = Ok;

  HeapTypeT makeFuncType(Shareability) { return Ok{}; }
  HeapTypeT makeAnyType(Shareability) { return Ok{}; }
  HeapTypeT makeExternType(Shareability) { return Ok{}; }
  HeapTypeT makeEqType(Shareability) { return Ok{}; }
  HeapTypeT makeI31Type(Shareability) { return Ok{}; }
  HeapTypeT makeStructType(Shareability) { return Ok{}; }
  HeapTypeT makeArrayType(Shareability) { return Ok{}; }
  HeapTypeT makeExnType(Shareability) { return Ok{}; }
  HeapTypeT makeStringType(Shareability) { return Ok{}; }
  HeapTypeT makeContType(Shareability) { return Ok{}; }
  HeapTypeT makeNoneType(Shareability) { return Ok{}; }
  HeapTypeT makeNoextType(Shareability) { return Ok{}; }
  HeapTypeT makeNofuncType(Shareability) { return Ok{}; }
  HeapTypeT makeNoexnType(Shareability) { return Ok{}; }
  HeapTypeT makeNocontType(Shareability) { return Ok{}; }

  TypeT makeI32() { return Ok{}; }
  TypeT makeI64() { return Ok{}; }
  TypeT makeF32() { return Ok{}; }
  TypeT makeF64() { return Ok{}; }
  TypeT makeV128() { return Ok{}; }

  TypeT makeRefType(HeapTypeT, Nullability) { return Ok{}; }

  TupleElemListT makeTupleElemList() { return Ok{}; }
  void appendTupleElem(TupleElemListT&, TypeT) {}
  TypeT makeTupleType(TupleElemListT) { return Ok{}; }

  ParamsT makeParams() { return Ok{}; }
  void appendParam(ParamsT&, Name, TypeT) {}

  // We have to count results because whether or not a block introduces a
  // typeuse that may implicitly define a type depends on how many results it
  // has.
  size_t makeResults() { return 0; }
  void appendResult(size_t& results, TypeT) { ++results; }
  size_t getResultsSize(size_t results) { return results; }

  SignatureT makeFuncType(ParamsT*, ResultsT*) { return Ok{}; }
  ContinuationT makeContType(HeapTypeT) { return Ok{}; }

  StorageT makeI8() { return Ok{}; }
  StorageT makeI16() { return Ok{}; }
  StorageT makeStorageType(TypeT) { return Ok{}; }

  FieldT makeFieldType(StorageT, Mutability) { return Ok{}; }

  FieldsT makeFields() { return Ok{}; }
  void appendField(FieldsT&, Name, FieldT) {}

  StructT makeStruct(FieldsT&) { return Ok{}; }

  std::optional<ArrayT> makeArray(FieldsT&) { return Ok{}; }

  GlobalTypeT makeGlobalType(Mutability, TypeT) { return Ok{}; }

  LocalsT makeLocals() { return Ok{}; }
  void appendLocal(LocalsT&, Name, TypeT) {}

  Result<Index> getTypeIndex(Name) { return 1; }
  Result<HeapTypeT> getHeapTypeFromIdx(Index) { return Ok{}; }

  DataStringT makeDataString() { return Ok{}; }
  void appendDataString(DataStringT&, std::string_view) {}

  MemTypeT makeMemType(Type, LimitsT, bool) { return Ok{}; }

  BlockTypeT getBlockTypeFromResult(size_t results) { return Ok{}; }

  Result<> getBlockTypeFromTypeUse(Index, TypeUseT) { return Ok{}; }

  bool skipFunctionBody() { return false; }
};

template<typename Ctx> struct TypeParserCtx {
  using IndexT = Index;
  using HeapTypeT = HeapType;
  using TypeT = Type;
  using ParamsT = std::vector<NameType>;
  using ResultsT = std::vector<Type>;
  using BlockTypeT = HeapType;
  using SignatureT = Signature;
  using ContinuationT = Continuation;
  using StorageT = Field;
  using FieldT = Field;
  using FieldsT = std::pair<std::vector<Name>, std::vector<Field>>;
  using StructT = std::pair<std::vector<Name>, Struct>;
  using ArrayT = Array;
  using LimitsT = Ok;
  using MemTypeT = Ok;
  using LocalsT = std::vector<NameType>;
  using DataStringT = Ok;

  // Map heap type names to their indices.
  const IndexMap& typeIndices;

  TypeParserCtx(const IndexMap& typeIndices) : typeIndices(typeIndices) {}

  Ctx& self() { return *static_cast<Ctx*>(this); }

  HeapTypeT makeFuncType(Shareability share) {
    return HeapTypes::func.getBasic(share);
  }
  HeapTypeT makeAnyType(Shareability share) {
    return HeapTypes::any.getBasic(share);
  }
  HeapTypeT makeExternType(Shareability share) {
    return HeapTypes::ext.getBasic(share);
  }
  HeapTypeT makeEqType(Shareability share) {
    return HeapTypes::eq.getBasic(share);
  }
  HeapTypeT makeI31Type(Shareability share) {
    return HeapTypes::i31.getBasic(share);
  }
  HeapTypeT makeStructType(Shareability share) {
    return HeapTypes::struct_.getBasic(share);
  }
  HeapTypeT makeArrayType(Shareability share) {
    return HeapTypes::array.getBasic(share);
  }
  HeapTypeT makeExnType(Shareability share) {
    return HeapTypes::exn.getBasic(share);
  }
  HeapTypeT makeStringType(Shareability share) {
    return HeapTypes::string.getBasic(share);
  }
  HeapTypeT makeContType(Shareability share) {
    return HeapTypes::cont.getBasic(share);
  }
  HeapTypeT makeNoneType(Shareability share) {
    return HeapTypes::none.getBasic(share);
  }
  HeapTypeT makeNoextType(Shareability share) {
    return HeapTypes::noext.getBasic(share);
  }
  HeapTypeT makeNofuncType(Shareability share) {
    return HeapTypes::nofunc.getBasic(share);
  }
  HeapTypeT makeNoexnType(Shareability share) {
    return HeapTypes::noexn.getBasic(share);
  }
  HeapTypeT makeNocontType(Shareability share) {
    return HeapTypes::nocont.getBasic(share);
  }

  TypeT makeI32() { return Type::i32; }
  TypeT makeI64() { return Type::i64; }
  TypeT makeF32() { return Type::f32; }
  TypeT makeF64() { return Type::f64; }
  TypeT makeV128() { return Type::v128; }

  TypeT makeRefType(HeapTypeT ht, Nullability nullability) {
    return Type(ht, nullability);
  }

  std::vector<Type> makeTupleElemList() { return {}; }
  void appendTupleElem(std::vector<Type>& elems, Type elem) {
    elems.push_back(elem);
  }
  Result<TypeT> makeTupleType(const std::vector<Type>& types) {
    return Tuple(types);
  }

  ParamsT makeParams() { return {}; }
  void appendParam(ParamsT& params, Name id, TypeT type) {
    params.push_back({id, type});
  }

  ResultsT makeResults() { return {}; }
  void appendResult(ResultsT& results, TypeT type) { results.push_back(type); }
  size_t getResultsSize(const ResultsT& results) { return results.size(); }

  SignatureT makeFuncType(ParamsT* params, ResultsT* results) {
    std::vector<Type> empty;
    const auto& paramTypes = params ? getUnnamedTypes(*params) : empty;
    const auto& resultTypes = results ? *results : empty;
    return Signature(self().makeTupleType(paramTypes),
                     self().makeTupleType(resultTypes));
  }

  ContinuationT makeContType(HeapTypeT ft) { return Continuation(ft); }

  StorageT makeI8() { return Field(Field::i8, Immutable); }
  StorageT makeI16() { return Field(Field::i16, Immutable); }
  StorageT makeStorageType(TypeT type) { return Field(type, Immutable); }

  FieldT makeFieldType(FieldT field, Mutability mutability) {
    if (field.packedType == Field::not_packed) {
      return Field(field.type, mutability);
    }
    return Field(field.packedType, mutability);
  }

  FieldsT makeFields() { return {}; }
  void appendField(FieldsT& fields, Name name, FieldT field) {
    fields.first.push_back(name);
    fields.second.push_back(field);
  }

  StructT makeStruct(FieldsT& fields) {
    return {std::move(fields.first), Struct(std::move(fields.second))};
  }

  std::optional<ArrayT> makeArray(FieldsT& fields) {
    if (fields.second.size() == 1) {
      return Array(fields.second[0]);
    }
    return {};
  }

  LocalsT makeLocals() { return {}; }
  void appendLocal(LocalsT& locals, Name id, TypeT type) {
    locals.push_back({id, type});
  }

  Result<Index> getTypeIndex(Name id) {
    auto it = typeIndices.find(id);
    if (it == typeIndices.end()) {
      return self().in.err("unknown type identifier");
    }
    return it->second;
  }

  DataStringT makeDataString() { return Ok{}; }
  void appendDataString(DataStringT&, std::string_view) {}

  Result<LimitsT> makeLimits(uint64_t, std::optional<uint64_t>) { return Ok{}; }
  LimitsT getLimitsFromData(DataStringT) { return Ok{}; }

  MemTypeT makeMemType(Type, LimitsT, bool) { return Ok{}; }

  HeapType getBlockTypeFromResult(const std::vector<Type> results) {
    assert(results.size() == 1);
    return HeapType(Signature(Type::none, results[0]));
  }

  bool skipFunctionBody() { return false; }
};

struct NullInstrParserCtx {
  using ExprT = Ok;
  using CatchT = Ok;
  using CatchListT = Ok;
  using TagLabelListT = Ok;

  using FieldIdxT = Ok;
  using FuncIdxT = Ok;
  using LocalIdxT = Ok;
  using TableIdxT = Ok;
  using MemoryIdxT = Ok;
  using GlobalIdxT = Ok;
  using ElemIdxT = Ok;
  using DataIdxT = Ok;
  using LabelIdxT = Ok;
  using TagIdxT = Ok;

  using MemargT = Ok;

  Result<> makeExpr() { return Ok{}; }

  template<typename HeapTypeT> FieldIdxT getFieldFromIdx(HeapTypeT, uint32_t) {
    return Ok{};
  }
  template<typename HeapTypeT> FieldIdxT getFieldFromName(HeapTypeT, Name) {
    return Ok{};
  }
  FuncIdxT getFuncFromIdx(uint32_t) { return Ok{}; }
  FuncIdxT getFuncFromName(Name) { return Ok{}; }
  LocalIdxT getLocalFromIdx(uint32_t) { return Ok{}; }
  LocalIdxT getLocalFromName(Name) { return Ok{}; }
  GlobalIdxT getGlobalFromIdx(uint32_t) { return Ok{}; }
  GlobalIdxT getGlobalFromName(Name) { return Ok{}; }
  TableIdxT getTableFromIdx(uint32_t) { return Ok{}; }
  TableIdxT getTableFromName(Name) { return Ok{}; }
  MemoryIdxT getMemoryFromIdx(uint32_t) { return Ok{}; }
  MemoryIdxT getMemoryFromName(Name) { return Ok{}; }
  ElemIdxT getElemFromIdx(uint32_t) { return Ok{}; }
  ElemIdxT getElemFromName(Name) { return Ok{}; }
  DataIdxT getDataFromIdx(uint32_t) { return Ok{}; }
  DataIdxT getDataFromName(Name) { return Ok{}; }
  LabelIdxT getLabelFromIdx(uint32_t, bool) { return Ok{}; }
  LabelIdxT getLabelFromName(Name, bool) { return Ok{}; }
  TagIdxT getTagFromIdx(uint32_t) { return Ok{}; }
  TagIdxT getTagFromName(Name) { return Ok{}; }

  MemargT getMemarg(uint64_t, uint32_t) { return Ok{}; }

  template<typename BlockTypeT>
  Result<> makeBlock(Index,
                     const std::vector<Annotation>&,
                     std::optional<Name>,
                     BlockTypeT) {
    return Ok{};
  }
  template<typename BlockTypeT>
  Result<> makeIf(Index,
                  const std::vector<Annotation>&,
                  std::optional<Name>,
                  BlockTypeT) {
    return Ok{};
  }
  Result<> visitElse() { return Ok{}; }
  template<typename BlockTypeT>
  Result<> makeLoop(Index,
                    const std::vector<Annotation>&,
                    std::optional<Name>,
                    BlockTypeT) {
    return Ok{};
  }
  template<typename BlockTypeT>
  Result<> makeTry(Index,
                   const std::vector<Annotation>&,
                   std::optional<Name>,
                   BlockTypeT) {
    return Ok{};
  }
  Result<> visitCatch(Index, TagIdxT) { return Ok{}; }
  Result<> visitCatchAll(Index) { return Ok{}; }
  Result<> visitDelegate(Index, LabelIdxT) { return Ok{}; }
  Result<> visitEnd() { return Ok{}; }

  CatchListT makeCatchList() { return Ok{}; }
  void appendCatch(CatchListT&, CatchT) {}
  CatchT makeCatch(TagIdxT, LabelIdxT) { return Ok{}; }
  CatchT makeCatchRef(TagIdxT, LabelIdxT) { return Ok{}; }
  CatchT makeCatchAll(LabelIdxT) { return Ok{}; }
  CatchT makeCatchAllRef(LabelIdxT) { return Ok{}; }
  template<typename BlockTypeT>
  Result<> makeTryTable(Index,
                        const std::vector<Annotation>&,
                        std::optional<Name>,
                        BlockTypeT,
                        CatchListT) {
    return Ok{};
  }

  TagLabelListT makeTagLabelList() { return Ok{}; }
  void appendTagLabel(TagLabelListT&, TagIdxT, LabelIdxT) {}

  void setSrcLoc(const std::vector<Annotation>&) {}

  Result<> makeUnreachable(Index, const std::vector<Annotation>&) {
    return Ok{};
  }
  Result<> makeNop(Index, const std::vector<Annotation>&) { return Ok{}; }
  Result<> makeBinary(Index, const std::vector<Annotation>&, BinaryOp) {
    return Ok{};
  }
  Result<> makeUnary(Index, const std::vector<Annotation>&, UnaryOp) {
    return Ok{};
  }
  template<typename ResultsT>
  Result<> makeSelect(Index, const std::vector<Annotation>&, ResultsT*) {
    return Ok{};
  }
  Result<> makeDrop(Index, const std::vector<Annotation>&) { return Ok{}; }
  Result<> makeMemorySize(Index, const std::vector<Annotation>&, MemoryIdxT*) {
    return Ok{};
  }
  Result<> makeMemoryGrow(Index, const std::vector<Annotation>&, MemoryIdxT*) {
    return Ok{};
  }
  Result<> makeLocalGet(Index, const std::vector<Annotation>&, LocalIdxT) {
    return Ok{};
  }
  Result<> makeLocalTee(Index, const std::vector<Annotation>&, LocalIdxT) {
    return Ok{};
  }
  Result<> makeLocalSet(Index, const std::vector<Annotation>&, LocalIdxT) {
    return Ok{};
  }
  Result<> makeGlobalGet(Index, const std::vector<Annotation>&, GlobalIdxT) {
    return Ok{};
  }
  Result<> makeGlobalSet(Index, const std::vector<Annotation>&, GlobalIdxT) {
    return Ok{};
  }

  Result<> makeI32Const(Index, const std::vector<Annotation>&, uint32_t) {
    return Ok{};
  }
  Result<> makeI64Const(Index, const std::vector<Annotation>&, uint64_t) {
    return Ok{};
  }
  Result<> makeF32Const(Index, const std::vector<Annotation>&, float) {
    return Ok{};
  }
  Result<> makeF64Const(Index, const std::vector<Annotation>&, double) {
    return Ok{};
  }
  Result<> makeI8x16Const(Index,
                          const std::vector<Annotation>&,
                          const std::array<uint8_t, 16>&) {
    return Ok{};
  }
  Result<> makeI16x8Const(Index,
                          const std::vector<Annotation>&,
                          const std::array<uint16_t, 8>&) {
    return Ok{};
  }
  Result<> makeI32x4Const(Index,
                          const std::vector<Annotation>&,
                          const std::array<uint32_t, 4>&) {
    return Ok{};
  }
  Result<> makeI64x2Const(Index,
                          const std::vector<Annotation>&,
                          const std::array<uint64_t, 2>&) {
    return Ok{};
  }
  Result<> makeF32x4Const(Index,
                          const std::vector<Annotation>&,
                          const std::array<float, 4>&) {
    return Ok{};
  }
  Result<> makeF64x2Const(Index,
                          const std::vector<Annotation>&,
                          const std::array<double, 2>&) {
    return Ok{};
  }
  Result<> makeLoad(Index,
                    const std::vector<Annotation>&,
                    Type,
                    bool,
                    int,
                    bool,
                    MemoryIdxT*,
                    MemargT) {
    return Ok{};
  }
  Result<> makeStore(Index,
                     const std::vector<Annotation>&,
                     Type,
                     int,
                     bool,
                     MemoryIdxT*,
                     MemargT) {
    return Ok{};
  }
  Result<> makeAtomicRMW(Index,
                         const std::vector<Annotation>&,
                         AtomicRMWOp,
                         Type,
                         int,
                         MemoryIdxT*,
                         MemargT) {
    return Ok{};
  }
  Result<> makeAtomicCmpxchg(
    Index, const std::vector<Annotation>&, Type, int, MemoryIdxT*, MemargT) {
    return Ok{};
  }
  Result<> makeAtomicWait(
    Index, const std::vector<Annotation>&, Type, MemoryIdxT*, MemargT) {
    return Ok{};
  }
  Result<> makeAtomicNotify(Index,
                            const std::vector<Annotation>&,
                            MemoryIdxT*,
                            MemargT) {
    return Ok{};
  }
  Result<> makeAtomicFence(Index, const std::vector<Annotation>&) {
    return Ok{};
  }
  Result<> makeSIMDExtract(Index,
                           const std::vector<Annotation>&,
                           SIMDExtractOp,
                           uint8_t) {
    return Ok{};
  }
  Result<> makeSIMDReplace(Index,
                           const std::vector<Annotation>&,
                           SIMDReplaceOp,
                           uint8_t) {
    return Ok{};
  }
  Result<> makeSIMDShuffle(Index,
                           const std::vector<Annotation>&,
                           const std::array<uint8_t, 16>&) {
    return Ok{};
  }
  Result<>
  makeSIMDTernary(Index, const std::vector<Annotation>&, SIMDTernaryOp) {
    return Ok{};
  }
  Result<> makeSIMDShift(Index, const std::vector<Annotation>&, SIMDShiftOp) {
    return Ok{};
  }
  Result<> makeSIMDLoad(
    Index, const std::vector<Annotation>&, SIMDLoadOp, MemoryIdxT*, MemargT) {
    return Ok{};
  }
  Result<> makeSIMDLoadStoreLane(Index,
                                 const std::vector<Annotation>&,
                                 SIMDLoadStoreLaneOp,
                                 MemoryIdxT*,
                                 MemargT,
                                 uint8_t) {
    return Ok{};
  }
  Result<>
  makeMemoryInit(Index, const std::vector<Annotation>&, MemoryIdxT*, DataIdxT) {
    return Ok{};
  }
  Result<> makeDataDrop(Index, const std::vector<Annotation>&, DataIdxT) {
    return Ok{};
  }

  Result<> makeMemoryCopy(Index,
                          const std::vector<Annotation>&,
                          MemoryIdxT*,
                          MemoryIdxT*) {
    return Ok{};
  }
  Result<> makeMemoryFill(Index, const std::vector<Annotation>&, MemoryIdxT*) {
    return Ok{};
  }
  template<typename TypeT>
  Result<> makePop(Index, const std::vector<Annotation>&, TypeT) {
    return Ok{};
  }
  Result<> makeCall(Index, const std::vector<Annotation>&, FuncIdxT, bool) {
    return Ok{};
  }
  template<typename TypeUseT>
  Result<> makeCallIndirect(
    Index, const std::vector<Annotation>&, TableIdxT*, TypeUseT, bool) {
    return Ok{};
  }
  Result<> makeBreak(Index, const std::vector<Annotation>&, LabelIdxT, bool) {
    return Ok{};
  }
  Result<> makeSwitch(Index,
                      const std::vector<Annotation>&,
                      const std::vector<LabelIdxT>&,
                      LabelIdxT) {
    return Ok{};
  }
  Result<> makeReturn(Index, const std::vector<Annotation>&) { return Ok{}; }
  template<typename HeapTypeT>
  Result<> makeRefNull(Index, const std::vector<Annotation>&, HeapTypeT) {
    return Ok{};
  }
  Result<> makeRefIsNull(Index, const std::vector<Annotation>&) { return Ok{}; }
  Result<> makeRefFunc(Index, const std::vector<Annotation>&, FuncIdxT) {
    return Ok{};
  }
  Result<> makeRefEq(Index, const std::vector<Annotation>&) { return Ok{}; }
  Result<> makeTableGet(Index, const std::vector<Annotation>&, TableIdxT*) {
    return Ok{};
  }
  Result<> makeTableSet(Index, const std::vector<Annotation>&, TableIdxT*) {
    return Ok{};
  }
  Result<> makeTableSize(Index, const std::vector<Annotation>&, TableIdxT*) {
    return Ok{};
  }
  Result<> makeTableGrow(Index, const std::vector<Annotation>&, TableIdxT*) {
    return Ok{};
  }
  Result<> makeTableFill(Index, const std::vector<Annotation>&, TableIdxT*) {
    return Ok{};
  }
  Result<>
  makeTableCopy(Index, const std::vector<Annotation>&, TableIdxT*, TableIdxT*) {
    return Ok{};
  }
  Result<>
  makeTableInit(Index, const std::vector<Annotation>&, TableIdxT*, ElemIdxT) {
    return Ok{};
  }
  Result<> makeThrow(Index, const std::vector<Annotation>&, TagIdxT) {
    return Ok{};
  }
  Result<> makeRethrow(Index, const std::vector<Annotation>&, LabelIdxT) {
    return Ok{};
  }
  Result<> makeThrowRef(Index, const std::vector<Annotation>&) { return Ok{}; }
  Result<> makeTupleMake(Index, const std::vector<Annotation>&, uint32_t) {
    return Ok{};
  }
  Result<>
  makeTupleExtract(Index, const std::vector<Annotation>&, uint32_t, uint32_t) {
    return Ok{};
  }
  Result<> makeTupleDrop(Index, const std::vector<Annotation>&, uint32_t) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<> makeCallRef(Index, const std::vector<Annotation>&, HeapTypeT, bool) {
    return Ok{};
  }
  Result<>
  makeRefI31(Index, const std::vector<Annotation>&, Shareability share) {
    return Ok{};
  }
  Result<> makeI31Get(Index, const std::vector<Annotation>&, bool) {
    return Ok{};
  }
  template<typename TypeT>
  Result<> makeRefTest(Index, const std::vector<Annotation>&, TypeT) {
    return Ok{};
  }
  template<typename TypeT>
  Result<> makeRefCast(Index, const std::vector<Annotation>&, TypeT) {
    return Ok{};
  }

  Result<> makeBrOn(Index, const std::vector<Annotation>&, LabelIdxT, BrOnOp) {
    return Ok{};
  }

  template<typename TypeT>
  Result<> makeBrOn(
    Index, const std::vector<Annotation>&, LabelIdxT, BrOnOp, TypeT, TypeT) {
    return Ok{};
  }

  template<typename HeapTypeT>
  Result<> makeStructNew(Index, const std::vector<Annotation>&, HeapTypeT) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<>
  makeStructNewDefault(Index, const std::vector<Annotation>&, HeapTypeT) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<> makeStructGet(
    Index, const std::vector<Annotation>&, HeapTypeT, FieldIdxT, bool) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<>
  makeStructSet(Index, const std::vector<Annotation>&, HeapTypeT, FieldIdxT) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<> makeArrayNew(Index, const std::vector<Annotation>&, HeapTypeT) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<>
  makeArrayNewDefault(Index, const std::vector<Annotation>&, HeapTypeT) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<>
  makeArrayNewData(Index, const std::vector<Annotation>&, HeapTypeT, DataIdxT) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<>
  makeArrayNewElem(Index, const std::vector<Annotation>&, HeapTypeT, ElemIdxT) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<> makeArrayNewFixed(Index,
                             const std::vector<Annotation>&,
                             HeapTypeT,
                             uint32_t) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<>
  makeArrayGet(Index, const std::vector<Annotation>&, HeapTypeT, bool) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<> makeArraySet(Index, const std::vector<Annotation>&, HeapTypeT) {
    return Ok{};
  }
  Result<> makeArrayLen(Index, const std::vector<Annotation>&) { return Ok{}; }
  template<typename HeapTypeT>
  Result<>
  makeArrayCopy(Index, const std::vector<Annotation>&, HeapTypeT, HeapTypeT) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<> makeArrayFill(Index, const std::vector<Annotation>&, HeapTypeT) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<> makeArrayInitData(Index,
                             const std::vector<Annotation>&,
                             HeapTypeT,
                             DataIdxT) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<> makeArrayInitElem(Index,
                             const std::vector<Annotation>&,
                             HeapTypeT,
                             ElemIdxT) {
    return Ok{};
  }
  Result<> makeRefAs(Index, const std::vector<Annotation>&, RefAsOp) {
    return Ok{};
  }
  Result<> makeStringNew(Index, const std::vector<Annotation>&, StringNewOp) {
    return Ok{};
  }
  Result<>
  makeStringConst(Index, const std::vector<Annotation>&, std::string_view) {
    return Ok{};
  }
  Result<>
  makeStringMeasure(Index, const std::vector<Annotation>&, StringMeasureOp) {
    return Ok{};
  }
  Result<>
  makeStringEncode(Index, const std::vector<Annotation>&, StringEncodeOp) {
    return Ok{};
  }
  Result<> makeStringConcat(Index, const std::vector<Annotation>&) {
    return Ok{};
  }
  Result<> makeStringEq(Index, const std::vector<Annotation>&, StringEqOp) {
    return Ok{};
  }
  Result<> makeStringWTF8Advance(Index, const std::vector<Annotation>&) {
    return Ok{};
  }
  Result<> makeStringWTF16Get(Index, const std::vector<Annotation>&) {
    return Ok{};
  }
  Result<> makeStringIterNext(Index, const std::vector<Annotation>&) {
    return Ok{};
  }
  Result<> makeStringSliceWTF(Index, const std::vector<Annotation>&) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<>
  makeContBind(Index, const std::vector<Annotation>&, HeapTypeT, HeapTypeT) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<> makeContNew(Index, const std::vector<Annotation>&, HeapTypeT) {
    return Ok{};
  }
  template<typename HeapTypeT>
  Result<> makeResume(Index,
                      const std::vector<Annotation>&,
                      HeapTypeT,
                      const TagLabelListT&) {
    return Ok{};
  }
  Result<> makeSuspend(Index, const std::vector<Annotation>&, TagIdxT) {
    return Ok{};
  }
};

struct NullCtx : NullTypeParserCtx, NullInstrParserCtx {
  Lexer in;
  NullCtx(const Lexer& in) : in(in) {}
  Result<> makeTypeUse(Index, std::optional<HeapTypeT>, ParamsT*, ResultsT*) {
    return Ok{};
  }
};

// Phase 1: Parse definition spans for top-level module elements and determine
// their indices and names.
struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx {
  using ExprT = Ok;
  using LimitsT = Limits;
  using ElemListT = Index;
  using DataStringT = std::vector<char>;
  using TableTypeT = TableType;
  using MemTypeT = MemType;

  Lexer in;

  // At this stage we only look at types to find implicit type definitions,
  // which are inserted directly into the context. We cannot materialize or
  // validate any types because we don't know what types exist yet.
  //
  // Declared module elements are inserted into the module, but their bodies are
  // not filled out until later parsing phases.
  Module& wasm;

  // The module element definitions we are parsing in this phase.
  std::vector<DefPos> recTypeDefs;
  std::vector<DefPos> typeDefs;
  std::vector<DefPos> funcDefs;
  std::vector<DefPos> tableDefs;
  std::vector<DefPos> memoryDefs;
  std::vector<DefPos> globalDefs;
  std::vector<DefPos> startDefs;
  std::vector<DefPos> elemDefs;
  std::vector<DefPos> dataDefs;
  std::vector<DefPos> tagDefs;

  // Positions of export definitions.
  std::vector<Index> exportDefs;

  // Positions of typeuses that might implicitly define new types.
  std::vector<Index> implicitTypeDefs;

  // Map table indices to the indices of their implicit, in-line element
  // segments. We need these to find associated segments in later parsing phases
  // where we can parse their types and instructions.
  std::unordered_map<Index, Index> implicitElemIndices;

  // Counters used for generating names for module elements.
  int funcCounter = 0;
  int tableCounter = 0;
  int memoryCounter = 0;
  int globalCounter = 0;
  int elemCounter = 0;
  int dataCounter = 0;
  int tagCounter = 0;

  // Used to verify that all imports come before all non-imports.
  bool hasNonImport = false;

  Result<> checkImport(Index pos, ImportNames* import) {
    if (import) {
      if (hasNonImport) {
        return in.err(pos, "import after non-import");
      }
    } else {
      hasNonImport = true;
    }
    return Ok{};
  }

  ParseDeclsCtx(Lexer& in, Module& wasm) : in(in), wasm(wasm) {}

  void addFuncType(SignatureT) {}
  void addContType(ContinuationT) {}
  void addStructType(StructT) {}
  void addArrayType(ArrayT) {}
  void setOpen() {}
  void setShared() {}
  Result<> addSubtype(HeapTypeT) { return Ok{}; }
  void finishTypeDef(Name name, Index pos) {
    // TODO: type annotations
    typeDefs.push_back({name, pos, Index(typeDefs.size()), {}});
  }
  size_t getRecGroupStartIndex() { return 0; }
  void addRecGroup(Index, size_t) {}
  void finishRectype(Index pos) {
    // TODO: type annotations
    recTypeDefs.push_back({{}, pos, Index(recTypeDefs.size()), {}});
  }

  Limits makeLimits(uint64_t n, std::optional<uint64_t> m) {
    return Limits{n, m};
  }

  Index makeElemList(TypeT) { return 0; }
  Index makeFuncElemList() { return 0; }
  void appendElem(Index& elems, ExprT) { ++elems; }
  void appendFuncElem(Index& elems, FuncIdxT) { ++elems; }

  Limits getLimitsFromElems(Index elems) { return {elems, elems}; }

  TableType makeTableType(Type addressType, Limits limits, TypeT) {
    return {addressType, limits};
  }

  std::vector<char> makeDataString() { return {}; }
  void appendDataString(std::vector<char>& data, std::string_view str) {
    data.insert(data.end(), str.begin(), str.end());
  }

  Limits getLimitsFromData(const std::vector<char>& data) {
    uint64_t size = (data.size() + Memory::kPageSize - 1) / Memory::kPageSize;
    return {size, size};
  }

  MemType makeMemType(Type addressType, Limits limits, bool shared) {
    return {addressType, limits, shared};
  }

  Result<TypeUseT>
  makeTypeUse(Index pos, std::optional<HeapTypeT> type, ParamsT*, ResultsT*) {
    if (!type) {
      implicitTypeDefs.push_back(pos);
    }
    return Ok{};
  }

  Result<Function*> addFuncDecl(Index pos, Name name, ImportNames* importNames);
  Result<> addFunc(Name name,
                   const std::vector<Name>& exports,
                   ImportNames* import,
                   TypeUseT type,
                   std::optional<LocalsT>,
                   std::vector<Annotation>&&,
                   Index pos);

  Result<Table*> addTableDecl(Index pos,
                              Name name,
                              ImportNames* importNames,
                              TableType limits);
  Result<>
  addTable(Name, const std::vector<Name>&, ImportNames*, TableType, Index);

  // TODO: Record index of implicit elem for use when parsing types and instrs.
  Result<> addImplicitElems(TypeT, ElemListT&& elems);

  Result<Memory*>
  addMemoryDecl(Index pos, Name name, ImportNames* importNames, MemType type);

  Result<> addMemory(Name name,
                     const std::vector<Name>& exports,
                     ImportNames* import,
                     MemType type,
                     Index pos);

  Result<> addImplicitData(DataStringT&& data);

  Result<Global*> addGlobalDecl(Index pos, Name name, ImportNames* importNames);

  Result<> addGlobal(Name name,
                     const std::vector<Name>& exports,
                     ImportNames* import,
                     GlobalTypeT,
                     std::optional<ExprT>,
                     Index pos);

  Result<> addStart(FuncIdxT, Index pos) {
    if (!startDefs.empty()) {
      return Err{"unexpected extra 'start' function"};
    }
    // TODO: start function annotations.
    startDefs.push_back({{}, pos, 0, {}});
    return Ok{};
  }

  Result<> addElem(Name, TableIdxT*, std::optional<ExprT>, ElemListT&&, Index);

  Result<> addDeclareElem(Name, ElemListT&&, Index) { return Ok{}; }

  Result<> addData(Name name,
                   MemoryIdxT*,
                   std::optional<ExprT>,
                   std::vector<char>&& data,
                   Index pos);

  Result<Tag*> addTagDecl(Index pos, Name name, ImportNames* importNames);

  Result<> addTag(Name name,
                  const std::vector<Name>& exports,
                  ImportNames* import,
                  TypeUseT type,
                  Index pos);

  Result<> addExport(Index pos, Ok, Name, ExternalKind) {
    exportDefs.push_back(pos);
    return Ok{};
  }
};

// Phase 2: Parse type definitions into a TypeBuilder.
struct ParseTypeDefsCtx : TypeParserCtx<ParseTypeDefsCtx> {
  Lexer in;

  // We update slots in this builder as we parse type definitions.
  TypeBuilder& builder;

  // Parse the names of types and fields as we go.
  std::vector<TypeNames> names;

  // The index of the subtype definition we are parsing.
  Index index = 0;

  ParseTypeDefsCtx(Lexer& in, TypeBuilder& builder, const IndexMap& typeIndices)
    : TypeParserCtx<ParseTypeDefsCtx>(typeIndices), in(in), builder(builder),
      names(builder.size()) {}

  TypeT makeRefType(HeapTypeT ht, Nullability nullability) {
    return builder.getTempRefType(ht, nullability);
  }

  TypeT makeTupleType(const std::vector<Type> types) {
    return builder.getTempTupleType(types);
  }

  Result<HeapTypeT> getHeapTypeFromIdx(Index idx) {
    if (idx >= builder.size()) {
      return in.err("type index out of bounds");
    }
    return builder[idx];
  }

  void addFuncType(SignatureT& type) { builder[index] = type; }
  void addContType(ContinuationT& type) { builder[index] = type; }

  void addStructType(StructT& type) {
    auto& [fieldNames, str] = type;
    builder[index] = str;
    for (Index i = 0; i < fieldNames.size(); ++i) {
      if (auto name = fieldNames[i]; name.is()) {
        names[index].fieldNames[i] = name;
      }
    }
  }

  void addArrayType(ArrayT& type) { builder[index] = type; }

  void setOpen() { builder[index].setOpen(); }

  void setShared() { builder[index].setShared(); }

  Result<> addSubtype(HeapTypeT super) {
    builder[index].subTypeOf(super);
    return Ok{};
  }

  void finishTypeDef(Name name, Index pos) { names[index++].name = name; }

  size_t getRecGroupStartIndex() { return index; }

  void addRecGroup(Index start, size_t len) {
    builder.createRecGroup(start, len);
  }

  void finishRectype(Index) {}
};

// Phase 3: Parse type uses to find implicitly defined types.
struct ParseImplicitTypeDefsCtx : TypeParserCtx<ParseImplicitTypeDefsCtx> {
  using TypeUseT = Ok;

  Lexer in;

  // Types parsed so far.
  std::vector<HeapType>& types;

  // Map typeuse positions without an explicit type to the correct type.
  std::unordered_map<Index, HeapType>& implicitTypes;

  // Map signatures to the first defined heap type they match.
  std::unordered_map<Signature, HeapType> sigTypes;

  ParseImplicitTypeDefsCtx(Lexer& in,
                           std::vector<HeapType>& types,
                           std::unordered_map<Index, HeapType>& implicitTypes,
                           const IndexMap& typeIndices)
    : TypeParserCtx<ParseImplicitTypeDefsCtx>(typeIndices), in(in),
      types(types), implicitTypes(implicitTypes) {
    for (auto type : types) {
      if (type.isSignature() && type.getRecGroup().size() == 1 &&
          !type.getDeclaredSuperType() && !type.isOpen() && !type.isShared()) {
        sigTypes.insert({type.getSignature(), type});
      }
    }
  }

  Result<HeapTypeT> getHeapTypeFromIdx(Index idx) {
    if (idx >= types.size()) {
      return in.err("type index out of bounds");
    }
    return types[idx];
  }

  Result<TypeUseT> makeTypeUse(Index pos,
                               std::optional<HeapTypeT>,
                               ParamsT* params,
                               ResultsT* results) {
    std::vector<Type> paramTypes;
    if (params) {
      paramTypes = getUnnamedTypes(*params);
    }

    std::vector<Type> resultTypes;
    if (results) {
      resultTypes = *results;
    }

    auto sig = Signature(Type(paramTypes), Type(resultTypes));
    auto [it, inserted] = sigTypes.insert({sig, HeapType::func});
    if (inserted) {
      auto type = HeapType(sig);
      it->second = type;
      types.push_back(type);
    }
    implicitTypes.insert({pos, it->second});

    return Ok{};
  }
};

// Phase 4: Parse and set the types of module elements.
struct ParseModuleTypesCtx : TypeParserCtx<ParseModuleTypesCtx>,
                             NullInstrParserCtx {
  // In this phase we have constructed all the types, so we can materialize and
  // validate them when they are used.

  using GlobalTypeT = GlobalType;
  using TableTypeT = Type;
  using TypeUseT = TypeUse;

  using ElemListT = Type;

  Lexer in;

  Module& wasm;

  const std::vector<HeapType>& types;
  const std::unordered_map<Index, HeapType>& implicitTypes;
  const std::unordered_map<Index, Index>& implicitElemIndices;

  // The index of the current type.
  Index index = 0;

  ParseModuleTypesCtx(
    Lexer& in,
    Module& wasm,
    const std::vector<HeapType>& types,
    const std::unordered_map<Index, HeapType>& implicitTypes,
    const std::unordered_map<Index, Index>& implicitElemIndices,
    const IndexMap& typeIndices)
    : TypeParserCtx<ParseModuleTypesCtx>(typeIndices), in(in), wasm(wasm),
      types(types), implicitTypes(implicitTypes),
      implicitElemIndices(implicitElemIndices) {}

  bool skipFunctionBody() { return true; }

  Result<HeapTypeT> getHeapTypeFromIdx(Index idx) {
    if (idx >= types.size()) {
      return in.err("type index out of bounds");
    }
    return types[idx];
  }

  Result<TypeUseT> makeTypeUse(Index pos,
                               std::optional<HeapTypeT> type,
                               ParamsT* params,
                               ResultsT* results) {
    std::vector<Name> ids;
    if (params) {
      ids.reserve(params->size());
      for (auto& p : *params) {
        ids.push_back(p.name);
      }
    }

    if (type) {
      return TypeUse{*type, ids};
    }

    auto it = implicitTypes.find(pos);
    assert(it != implicitTypes.end());

    return TypeUse{it->second, ids};
  }

  Result<HeapType> getBlockTypeFromTypeUse(Index pos, TypeUse use) {
    return use.type;
  }

  GlobalTypeT makeGlobalType(Mutability mutability, TypeT type) {
    return {mutability, type};
  }

  Type makeElemList(Type type) { return type; }
  Type makeFuncElemList() { return Type(HeapType::func, Nullable); }
  void appendElem(ElemListT&, ExprT) {}
  void appendFuncElem(ElemListT&, FuncIdxT) {}

  LimitsT getLimitsFromElems(ElemListT) { return Ok{}; }

  Type makeTableType(Type addressType, LimitsT, Type type) { return type; }

  LimitsT getLimitsFromData(DataStringT) { return Ok{}; }
  MemTypeT makeMemType(Type, LimitsT, bool) { return Ok{}; }

  Result<> addFunc(Name name,
                   const std::vector<Name>&,
                   ImportNames*,
                   TypeUse type,
                   std::optional<LocalsT> locals,
                   std::vector<Annotation>&&,
                   Index pos) {
    auto& f = wasm.functions[index];
    if (!type.type.isSignature()) {
      return in.err(pos, "expected signature type");
    }
    f->type = type.type;
    for (Index i = 0; i < type.names.size(); ++i) {
      if (type.names[i].is()) {
        f->setLocalName(i, type.names[i]);
      }
    }
    if (locals) {
      for (auto& l : *locals) {
        Builder::addVar(f.get(), l.name, l.type);
      }
    }
    return Ok{};
  }

  Result<> addTable(
    Name, const std::vector<Name>&, ImportNames*, Type ttype, Index pos) {
    auto& t = wasm.tables[index];
    if (!ttype.isRef()) {
      return in.err(pos, "expected reference type");
    }
    t->type = ttype;
    return Ok{};
  }

  Result<> addImplicitElems(Type type, ElemListT&&) {
    auto& t = wasm.tables[index];
    auto& e = wasm.elementSegments[implicitElemIndices.at(index)];
    e->type = t->type;
    return Ok{};
  }

  Result<>
  addMemory(Name, const std::vector<Name>&, ImportNames*, MemTypeT, Index) {
    return Ok{};
  }

  Result<> addImplicitData(DataStringT&& data) { return Ok{}; }

  Result<> addGlobal(Name,
                     const std::vector<Name>&,
                     ImportNames*,
                     GlobalType type,
                     std::optional<ExprT>,
                     Index) {
    auto& g = wasm.globals[index];
    g->mutable_ = type.mutability;
    g->type = type.type;
    return Ok{};
  }

  Result<>
  addElem(Name, TableIdxT*, std::optional<ExprT>, ElemListT&& type, Index) {
    auto& e = wasm.elementSegments[index];
    e->type = type;
    return Ok{};
  }

  Result<> addDeclareElem(Name, ElemListT&&, Index) { return Ok{}; }

  Result<>
  addTag(Name, const std::vector<Name>&, ImportNames*, TypeUse use, Index pos) {
    auto& t = wasm.tags[index];
    if (!use.type.isSignature()) {
      return in.err(pos, "tag type must be a signature");
    }
    t->sig = use.type.getSignature();
    return Ok{};
  }
};

// Phase 5: Parse module element definitions, including instructions.
struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
  using GlobalTypeT = Ok;
  using TableTypeT = Ok;
  using TypeUseT = HeapType;

  using FieldIdxT = Index;
  using FuncIdxT = Name;
  using LocalIdxT = Index;
  using LabelIdxT = Index;
  using GlobalIdxT = Name;
  using TableIdxT = Name;
  using MemoryIdxT = Name;
  using ElemIdxT = Name;
  using DataIdxT = Name;
  using TagIdxT = Name;

  using MemargT = Memarg;

  using ExprT = Expression*;
  using ElemListT = std::vector<Expression*>;

  struct CatchInfo;
  using CatchT = CatchInfo;
  using CatchListT = std::vector<CatchInfo>;

  using TagLabelListT = std::vector<std::pair<TagIdxT, LabelIdxT>>;

  Lexer in;

  Module& wasm;
  Builder builder;

  const std::vector<HeapType>& types;
  const std::unordered_map<Index, HeapType>& implicitTypes;
  const std::unordered_map<HeapType, std::unordered_map<Name, Index>>&
    typeNames;
  const std::unordered_map<Index, Index>& implicitElemIndices;

  std::unordered_map<std::string_view, Index> debugSymbolNameIndices;
  std::unordered_map<std::string_view, Index> debugFileIndices;

  // The index of the current module element.
  Index index = 0;

  // The current function being parsed, used to create scratch locals, type
  // local.get, etc.
  Function* func = nullptr;

  IRBuilder irBuilder;

  Result<> visitFunctionStart(Function* func) {
    this->func = func;
    CHECK_ERR(irBuilder.visitFunctionStart(func));
    return Ok{};
  }

  ParseDefsCtx(
    Lexer& in,
    Module& wasm,
    const std::vector<HeapType>& types,
    const std::unordered_map<Index, HeapType>& implicitTypes,
    const std::unordered_map<HeapType, std::unordered_map<Name, Index>>&
      typeNames,
    const std::unordered_map<Index, Index>& implicitElemIndices,
    const IndexMap& typeIndices)
    : TypeParserCtx(typeIndices), in(in), wasm(wasm), builder(wasm),
      types(types), implicitTypes(implicitTypes), typeNames(typeNames),
      implicitElemIndices(implicitElemIndices), irBuilder(wasm) {}

  template<typename T> Result<T> withLoc(Index pos, Result<T> res) {
    if (auto err = res.getErr()) {
      return in.err(pos, err->msg);
    }
    return res;
  }

  template<typename T> Result<T> withLoc(Result<T> res) {
    return withLoc(in.getPos(), res);
  }

  HeapType getBlockTypeFromResult(const std::vector<Type> results) {
    assert(results.size() == 1);
    return HeapType(Signature(Type::none, results[0]));
  }

  Result<HeapType> getBlockTypeFromTypeUse(Index pos, HeapType type) {
    assert(type.isSignature());
    if (type.getSignature().params != Type::none) {
      return in.err(pos, "block parameters not yet supported");
    }
    // TODO: Once we support block parameters, return an error here if any of
    // them are named.
    return type;
  }

  GlobalTypeT makeGlobalType(Mutability, TypeT) { return Ok{}; }

  std::vector<Expression*> makeElemList(TypeT) { return {}; }
  std::vector<Expression*> makeFuncElemList() { return {}; }
  void appendElem(std::vector<Expression*>& elems, Expression* expr) {
    elems.push_back(expr);
  }
  void appendFuncElem(std::vector<Expression*>& elems, Name func) {
    auto type = wasm.getFunction(func)->type;
    elems.push_back(builder.makeRefFunc(func, type));
  }

  LimitsT getLimitsFromElems(std::vector<Expression*>& elems) { return Ok{}; }

  TableTypeT makeTableType(Type, LimitsT, Type) { return Ok{}; }

  struct CatchInfo {
    Name tag;
    Index label;
    bool isRef;
  };

  std::vector<CatchInfo> makeCatchList() { return {}; }
  void appendCatch(std::vector<CatchInfo>& list, CatchInfo info) {
    list.push_back(info);
  }
  CatchInfo makeCatch(Name tag, Index label) { return {tag, label, false}; }
  CatchInfo makeCatchRef(Name tag, Index label) { return {tag, label, true}; }
  CatchInfo makeCatchAll(Index label) { return {{}, label, false}; }
  CatchInfo makeCatchAllRef(Index label) { return {{}, label, true}; }

  TagLabelListT makeTagLabelList() { return {}; }
  void appendTagLabel(TagLabelListT& tagLabels, Name tag, Index label) {
    tagLabels.push_back({tag, label});
  }

  Result<HeapTypeT> getHeapTypeFromIdx(Index idx) {
    if (idx >= types.size()) {
      return in.err("type index out of bounds");
    }
    return types[idx];
  }

  Result<Index> getFieldFromIdx(HeapType type, uint32_t idx) {
    if (!type.isStruct()) {
      return in.err("expected struct type");
    }
    if (idx >= type.getStruct().fields.size()) {
      return in.err("struct index out of bounds");
    }
    return idx;
  }

  Result<Index> getFieldFromName(HeapType type, Name name) {
    if (auto typeIt = typeNames.find(type); typeIt != typeNames.end()) {
      const auto& fieldIdxs = typeIt->second;
      if (auto fieldIt = fieldIdxs.find(name); fieldIt != fieldIdxs.end()) {
        return fieldIt->second;
      }
    }
    return in.err("unrecognized field name");
  }

  Result<Index> getLocalFromIdx(uint32_t idx) {
    if (!func) {
      return in.err("cannot access locals outside of a function");
    }
    if (idx >= func->getNumLocals()) {
      return in.err("local index out of bounds");
    }
    return idx;
  }

  Result<Name> getFuncFromIdx(uint32_t idx) {
    if (idx >= wasm.functions.size()) {
      return in.err("function index out of bounds");
    }
    return wasm.functions[idx]->name;
  }

  Result<Name> getFuncFromName(Name name) {
    if (!wasm.getFunctionOrNull(name)) {
      return in.err("function $" + name.toString() + " does not exist");
    }
    return name;
  }

  Result<Index> getLocalFromName(Name name) {
    if (!func) {
      return in.err("cannot access locals outside of a function");
    }
    if (!func->hasLocalIndex(name)) {
      return in.err("local $" + name.toString() + " does not exist");
    }
    return func->getLocalIndex(name);
  }

  Result<Name> getGlobalFromIdx(uint32_t idx) {
    if (idx >= wasm.globals.size()) {
      return in.err("global index out of bounds");
    }
    return wasm.globals[idx]->name;
  }

  Result<Name> getGlobalFromName(Name name) {
    if (!wasm.getGlobalOrNull(name)) {
      return in.err("global $" + name.toString() + " does not exist");
    }
    return name;
  }

  Result<Name> getTableFromIdx(uint32_t idx) {
    if (idx >= wasm.tables.size()) {
      return in.err("table index out of bounds");
    }
    return wasm.tables[idx]->name;
  }

  Result<Name> getTableFromName(Name name) {
    if (!wasm.getTableOrNull(name)) {
      return in.err("table $" + name.toString() + " does not exist");
    }
    return name;
  }

  Result<Name> getMemoryFromIdx(uint32_t idx) {
    if (idx >= wasm.memories.size()) {
      return in.err("memory index out of bounds");
    }
    return wasm.memories[idx]->name;
  }

  Result<Name> getMemoryFromName(Name name) {
    if (!wasm.getMemoryOrNull(name)) {
      return in.err("memory $" + name.toString() + " does not exist");
    }
    return name;
  }

  Result<Name> getElemFromIdx(uint32_t idx) {
    if (idx >= wasm.elementSegments.size()) {
      return in.err("elem index out of bounds");
    }
    return wasm.elementSegments[idx]->name;
  }

  Result<Name> getElemFromName(Name name) {
    if (!wasm.getElementSegmentOrNull(name)) {
      return in.err("elem $" + name.toString() + " does not exist");
    }
    return name;
  }

  Result<Name> getDataFromIdx(uint32_t idx) {
    if (idx >= wasm.dataSegments.size()) {
      return in.err("data index out of bounds");
    }
    return wasm.dataSegments[idx]->name;
  }

  Result<Name> getDataFromName(Name name) {
    if (!wasm.getDataSegmentOrNull(name)) {
      return in.err("data $" + name.toString() + " does not exist");
    }
    return name;
  }

  Result<Index> getLabelFromIdx(uint32_t idx, bool) { return idx; }

  Result<Index> getLabelFromName(Name name, bool inDelegate) {
    return irBuilder.getLabelIndex(name, inDelegate);
  }

  Result<Name> getTagFromIdx(uint32_t idx) {
    if (idx >= wasm.tags.size()) {
      return in.err("tag index out of bounds");
    }
    return wasm.tags[idx]->name;
  }

  Result<Name> getTagFromName(Name name) {
    if (!wasm.getTagOrNull(name)) {
      return in.err("tag $" + name.toString() + " does not exist");
    }
    return name;
  }

  Result<TypeUseT> makeTypeUse(Index pos,
                               std::optional<HeapTypeT> type,
                               ParamsT* params,
                               ResultsT* results);

  Result<> addFunc(Name,
                   const std::vector<Name>&,
                   ImportNames*,
                   TypeUseT,
                   std::optional<LocalsT>,
                   std::vector<Annotation>&&,
                   Index) {
    return Ok{};
  }

  Result<>
  addTable(Name, const std::vector<Name>&, ImportNames*, TableTypeT, Index) {
    return Ok{};
  }

  Result<>
  addMemory(Name, const std::vector<Name>&, ImportNames*, TableTypeT, Index) {
    return Ok{};
  }

  Result<> addGlobal(Name,
                     const std::vector<Name>&,
                     ImportNames*,
                     GlobalTypeT,
                     std::optional<ExprT> exp,
                     Index);

  Result<> addStart(Name name, Index pos) {
    wasm.start = name;
    return Ok{};
  }

  Result<> addImplicitElems(Type type, std::vector<Expression*>&& elems);

  Result<> addDeclareElem(Name, std::vector<Expression*>&&, Index) {
    // TODO: Validate that referenced functions appear in a declarative element
    // segment.
    return Ok{};
  }

  Result<> addElem(Name,
                   Name* table,
                   std::optional<Expression*> offset,
                   std::vector<Expression*>&& elems,
                   Index pos);

  Result<>
  addData(Name, Name* mem, std::optional<ExprT> offset, DataStringT, Index pos);

  Result<>
  addTag(Name, const std::vector<Name>, ImportNames*, TypeUseT, Index) {
    return Ok{};
  }

  Result<> addExport(Index pos, Name value, Name name, ExternalKind kind) {
    if (wasm.getExportOrNull(name)) {
      return in.err(pos, "duplicate export");
    }
    wasm.addExport(builder.makeExport(name, value, kind));
    return Ok{};
  }

  Result<Index> addScratchLocal(Index pos, Type type) {
    if (!func) {
      return in.err(pos,
                    "scratch local required, but there is no function context");
    }
    Name name = Names::getValidLocalName(*func, "scratch");
    return Builder::addVar(func, name, type);
  }

  Result<Expression*> makeExpr() { return withLoc(irBuilder.build()); }

  Memarg getMemarg(uint64_t offset, uint32_t align) { return {offset, align}; }

  Result<Name> getTable(Index pos, Name* table) {
    if (table) {
      return *table;
    }
    if (wasm.tables.empty()) {
      return in.err(pos, "table required, but there is no table");
    }
    return wasm.tables[0]->name;
  }

  Result<Name> getMemory(Index pos, Name* mem) {
    if (mem) {
      return *mem;
    }
    if (wasm.memories.empty()) {
      return in.err(pos, "memory required, but there is no memory");
    }
    return wasm.memories[0]->name;
  }

  void setSrcLoc(const std::vector<Annotation>& annotations) {
    const Annotation* annotation = nullptr;
    for (auto& a : annotations) {
      if (a.kind == srcAnnotationKind) {
        annotation = &a;
      }
    }
    if (!annotation) {
      return;
    }
    Lexer lexer(annotation->contents);
    if (lexer.empty()) {
      irBuilder.setDebugLocation(std::nullopt);
      return;
    }

    auto contents = lexer.next();

    auto fileSize = contents.find(':');
    if (fileSize == 0 || fileSize == contents.npos) {
      return;
    }
    auto file = contents.substr(0, fileSize);
    contents = contents.substr(fileSize + 1);

    auto lineSize = contents.find(':');
    if (lineSize == contents.npos) {
      return;
    }
    lexer = Lexer(contents.substr(0, lineSize));
    auto line = lexer.takeU32();
    if (!line || !lexer.empty()) {
      return;
    }
    contents = contents.substr(lineSize + 1);

    auto colSize = contents.find(':');
    if (colSize == contents.npos) {
      colSize = contents.size();
      if (colSize == 0) {
        return;
      }
    }
    lexer = Lexer(contents.substr(0, colSize));
    auto col = lexer.takeU32();
    if (!col) {
      return;
    }

    std::optional<BinaryLocation> symbolNameIndex;
    if (colSize != contents.size()) {
      contents = contents.substr(colSize + 1);
      auto symbolName = contents;
      auto [it, inserted] = debugSymbolNameIndices.insert(
        {symbolName, debugSymbolNameIndices.size()});
      if (inserted) {
        assert(wasm.debugInfoSymbolNames.size() == it->second);
        wasm.debugInfoSymbolNames.push_back(std::string(symbolName));
      }
      symbolNameIndex = it->second;
    }

    // TODO: If we ever parallelize the parse, access to
    // `wasm.debugInfoFileNames` will have to be protected by a lock.
    auto [it, inserted] =
      debugFileIndices.insert({file, debugFileIndices.size()});
    if (inserted) {
      assert(wasm.debugInfoFileNames.size() == it->second);
      wasm.debugInfoFileNames.push_back(std::string(file));
    }
    irBuilder.setDebugLocation(
      Function::DebugLocation({it->second, *line, *col, symbolNameIndex}));
  }

  Result<> makeBlock(Index pos,
                     const std::vector<Annotation>& annotations,
                     std::optional<Name> label,
                     HeapType type) {
    // TODO: validate labels?
    // TODO: Move error on input types to here?
    return withLoc(pos,
                   irBuilder.makeBlock(label ? *label : Name{},
                                       type.getSignature().results));
  }

  Result<> makeIf(Index pos,
                  const std::vector<Annotation>& annotations,
                  std::optional<Name> label,
                  HeapType type) {
    // TODO: validate labels?
    // TODO: Move error on input types to here?
    return withLoc(
      pos,
      irBuilder.makeIf(label ? *label : Name{}, type.getSignature().results));
  }

  Result<> visitElse() { return withLoc(irBuilder.visitElse()); }

  Result<> makeLoop(Index pos,
                    const std::vector<Annotation>& annotations,
                    std::optional<Name> label,
                    HeapType type) {
    // TODO: validate labels?
    // TODO: Move error on input types to here?
    return withLoc(
      pos,
      irBuilder.makeLoop(label ? *label : Name{}, type.getSignature().results));
  }

  Result<> makeTry(Index pos,
                   const std::vector<Annotation>& annotations,
                   std::optional<Name> label,
                   HeapType type) {
    // TODO: validate labels?
    // TODO: Move error on input types to here?
    return withLoc(
      pos,
      irBuilder.makeTry(label ? *label : Name{}, type.getSignature().results));
  }

  Result<> makeTryTable(Index pos,
                        const std::vector<Annotation>& annotations,
                        std::optional<Name> label,
                        HeapType type,
                        const std::vector<CatchInfo>& info) {
    std::vector<Name> tags;
    std::vector<Index> labels;
    std::vector<bool> isRefs;
    for (auto& info : info) {
      tags.push_back(info.tag);
      labels.push_back(info.label);
      isRefs.push_back(info.isRef);
    }
    return withLoc(pos,
                   irBuilder.makeTryTable(label ? *label : Name{},
                                          type.getSignature().results,
                                          tags,
                                          labels,
                                          isRefs));
  }

  Result<> visitCatch(Index pos, Name tag) {
    return withLoc(pos, irBuilder.visitCatch(tag));
  }

  Result<> visitCatchAll(Index pos) {
    return withLoc(pos, irBuilder.visitCatchAll());
  }

  Result<> visitDelegate(Index pos, Index label) {
    return withLoc(pos, irBuilder.visitDelegate(label));
  }

  Result<> visitEnd() { return withLoc(irBuilder.visitEnd()); }

  Result<> makeUnreachable(Index pos,
                           const std::vector<Annotation>& annotations) {
    return withLoc(pos, irBuilder.makeUnreachable());
  }

  Result<> makeNop(Index pos, const std::vector<Annotation>& annotations) {
    return withLoc(pos, irBuilder.makeNop());
  }

  Result<> makeBinary(Index pos,
                      const std::vector<Annotation>& annotations,
                      BinaryOp op) {
    return withLoc(pos, irBuilder.makeBinary(op));
  }

  Result<>
  makeUnary(Index pos, const std::vector<Annotation>& annotations, UnaryOp op) {
    return withLoc(pos, irBuilder.makeUnary(op));
  }

  Result<> makeSelect(Index pos,
                      const std::vector<Annotation>& annotations,
                      std::vector<Type>* res) {
    if (res && res->size()) {
      if (res->size() > 1) {
        return in.err(pos, "select may not have more than one result type");
      }
      return withLoc(pos, irBuilder.makeSelect((*res)[0]));
    }
    return withLoc(pos, irBuilder.makeSelect());
  }

  Result<> makeDrop(Index pos, const std::vector<Annotation>& annotations) {
    return withLoc(pos, irBuilder.makeDrop());
  }

  Result<> makeMemorySize(Index pos,
                          const std::vector<Annotation>& annotations,
                          Name* mem) {
    auto m = getMemory(pos, mem);
    CHECK_ERR(m);
    return withLoc(pos, irBuilder.makeMemorySize(*m));
  }

  Result<> makeMemoryGrow(Index pos,
                          const std::vector<Annotation>& annotations,
                          Name* mem) {
    auto m = getMemory(pos, mem);
    CHECK_ERR(m);
    return withLoc(pos, irBuilder.makeMemoryGrow(*m));
  }

  Result<> makeLocalGet(Index pos,
                        const std::vector<Annotation>& annotations,
                        Index local) {
    return withLoc(pos, irBuilder.makeLocalGet(local));
  }

  Result<> makeLocalTee(Index pos,
                        const std::vector<Annotation>& annotations,
                        Index local) {
    return withLoc(pos, irBuilder.makeLocalTee(local));
  }

  Result<> makeLocalSet(Index pos,
                        const std::vector<Annotation>& annotations,
                        Index local) {
    return withLoc(pos, irBuilder.makeLocalSet(local));
  }

  Result<> makeGlobalGet(Index pos,
                         const std::vector<Annotation>& annotations,
                         Name global) {
    return withLoc(pos, irBuilder.makeGlobalGet(global));
  }

  Result<> makeGlobalSet(Index pos,
                         const std::vector<Annotation>& annotations,
                         Name global) {
    assert(wasm.getGlobalOrNull(global));
    return withLoc(pos, irBuilder.makeGlobalSet(global));
  }

  Result<> makeI32Const(Index pos,
                        const std::vector<Annotation>& annotations,
                        uint32_t c) {
    return withLoc(pos, irBuilder.makeConst(Literal(c)));
  }

  Result<> makeI64Const(Index pos,
                        const std::vector<Annotation>& annotations,
                        uint64_t c) {
    return withLoc(pos, irBuilder.makeConst(Literal(c)));
  }

  Result<>
  makeF32Const(Index pos, const std::vector<Annotation>& annotations, float c) {
    return withLoc(pos, irBuilder.makeConst(Literal(c)));
  }

  Result<> makeF64Const(Index pos,
                        const std::vector<Annotation>& annotations,
                        double c) {
    return withLoc(pos, irBuilder.makeConst(Literal(c)));
  }

  Result<> makeI8x16Const(Index pos,
                          const std::vector<Annotation>& annotations,
                          const std::array<uint8_t, 16>& vals) {
    std::array<Literal, 16> lanes;
    for (size_t i = 0; i < 16; ++i) {
      lanes[i] = Literal(uint32_t(vals[i]));
    }
    return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
  }

  Result<> makeI16x8Const(Index pos,
                          const std::vector<Annotation>& annotations,
                          const std::array<uint16_t, 8>& vals) {
    std::array<Literal, 8> lanes;
    for (size_t i = 0; i < 8; ++i) {
      lanes[i] = Literal(uint32_t(vals[i]));
    }
    return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
  }

  Result<> makeI32x4Const(Index pos,
                          const std::vector<Annotation>& annotations,
                          const std::array<uint32_t, 4>& vals) {
    std::array<Literal, 4> lanes;
    for (size_t i = 0; i < 4; ++i) {
      lanes[i] = Literal(vals[i]);
    }
    return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
  }

  Result<> makeI64x2Const(Index pos,
                          const std::vector<Annotation>& annotations,
                          const std::array<uint64_t, 2>& vals) {
    std::array<Literal, 2> lanes;
    for (size_t i = 0; i < 2; ++i) {
      lanes[i] = Literal(vals[i]);
    }
    return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
  }

  Result<> makeF32x4Const(Index pos,
                          const std::vector<Annotation>& annotations,
                          const std::array<float, 4>& vals) {
    std::array<Literal, 4> lanes;
    for (size_t i = 0; i < 4; ++i) {
      lanes[i] = Literal(vals[i]);
    }
    return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
  }

  Result<> makeF64x2Const(Index pos,
                          const std::vector<Annotation>& annotations,
                          const std::array<double, 2>& vals) {
    std::array<Literal, 2> lanes;
    for (size_t i = 0; i < 2; ++i) {
      lanes[i] = Literal(vals[i]);
    }
    return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
  }

  Result<> makeLoad(Index pos,
                    const std::vector<Annotation>& annotations,
                    Type type,
                    bool signed_,
                    int bytes,
                    bool isAtomic,
                    Name* mem,
                    Memarg memarg) {
    auto m = getMemory(pos, mem);
    CHECK_ERR(m);
    if (isAtomic) {
      return withLoc(pos,
                     irBuilder.makeAtomicLoad(bytes, memarg.offset, type, *m));
    }
    return withLoc(pos,
                   irBuilder.makeLoad(
                     bytes, signed_, memarg.offset, memarg.align, type, *m));
  }

  Result<> makeStore(Index pos,
                     const std::vector<Annotation>& annotations,
                     Type type,
                     int bytes,
                     bool isAtomic,
                     Name* mem,
                     Memarg memarg) {
    auto m = getMemory(pos, mem);
    CHECK_ERR(m);
    if (isAtomic) {
      return withLoc(pos,
                     irBuilder.makeAtomicStore(bytes, memarg.offset, type, *m));
    }
    return withLoc(
      pos, irBuilder.makeStore(bytes, memarg.offset, memarg.align, type, *m));
  }

  Result<> makeAtomicRMW(Index pos,
                         const std::vector<Annotation>& annotations,
                         AtomicRMWOp op,
                         Type type,
                         int bytes,
                         Name* mem,
                         Memarg memarg) {
    auto m = getMemory(pos, mem);
    CHECK_ERR(m);
    return withLoc(pos,
                   irBuilder.makeAtomicRMW(op, bytes, memarg.offset, type, *m));
  }

  Result<> makeAtomicCmpxchg(Index pos,
                             const std::vector<Annotation>& annotations,
                             Type type,
                             int bytes,
                             Name* mem,
                             Memarg memarg) {
    auto m = getMemory(pos, mem);
    CHECK_ERR(m);
    return withLoc(pos,
                   irBuilder.makeAtomicCmpxchg(bytes, memarg.offset, type, *m));
  }

  Result<> makeAtomicWait(Index pos,
                          const std::vector<Annotation>& annotations,
                          Type type,
                          Name* mem,
                          Memarg memarg) {
    auto m = getMemory(pos, mem);
    CHECK_ERR(m);
    return withLoc(pos, irBuilder.makeAtomicWait(type, memarg.offset, *m));
  }

  Result<> makeAtomicNotify(Index pos,
                            const std::vector<Annotation>& annotations,
                            Name* mem,
                            Memarg memarg) {
    auto m = getMemory(pos, mem);
    CHECK_ERR(m);
    return withLoc(pos, irBuilder.makeAtomicNotify(memarg.offset, *m));
  }

  Result<> makeAtomicFence(Index pos,
                           const std::vector<Annotation>& annotations) {
    return withLoc(pos, irBuilder.makeAtomicFence());
  }

  Result<> makeSIMDExtract(Index pos,
                           const std::vector<Annotation>& annotations,
                           SIMDExtractOp op,
                           uint8_t lane) {
    return withLoc(pos, irBuilder.makeSIMDExtract(op, lane));
  }

  Result<> makeSIMDReplace(Index pos,
                           const std::vector<Annotation>& annotations,
                           SIMDReplaceOp op,
                           uint8_t lane) {
    return withLoc(pos, irBuilder.makeSIMDReplace(op, lane));
  }

  Result<> makeSIMDShuffle(Index pos,
                           const std::vector<Annotation>& annotations,
                           const std::array<uint8_t, 16>& lanes) {
    return withLoc(pos, irBuilder.makeSIMDShuffle(lanes));
  }

  Result<> makeSIMDTernary(Index pos,
                           const std::vector<Annotation>& annotations,
                           SIMDTernaryOp op) {
    return withLoc(pos, irBuilder.makeSIMDTernary(op));
  }

  Result<> makeSIMDShift(Index pos,
                         const std::vector<Annotation>& annotations,
                         SIMDShiftOp op) {
    return withLoc(pos, irBuilder.makeSIMDShift(op));
  }

  Result<> makeSIMDLoad(Index pos,
                        const std::vector<Annotation>& annotations,
                        SIMDLoadOp op,
                        Name* mem,
                        Memarg memarg) {
    auto m = getMemory(pos, mem);
    CHECK_ERR(m);
    return withLoc(pos,
                   irBuilder.makeSIMDLoad(op, memarg.offset, memarg.align, *m));
  }

  Result<> makeSIMDLoadStoreLane(Index pos,
                                 const std::vector<Annotation>& annotations,
                                 SIMDLoadStoreLaneOp op,
                                 Name* mem,
                                 Memarg memarg,
                                 uint8_t lane) {
    auto m = getMemory(pos, mem);
    CHECK_ERR(m);
    return withLoc(pos,
                   irBuilder.makeSIMDLoadStoreLane(
                     op, memarg.offset, memarg.align, lane, *m));
  }

  Result<> makeMemoryInit(Index pos,
                          const std::vector<Annotation>& annotations,
                          Name* mem,
                          Name data) {
    auto m = getMemory(pos, mem);
    CHECK_ERR(m);
    return withLoc(pos, irBuilder.makeMemoryInit(data, *m));
  }

  Result<> makeDataDrop(Index pos,
                        const std::vector<Annotation>& annotations,
                        Name data) {
    return withLoc(pos, irBuilder.makeDataDrop(data));
  }

  Result<> makeMemoryCopy(Index pos,
                          const std::vector<Annotation>& annotations,
                          Name* destMem,
                          Name* srcMem) {
    auto destMemory = getMemory(pos, destMem);
    CHECK_ERR(destMemory);
    auto srcMemory = getMemory(pos, srcMem);
    CHECK_ERR(srcMemory);
    return withLoc(pos, irBuilder.makeMemoryCopy(*destMemory, *srcMemory));
  }

  Result<> makeMemoryFill(Index pos,
                          const std::vector<Annotation>& annotations,
                          Name* mem) {
    auto m = getMemory(pos, mem);
    CHECK_ERR(m);
    return withLoc(pos, irBuilder.makeMemoryFill(*m));
  }

  Result<>
  makePop(Index pos, const std::vector<Annotation>& annotations, Type type) {
    return withLoc(pos, irBuilder.makePop(type));
  }

  Result<> makeCall(Index pos,
                    const std::vector<Annotation>& annotations,
                    Name func,
                    bool isReturn) {
    return withLoc(pos, irBuilder.makeCall(func, isReturn));
  }

  Result<> makeCallIndirect(Index pos,
                            const std::vector<Annotation>& annotations,
                            Name* table,
                            HeapType type,
                            bool isReturn) {
    auto t = getTable(pos, table);
    CHECK_ERR(t);
    return withLoc(pos, irBuilder.makeCallIndirect(*t, type, isReturn));
  }

  Result<> makeBreak(Index pos,
                     const std::vector<Annotation>& annotations,
                     Index label,
                     bool isConditional) {
    return withLoc(pos, irBuilder.makeBreak(label, isConditional));
  }

  Result<> makeSwitch(Index pos,
                      const std::vector<Annotation>& annotations,
                      const std::vector<Index> labels,
                      Index defaultLabel) {
    return withLoc(pos, irBuilder.makeSwitch(labels, defaultLabel));
  }

  Result<> makeReturn(Index pos, const std::vector<Annotation>& annotations) {
    return withLoc(pos, irBuilder.makeReturn());
  }

  Result<> makeRefNull(Index pos,
                       const std::vector<Annotation>& annotations,
                       HeapType type) {
    return withLoc(pos, irBuilder.makeRefNull(type));
  }

  Result<> makeRefIsNull(Index pos,
                         const std::vector<Annotation>& annotations) {
    return withLoc(pos, irBuilder.makeRefIsNull());
  }

  Result<> makeRefFunc(Index pos,
                       const std::vector<Annotation>& annotations,
                       Name func) {
    return withLoc(pos, irBuilder.makeRefFunc(func));
  }

  Result<> makeRefEq(Index pos, const std::vector<Annotation>& annotations) {
    return withLoc(pos, irBuilder.makeRefEq());
  }

  Result<> makeTableGet(Index pos,
                        const std::vector<Annotation>& annotations,
                        Name* table) {
    auto t = getTable(pos, table);
    CHECK_ERR(t);
    return withLoc(pos, irBuilder.makeTableGet(*t));
  }

  Result<> makeTableSet(Index pos,
                        const std::vector<Annotation>& annotations,
                        Name* table) {
    auto t = getTable(pos, table);
    CHECK_ERR(t);
    return withLoc(pos, irBuilder.makeTableSet(*t));
  }

  Result<> makeTableSize(Index pos,
                         const std::vector<Annotation>& annotations,
                         Name* table) {
    auto t = getTable(pos, table);
    CHECK_ERR(t);
    return withLoc(pos, irBuilder.makeTableSize(*t));
  }

  Result<> makeTableGrow(Index pos,
                         const std::vector<Annotation>& annotations,
                         Name* table) {
    auto t = getTable(pos, table);
    CHECK_ERR(t);
    return withLoc(pos, irBuilder.makeTableGrow(*t));
  }

  Result<> makeTableFill(Index pos,
                         const std::vector<Annotation>& annotations,
                         Name* table) {
    auto t = getTable(pos, table);
    CHECK_ERR(t);
    return withLoc(pos, irBuilder.makeTableFill(*t));
  }

  Result<> makeTableCopy(Index pos,
                         const std::vector<Annotation>& annotations,
                         Name* destTable,
                         Name* srcTable) {
    auto dest = getTable(pos, destTable);
    CHECK_ERR(dest);
    auto src = getTable(pos, srcTable);
    CHECK_ERR(src);
    return withLoc(pos, irBuilder.makeTableCopy(*dest, *src));
  }

  Result<> makeTableInit(Index pos,
                         const std::vector<Annotation>& annotations,
                         Name* table,
                         Name elem) {
    auto t = getTable(pos, table);
    CHECK_ERR(t);
    return withLoc(pos, irBuilder.makeTableInit(elem, *t));
  }

  Result<>
  makeThrow(Index pos, const std::vector<Annotation>& annotations, Name tag) {
    return withLoc(pos, irBuilder.makeThrow(tag));
  }

  Result<> makeRethrow(Index pos,
                       const std::vector<Annotation>& annotations,
                       Index label) {
    return withLoc(pos, irBuilder.makeRethrow(label));
  }

  Result<> makeThrowRef(Index pos, const std::vector<Annotation>& annotations) {
    return withLoc(pos, irBuilder.makeThrowRef());
  }

  Result<> makeTupleMake(Index pos,
                         const std::vector<Annotation>& annotations,
                         uint32_t arity) {
    return withLoc(pos, irBuilder.makeTupleMake(arity));
  }

  Result<> makeTupleExtract(Index pos,
                            const std::vector<Annotation>& annotations,
                            uint32_t arity,
                            uint32_t index) {
    return withLoc(pos, irBuilder.makeTupleExtract(arity, index));
  }

  Result<> makeTupleDrop(Index pos,
                         const std::vector<Annotation>& annotations,
                         uint32_t arity) {
    return withLoc(pos, irBuilder.makeTupleDrop(arity));
  }

  Result<> makeCallRef(Index pos,
                       const std::vector<Annotation>& annotations,
                       HeapType type,
                       bool isReturn) {
    return withLoc(pos, irBuilder.makeCallRef(type, isReturn));
  }

  Result<> makeRefI31(Index pos,
                      const std::vector<Annotation>& annotations,
                      Shareability share) {
    return withLoc(pos, irBuilder.makeRefI31(share));
  }

  Result<> makeI31Get(Index pos,
                      const std::vector<Annotation>& annotations,
                      bool signed_) {
    return withLoc(pos, irBuilder.makeI31Get(signed_));
  }

  Result<> makeRefTest(Index pos,
                       const std::vector<Annotation>& annotations,
                       Type type) {
    return withLoc(pos, irBuilder.makeRefTest(type));
  }

  Result<> makeRefCast(Index pos,
                       const std::vector<Annotation>& annotations,
                       Type type) {
    return withLoc(pos, irBuilder.makeRefCast(type));
  }

  Result<> makeBrOn(Index pos,
                    const std::vector<Annotation>& annotations,
                    Index label,
                    BrOnOp op,
                    Type in = Type::none,
                    Type out = Type::none) {
    return withLoc(pos, irBuilder.makeBrOn(label, op, in, out));
  }

  Result<> makeStructNew(Index pos,
                         const std::vector<Annotation>& annotations,
                         HeapType type) {
    return withLoc(pos, irBuilder.makeStructNew(type));
  }

  Result<> makeStructNewDefault(Index pos,
                                const std::vector<Annotation>& annotations,
                                HeapType type) {
    return withLoc(pos, irBuilder.makeStructNewDefault(type));
  }

  Result<> makeStructGet(Index pos,
                         const std::vector<Annotation>& annotations,
                         HeapType type,
                         Index field,
                         bool signed_) {
    return withLoc(pos, irBuilder.makeStructGet(type, field, signed_));
  }

  Result<> makeStructSet(Index pos,
                         const std::vector<Annotation>& annotations,
                         HeapType type,
                         Index field) {
    return withLoc(pos, irBuilder.makeStructSet(type, field));
  }

  Result<> makeArrayNew(Index pos,
                        const std::vector<Annotation>& annotations,
                        HeapType type) {
    return withLoc(pos, irBuilder.makeArrayNew(type));
  }

  Result<> makeArrayNewDefault(Index pos,
                               const std::vector<Annotation>& annotations,
                               HeapType type) {
    return withLoc(pos, irBuilder.makeArrayNewDefault(type));
  }

  Result<> makeArrayNewData(Index pos,
                            const std::vector<Annotation>& annotations,
                            HeapType type,
                            Name data) {
    return withLoc(pos, irBuilder.makeArrayNewData(type, data));
  }

  Result<> makeArrayNewElem(Index pos,
                            const std::vector<Annotation>& annotations,
                            HeapType type,
                            Name elem) {
    return withLoc(pos, irBuilder.makeArrayNewElem(type, elem));
  }

  Result<> makeArrayNewFixed(Index pos,
                             const std::vector<Annotation>& annotations,
                             HeapType type,
                             uint32_t arity) {
    return withLoc(pos, irBuilder.makeArrayNewFixed(type, arity));
  }

  Result<> makeArrayGet(Index pos,
                        const std::vector<Annotation>& annotations,
                        HeapType type,
                        bool signed_) {
    return withLoc(pos, irBuilder.makeArrayGet(type, signed_));
  }

  Result<> makeArraySet(Index pos,
                        const std::vector<Annotation>& annotations,
                        HeapType type) {
    return withLoc(pos, irBuilder.makeArraySet(type));
  }

  Result<> makeArrayLen(Index pos, const std::vector<Annotation>& annotations) {
    return withLoc(pos, irBuilder.makeArrayLen());
  }

  Result<> makeArrayCopy(Index pos,
                         const std::vector<Annotation>& annotations,
                         HeapType destType,
                         HeapType srcType) {
    return withLoc(pos, irBuilder.makeArrayCopy(destType, srcType));
  }

  Result<> makeArrayFill(Index pos,
                         const std::vector<Annotation>& annotations,
                         HeapType type) {
    return withLoc(pos, irBuilder.makeArrayFill(type));
  }

  Result<> makeArrayInitData(Index pos,
                             const std::vector<Annotation>& annotations,
                             HeapType type,
                             Name data) {
    return withLoc(pos, irBuilder.makeArrayInitData(type, data));
  }

  Result<> makeArrayInitElem(Index pos,
                             const std::vector<Annotation>& annotations,
                             HeapType type,
                             Name elem) {
    return withLoc(pos, irBuilder.makeArrayInitElem(type, elem));
  }

  Result<>
  makeRefAs(Index pos, const std::vector<Annotation>& annotations, RefAsOp op) {
    return withLoc(pos, irBuilder.makeRefAs(op));
  }

  Result<> makeStringNew(Index pos,
                         const std::vector<Annotation>& annotations,
                         StringNewOp op) {
    return withLoc(pos, irBuilder.makeStringNew(op));
  }

  Result<> makeStringConst(Index pos,
                           const std::vector<Annotation>& annotations,
                           std::string_view str) {
    // Re-encode from WTF-8 to WTF-16.
    std::stringstream wtf16;
    if (!String::convertWTF8ToWTF16(wtf16, str)) {
      return in.err(pos, "invalid string constant");
    }
    // TODO: Use wtf16.view() once we have C++20.
    return withLoc(pos, irBuilder.makeStringConst(wtf16.str()));
  }

  Result<> makeStringMeasure(Index pos,
                             const std::vector<Annotation>& annotations,
                             StringMeasureOp op) {
    return withLoc(pos, irBuilder.makeStringMeasure(op));
  }

  Result<> makeStringEncode(Index pos,
                            const std::vector<Annotation>& annotations,
                            StringEncodeOp op) {
    return withLoc(pos, irBuilder.makeStringEncode(op));
  }

  Result<> makeStringConcat(Index pos,
                            const std::vector<Annotation>& annotations) {
    return withLoc(pos, irBuilder.makeStringConcat());
  }

  Result<> makeStringEq(Index pos,
                        const std::vector<Annotation>& annotations,
                        StringEqOp op) {
    return withLoc(pos, irBuilder.makeStringEq(op));
  }

  Result<> makeStringWTF16Get(Index pos,
                              const std::vector<Annotation>& annotations) {
    return withLoc(pos, irBuilder.makeStringWTF16Get());
  }

  Result<> makeStringSliceWTF(Index pos,
                              const std::vector<Annotation>& annotations) {
    return withLoc(pos, irBuilder.makeStringSliceWTF());
  }

  Result<> makeContBind(Index pos,
                        const std::vector<Annotation>& annotations,
                        HeapType contTypeBefore,
                        HeapType contTypeAfter) {
    return withLoc(pos, irBuilder.makeContBind(contTypeBefore, contTypeAfter));
  }

  Result<> makeContNew(Index pos,
                       const std::vector<Annotation>& annotations,
                       HeapType type) {
    return withLoc(pos, irBuilder.makeContNew(type));
  }

  Result<> makeResume(Index pos,
                      const std::vector<Annotation>& annotations,
                      HeapType type,
                      const TagLabelListT& tagLabels) {
    std::vector<Name> tags;
    std::vector<Index> labels;
    tags.reserve(tagLabels.size());
    labels.reserve(tagLabels.size());
    for (auto& [tag, label] : tagLabels) {
      tags.push_back(tag);
      labels.push_back(label);
    }
    return withLoc(pos, irBuilder.makeResume(type, tags, labels));
  }

  Result<>
  makeSuspend(Index pos, const std::vector<Annotation>& annotations, Name tag) {
    return withLoc(pos, irBuilder.makeSuspend(tag));
  }
};

} // namespace wasm::WATParser

#endif // parser_context_h
