/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* TypeDef Definitions                                                        *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/

#ifdef GET_TYPEDEF_LIST
#undef GET_TYPEDEF_LIST

::mlir::wasmssa::FuncRefType,
::mlir::wasmssa::ExternRefType,
::mlir::wasmssa::LimitType,
::mlir::wasmssa::LocalRefType,
::mlir::wasmssa::TableType

#endif // GET_TYPEDEF_LIST

#ifdef GET_TYPEDEF_CLASSES
#undef GET_TYPEDEF_CLASSES

static ::mlir::OptionalParseResult generatedTypeParser(::mlir::AsmParser &parser, ::llvm::StringRef *mnemonic, ::mlir::Type &value) {
  return ::mlir::AsmParser::KeywordSwitch<::mlir::OptionalParseResult>(parser)
    .Case(::mlir::wasmssa::FuncRefType::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) {
      value = ::mlir::wasmssa::FuncRefType::parse(parser);
      return ::mlir::success(!!value);
    })
    .Case(::mlir::wasmssa::ExternRefType::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) {
      value = ::mlir::wasmssa::ExternRefType::get(parser.getContext());
      return ::mlir::success(!!value);
    })
    .Case(::mlir::wasmssa::LimitType::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) {
      value = ::mlir::wasmssa::LimitType::parse(parser);
      return ::mlir::success(!!value);
    })
    .Case(::mlir::wasmssa::LocalRefType::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) {
      value = ::mlir::wasmssa::LocalRefType::parse(parser);
      return ::mlir::success(!!value);
    })
    .Case(::mlir::wasmssa::TableType::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) {
      value = ::mlir::wasmssa::TableType::parse(parser);
      return ::mlir::success(!!value);
    })
    .Default([&](llvm::StringRef keyword, llvm::SMLoc) {
      *mnemonic = keyword;
      return std::nullopt;
    });
}

static ::llvm::LogicalResult generatedTypePrinter(::mlir::Type def, ::mlir::AsmPrinter &printer) {
  return ::llvm::TypeSwitch<::mlir::Type, ::llvm::LogicalResult>(def)    .Case<::mlir::wasmssa::FuncRefType>([&](auto t) {
      printer << ::mlir::wasmssa::FuncRefType::getMnemonic();
t.print(printer);
      return ::mlir::success();
    })
    .Case<::mlir::wasmssa::ExternRefType>([&](auto t) {
      printer << ::mlir::wasmssa::ExternRefType::getMnemonic();
      return ::mlir::success();
    })
    .Case<::mlir::wasmssa::LimitType>([&](auto t) {
      printer << ::mlir::wasmssa::LimitType::getMnemonic();
t.print(printer);
      return ::mlir::success();
    })
    .Case<::mlir::wasmssa::LocalRefType>([&](auto t) {
      printer << ::mlir::wasmssa::LocalRefType::getMnemonic();
t.print(printer);
      return ::mlir::success();
    })
    .Case<::mlir::wasmssa::TableType>([&](auto t) {
      printer << ::mlir::wasmssa::TableType::getMnemonic();
t.print(printer);
      return ::mlir::success();
    })
    .Default([](auto) { return ::mlir::failure(); });
}

namespace mlir::wasmssa {

::mlir::Type FuncRefType::parse(::mlir::AsmParser &odsParser) {
  ::mlir::Builder odsBuilder(odsParser.getContext());
  ::llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
  (void) odsLoc;
  return FuncRefType::get(odsParser.getContext());
}

void FuncRefType::print(::mlir::AsmPrinter &odsPrinter) const {
  ::mlir::Builder odsBuilder(getContext());
}


} // namespace mlir::wasmssa
MLIR_DEFINE_EXPLICIT_TYPE_ID(::mlir::wasmssa::FuncRefType)
namespace mlir::wasmssa {


} // namespace mlir::wasmssa
MLIR_DEFINE_EXPLICIT_TYPE_ID(::mlir::wasmssa::ExternRefType)
namespace mlir::wasmssa {

namespace detail {

struct LimitTypeStorage : public ::mlir::TypeStorage {
  using KeyTy = std::tuple<uint32_t, std::optional<uint32_t>>;
  LimitTypeStorage(uint32_t min, std::optional<uint32_t> max) : min(std::move(min)), max(std::move(max)) {}

  KeyTy getAsKey() const {
    return KeyTy(min, max);
  }

  bool operator==(const KeyTy &tblgenKey) const {
    return (min == std::get<0>(tblgenKey)) && (max == std::get<1>(tblgenKey));
  }

