//===- Constraint.cpp - Constraint class ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Constraint wrapper to simplify using TableGen Record for constraints.
//
//===----------------------------------------------------------------------===//

#include "mlir/TableGen/Constraint.h"
#include "llvm/TableGen/Record.h"

using namespace mlir;
using namespace mlir::tblgen;

Constraint::Constraint(const llvm::Record *record)
    : Constraint(record, CK_Uncategorized) {
  // Look through OpVariable's to their constraint.
  if (def->isSubClassOf("OpVariable"))
    def = def->getValueAsDef("constraint");

  if (def->isSubClassOf("TypeConstraint")) {
    kind = CK_Type;
  } else if (def->isSubClassOf("AttrConstraint")) {
    kind = CK_Attr;
  } else if (def->isSubClassOf("RegionConstraint")) {
    kind = CK_Region;
  } else if (def->isSubClassOf("SuccessorConstraint")) {
    kind = CK_Successor;
  } else if(!def->isSubClassOf("Constraint")) {
    llvm::errs() << "Expected a constraint but got: \n" << *def << "\n";
    llvm::report_fatal_error("Abort");
  }
}

Pred Constraint::getPredicate() const {
  auto *val = def->getValue("predicate");

  // If no predicate is specified, then return the null predicate (which
  // corresponds to true).
  if (!val)
    return Pred();

  const auto *pred = dyn_cast<llvm::DefInit>(val->getValue());
  return Pred(pred);
}

std::string Constraint::getConditionTemplate() const {
  return getPredicate().getCondition();
}

StringRef Constraint::getSummary() const {
  if (std::optional<StringRef> summary =
          def->getValueAsOptionalString("summary"))
    return *summary;
  return def->getName();
}

StringRef Constraint::getDescription() const {
  return def->getValueAsOptionalString("description").value_or("");
}

StringRef Constraint::getDefName() const {
  if (std::optional<StringRef> baseDefName = getBaseDefName())
    return *baseDefName;
  return def->getName();
}

std::string Constraint::getUniqueDefName() const {
  std::string defName = def->getName().str();

  // Non-anonymous classes already have a unique name from the def.
  if (!def->isAnonymous())
    return defName;

  // Otherwise, this is an anonymous class. In these cases we still use the def
  // name, but we also try attach the name of the base def when present to make
  // the name more obvious.
  if (std::optional<StringRef> baseDefName = getBaseDefName())
    return (*baseDefName + "(" + defName + ")").str();
  return defName;
}

std::optional<StringRef> Constraint::getBaseDefName() const {
  // Functor used to check a base def in the case where the current def is
  // anonymous.
  auto checkBaseDefFn = [&](StringRef baseName) -> std::optional<StringRef> {
    if (const auto *defValue = def->getValue(baseName)) {
      if (const auto *defInit = dyn_cast<llvm::DefInit>(defValue->getValue()))
        return Constraint(defInit->getDef(), kind).getDefName();
    }
    return std::nullopt;
  };

  switch (kind) {
  case CK_Attr:
    if (def->isAnonymous())
      return checkBaseDefFn("baseAttr");
    return std::nullopt;
  case CK_Type:
    if (def->isAnonymous())
      return checkBaseDefFn("baseType");
    return std::nullopt;
  default:
    return std::nullopt;
  }
}

AppliedConstraint::AppliedConstraint(Constraint &&constraint,
                                     llvm::StringRef self,
                                     std::vector<std::string> &&entities)
    : constraint(constraint), self(std::string(self)),
      entities(std::move(entities)) {}

Constraint DenseMapInfo<Constraint>::getEmptyKey() {
  return Constraint(RecordDenseMapInfo::getEmptyKey(),
                    Constraint::CK_Uncategorized);
}

Constraint DenseMapInfo<Constraint>::getTombstoneKey() {
  return Constraint(RecordDenseMapInfo::getTombstoneKey(),
                    Constraint::CK_Uncategorized);
}

unsigned DenseMapInfo<Constraint>::getHashValue(Constraint constraint) {
  if (constraint == getEmptyKey())
    return RecordDenseMapInfo::getHashValue(RecordDenseMapInfo::getEmptyKey());
  if (constraint == getTombstoneKey()) {
    return RecordDenseMapInfo::getHashValue(
        RecordDenseMapInfo::getTombstoneKey());
  }
  return llvm::hash_combine(constraint.getPredicate(), constraint.getSummary());
}

bool DenseMapInfo<Constraint>::isEqual(Constraint lhs, Constraint rhs) {
  if (lhs == rhs)
    return true;
  if (lhs == getEmptyKey() || lhs == getTombstoneKey())
    return false;
  if (rhs == getEmptyKey() || rhs == getTombstoneKey())
    return false;
  return lhs.getPredicate() == rhs.getPredicate() &&
         lhs.getSummary() == rhs.getSummary();
}