  static ::llvm::hash_code hashKey(const KeyTy &tblgenKey) {
    return ::llvm::hash_combine(std::get<0>(tblgenKey), std::get<1>(tblgenKey));
  }

  static LimitTypeStorage *construct(::mlir::TypeStorageAllocator &allocator, KeyTy &&tblgenKey) {
    auto min = std::move(std::get<0>(tblgenKey));
    auto max = std::move(std::get<1>(tblgenKey));
    return new (allocator.allocate<LimitTypeStorage>()) LimitTypeStorage(std::move(min), std::move(max));
  }

  uint32_t min;
  std::optional<uint32_t> max;
};

} // namespace detail
LimitType LimitType::get(::mlir::MLIRContext *context, uint32_t min, std::optional<uint32_t> max) {
  return Base::get(context, std::move(min), std::move(max));
}

::mlir::Type LimitType::parse(::mlir::AsmParser &odsParser) {
  ::mlir::Builder odsBuilder(odsParser.getContext());
  ::llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
  (void) odsLoc;
  ::mlir::FailureOr<uint32_t> _result_min;
  ::mlir::FailureOr<std::optional<uint32_t>> _result_max;
  // Parse literal '['
  if (odsParser.parseLSquare()) return {};

  // Parse variable 'min'
  _result_min = ::mlir::FieldParser<uint32_t>::parse(odsParser);
  if (::mlir::failed(_result_min)) {
    odsParser.emitError(odsParser.getCurrentLocation(), "failed to parse WasmSSA_LimitType parameter 'min' which is to be a `uint32_t`");
    return {};
  }
  // Parse literal ':'
  if (odsParser.parseColon()) return {};

  // Parse variable 'max'
  _result_max = ::mlir::FieldParser<std::optional<uint32_t>>::parse(odsParser);
  if (::mlir::failed(_result_max)) {
    odsParser.emitError(odsParser.getCurrentLocation(), "failed to parse WasmSSA_LimitType parameter 'max' which is to be a `std::optional<uint32_t>`");
    return {};
  }
  if (!((::mlir::succeeded(_result_max) && *_result_max))) {
  } else {
  }
  // Parse literal ']'
  if (odsParser.parseRSquare()) return {};
  assert(::mlir::succeeded(_result_min));
  return LimitType::get(odsParser.getContext(),
      uint32_t((*_result_min)),
      std::optional<uint32_t>((_result_max.value_or(std::optional<uint32_t>()))));
}

void LimitType::print(::mlir::AsmPrinter &odsPrinter) const {
  ::mlir::Builder odsBuilder(getContext());
  odsPrinter << "[";
  odsPrinter.printStrippedAttrOrType(getMin());
  odsPrinter << ":";
  if (!(getMax() == std::optional<uint32_t>())) {
    if (!(getMax() == std::optional<uint32_t>())) {
      odsPrinter << ' ';
      odsPrinter.printStrippedAttrOrType(getMax());
    }
  } else {
  }
  odsPrinter << "]";
}

uint32_t LimitType::getMin() const {
  return getImpl()->min;
}

std::optional<uint32_t> LimitType::getMax() const {
  return getImpl()->max;
}


} // namespace mlir::wasmssa
MLIR_DEFINE_EXPLICIT_TYPE_ID(::mlir::wasmssa::LimitType)
namespace mlir::wasmssa {

namespace detail {

struct LocalRefTypeStorage : public ::mlir::TypeStorage {
  using KeyTy = std::tuple<::mlir::Type>;
  LocalRefTypeStorage(::mlir::Type elementType) : elementType(std::move(elementType)) {}

  KeyTy getAsKey() const {
    return KeyTy(elementType);
  }

  bool operator==(const KeyTy &tblgenKey) const {
    return (elementType == std::get<0>(tblgenKey));
  }

  static ::llvm::hash_code hashKey(const KeyTy &tblgenKey) {
    return ::llvm::hash_combine(std::get<0>(tblgenKey));
  }

  static LocalRefTypeStorage *construct(::mlir::TypeStorageAllocator &allocator, KeyTy &&tblgenKey) {
    auto elementType = std::move(std::get<0>(tblgenKey));
    return new (allocator.allocate<LocalRefTypeStorage>()) LocalRefTypeStorage(std::move(elementType));
  }

  ::mlir::Type elementType;
};

} // namespace detail
LocalRefType LocalRefType::get(::mlir::MLIRContext *context, ::mlir::Type elementType) {
  return Base::get(context, std::move(elementType));
}

LocalRefType LocalRefType::getChecked(::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError, ::mlir::MLIRContext *context, ::mlir::Type elementType) {
  return Base::getChecked(emitError, context, std::move(elementType));
}

LocalRefType LocalRefType::get(Type typeParam) {
  return get(typeParam.getContext(), typeParam);
}

LocalRefType LocalRefType::getChecked(::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError, Type typeParam) {
  return get(typeParam.getContext(), typeParam);
}

::llvm::LogicalResult LocalRefType::verifyInvariantsImpl(::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError, ::mlir::Type elementType) {
  if (!(((((elementType.isSignlessInteger(32))) || ((elementType.isSignlessInteger(64)))) || (((elementType.isF32())) || ((elementType.isF64())))) || ((elementType.isSignlessInteger(128))) || (((::llvm::isa<::mlir::wasmssa::FuncRefType>(elementType))) || ((::llvm::isa<::mlir::wasmssa::ExternRefType>(elementType)))))) {
    emitError() << "failed to verify 'elementType': 32-bit signless integer or 64-bit signless integer or 32-bit float or 64-bit float or 128-bit signless integer or Opaque type for function reference or Opaque type for external reference";
    return ::mlir::failure();
  }

  return ::mlir::success();
}

::llvm::LogicalResult LocalRefType::verifyInvariants(::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError, ::mlir::Type elementType) {
  if (::mlir::failed(verifyInvariantsImpl(emitError, elementType)))
    return ::mlir::failure();
  return ::mlir::success();
}

::mlir::Type LocalRefType::parse(::mlir::AsmParser &odsParser) {
  ::mlir::Builder odsBuilder(odsParser.getContext());
  ::llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
  (void) odsLoc;
  ::mlir::FailureOr<::mlir::Type> _result_elementType;
  // Parse literal 'ref'
  if (odsParser.parseKeyword("ref")) return {};
  // Parse literal 'to'
  if (odsParser.parseKeyword("to")) return {};

  // Parse variable 'elementType'
  _result_elementType = ::mlir::FieldParser<::mlir::Type>::parse(odsParser);
  if (::mlir::failed(_result_elementType)) {
    odsParser.emitError(odsParser.getCurrentLocation(), "failed to parse WasmSSA_LocalRef parameter 'elementType' which is to be a `::mlir::Type`");
    return {};
  }
  assert(::mlir::succeeded(_result_elementType));
  return odsParser.getChecked<LocalRefType>(odsLoc, odsParser.getContext(),
      ::mlir::Type((*_result_elementType)));
}

void LocalRefType::print(::mlir::AsmPrinter &odsPrinter) const {
  ::mlir::Builder odsBuilder(getContext());
  odsPrinter << ' ' << "ref";
  odsPrinter << ' ' << "to";
  odsPrinter << ' ';
  odsPrinter.printStrippedAttrOrType(getElementType());
}

::mlir::Type LocalRefType::getElementType() const {
  return getImpl()->elementType;
}


} // namespace mlir::wasmssa
MLIR_DEFINE_EXPLICIT_TYPE_ID(::mlir::wasmssa::LocalRefType)
namespace mlir::wasmssa {

namespace detail {

struct TableTypeStorage : public ::mlir::TypeStorage {
  using KeyTy = std::tuple<::mlir::Type, ::mlir::wasmssa::LimitType>;
  TableTypeStorage(::mlir::Type reference, ::mlir::wasmssa::LimitType limit) : reference(std::move(reference)), limit(std::move(limit)) {}

  KeyTy getAsKey() const {
    return KeyTy(reference, limit);
  }

  bool operator==(const KeyTy &tblgenKey) const {
    return (reference == std::get<0>(tblgenKey)) && (limit == std::get<1>(tblgenKey));
  }

  static ::llvm::hash_code hashKey(const KeyTy &tblgenKey) {
    return ::llvm::hash_combine(std::get<0>(tblgenKey), std::get<1>(tblgenKey));
  }

  static TableTypeStorage *construct(::mlir::TypeStorageAllocator &allocator, KeyTy &&tblgenKey) {
    auto reference = std::move(std::get<0>(tblgenKey));
    auto limit = std::move(std::get<1>(tblgenKey));
    return new (allocator.allocate<TableTypeStorage>()) TableTypeStorage(std::move(reference), std::move(limit));
  }

  ::mlir::Type reference;
  ::mlir::wasmssa::LimitType limit;
};

} // namespace detail
TableType TableType::get(::mlir::MLIRContext *context, ::mlir::Type reference, ::mlir::wasmssa::LimitType limit) {
  return Base::get(context, std::move(reference), std::move(limit));
}

TableType TableType::getChecked(::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError, ::mlir::MLIRContext *context, ::mlir::Type reference, ::mlir::wasmssa::LimitType limit) {
  return Base::getChecked(emitError, context, std::move(reference), std::move(limit));
}

::llvm::LogicalResult TableType::verifyInvariantsImpl(::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError, ::mlir::Type reference, ::mlir::wasmssa::LimitType limit) {
  if (!(((::llvm::isa<::mlir::wasmssa::FuncRefType>(reference))) || ((::llvm::isa<::mlir::wasmssa::ExternRefType>(reference))))) {
    emitError() << "failed to verify 'reference': Opaque type for function reference or Opaque type for external reference";
    return ::mlir::failure();
  }


  if (!((::llvm::isa<::mlir::wasmssa::LimitType>(limit)))) {
    emitError() << "failed to verify 'limit': Wasm limit type";
    return ::mlir::failure();
  }

  return ::mlir::success();
}

::llvm::LogicalResult TableType::verifyInvariants(::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError, ::mlir::Type reference, ::mlir::wasmssa::LimitType limit) {
  if (::mlir::failed(verifyInvariantsImpl(emitError, reference, limit)))
    return ::mlir::failure();
  return ::mlir::success();
}

::mlir::Type TableType::parse(::mlir::AsmParser &odsParser) {
  ::mlir::Builder odsBuilder(odsParser.getContext());
  ::llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
  (void) odsLoc;
  ::mlir::FailureOr<::mlir::Type> _result_reference;
  ::mlir::FailureOr<::mlir::wasmssa::LimitType> _result_limit;

  // Parse variable 'reference'
  _result_reference = ::mlir::FieldParser<::mlir::Type>::parse(odsParser);
  if (::mlir::failed(_result_reference)) {
    odsParser.emitError(odsParser.getCurrentLocation(), "failed to parse WasmSSA_TableType parameter 'reference' which is to be a `::mlir::Type`");
    return {};
  }

  // Parse variable 'limit'
  odsParser.getContext()->getOrLoadDialect<::mlir::wasmssa::WasmSSADialect>();
  _result_limit = ::mlir::FieldParser<::mlir::wasmssa::LimitType>::parse(odsParser);
  if (::mlir::failed(_result_limit)) {
    odsParser.emitError(odsParser.getCurrentLocation(), "failed to parse WasmSSA_TableType parameter 'limit' which is to be a `::mlir::wasmssa::LimitType`");
    return {};
  }
  assert(::mlir::succeeded(_result_reference));
  assert(::mlir::succeeded(_result_limit));
  return odsParser.getChecked<TableType>(odsLoc, odsParser.getContext(),
      ::mlir::Type((*_result_reference)),
      ::mlir::wasmssa::LimitType((*_result_limit)));
}

void TableType::print(::mlir::AsmPrinter &odsPrinter) const {
  ::mlir::Builder odsBuilder(getContext());
  odsPrinter << ' ';
  odsPrinter.printStrippedAttrOrType(getReference());
  odsPrinter << ' ';
  odsPrinter.printStrippedAttrOrType(getLimit());
}

::mlir::Type TableType::getReference() const {
  return getImpl()->reference;
}

::mlir::wasmssa::LimitType TableType::getLimit() const {
  return getImpl()->limit;
}


} // namespace mlir::wasmssa
MLIR_DEFINE_EXPLICIT_TYPE_ID(::mlir::wasmssa::TableType)
namespace mlir::wasmssa {


/// Parse a type registered to this dialect.
::mlir::Type WasmSSADialect::parseType(::mlir::DialectAsmParser &parser) const {
  ::llvm::SMLoc typeLoc = parser.getCurrentLocation();
  ::llvm::StringRef mnemonic;
  ::mlir::Type genType;
  auto parseResult = generatedTypeParser(parser, &mnemonic, genType);
  if (parseResult.has_value())
    return genType;
  
  parser.emitError(typeLoc) << "unknown  type `"
      << mnemonic << "` in dialect `" << getNamespace() << "`";
  return {};
}
/// Print a type registered to this dialect.
void WasmSSADialect::printType(::mlir::Type type,
                    ::mlir::DialectAsmPrinter &printer) const {
  if (::mlir::succeeded(generatedTypePrinter(type, printer)))
    return;
  
}

} // namespace mlir::wasmssa

#endif // GET_TYPEDEF_CLASSES

