//===- Interfaces.cpp - Interface classes ---------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "mlir/TableGen/Interfaces.h"
#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"

using namespace mlir;
using namespace mlir::tblgen;

//===----------------------------------------------------------------------===//
// InterfaceMethod
//===----------------------------------------------------------------------===//

InterfaceMethod::InterfaceMethod(const llvm::Record *def) : def(def) {
  llvm::DagInit *args = def->getValueAsDag("arguments");
  for (unsigned i = 0, e = args->getNumArgs(); i != e; ++i) {
    arguments.push_back(
        {llvm::cast<llvm::StringInit>(args->getArg(i))->getValue(),
         args->getArgNameStr(i)});
  }
}

StringRef InterfaceMethod::getReturnType() const {
  return def->getValueAsString("returnType");
}

// Return the name of this method.
StringRef InterfaceMethod::getName() const {
  return def->getValueAsString("name");
}

// Return if this method is static.
bool InterfaceMethod::isStatic() const {
  return def->isSubClassOf("StaticInterfaceMethod");
}

// Return the body for this method if it has one.
std::optional<StringRef> InterfaceMethod::getBody() const {
  auto value = def->getValueAsString("body");
  return value.empty() ? std::optional<StringRef>() : value;
}

// Return the default implementation for this method if it has one.
std::optional<StringRef> InterfaceMethod::getDefaultImplementation() const {
  auto value = def->getValueAsString("defaultBody");
  return value.empty() ? std::optional<StringRef>() : value;
}

// Return the description of this method if it has one.
std::optional<StringRef> InterfaceMethod::getDescription() const {
  auto value = def->getValueAsString("description");
  return value.empty() ? std::optional<StringRef>() : value;
}

ArrayRef<InterfaceMethod::Argument> InterfaceMethod::getArguments() const {
  return arguments;
}

bool InterfaceMethod::arg_empty() const { return arguments.empty(); }

//===----------------------------------------------------------------------===//
// Interface
//===----------------------------------------------------------------------===//

Interface::Interface(const llvm::Record *def) : def(def) {
  assert(def->isSubClassOf("Interface") &&
         "must be subclass of TableGen 'Interface' class");

  // Initialize the interface methods.
  auto *listInit = dyn_cast<llvm::ListInit>(def->getValueInit("methods"));
  for (llvm::Init *init : listInit->getValues())
    methods.emplace_back(cast<llvm::DefInit>(init)->getDef());

  // Initialize the interface base classes.
  auto *basesInit =
      dyn_cast<llvm::ListInit>(def->getValueInit("baseInterfaces"));
  // Chained inheritance will produce duplicates in the base interface set.
  StringSet<> basesAdded;
  llvm::unique_function<void(Interface)> addBaseInterfaceFn =
      [&](const Interface &baseInterface) {
        // Inherit any base interfaces.
        for (const auto &baseBaseInterface : baseInterface.getBaseInterfaces())
          addBaseInterfaceFn(baseBaseInterface);

        // Add the base interface.
        if (basesAdded.contains(baseInterface.getName()))
          return;
        baseInterfaces.push_back(std::make_unique<Interface>(baseInterface));
        basesAdded.insert(baseInterface.getName());
      };
  for (llvm::Init *init : basesInit->getValues())
    addBaseInterfaceFn(Interface(cast<llvm::DefInit>(init)->getDef()));
}

// Return the name of this interface.
StringRef Interface::getName() const {
  return def->getValueAsString("cppInterfaceName");
}

// Returns this interface's name prefixed with namespaces.
std::string Interface::getFullyQualifiedName() const {
  StringRef cppNamespace = getCppNamespace();
  StringRef name = getName();
  if (cppNamespace.empty())
    return name.str();
  return (cppNamespace + "::" + name).str();
}

// Return the C++ namespace of this interface.
StringRef Interface::getCppNamespace() const {
  return def->getValueAsString("cppNamespace");
}

// Return the methods of this interface.
ArrayRef<InterfaceMethod> Interface::getMethods() const { return methods; }

// Return the description of this method if it has one.
std::optional<StringRef> Interface::getDescription() const {
  auto value = def->getValueAsString("description");
  return value.empty() ? std::optional<StringRef>() : value;
}

// Return the interfaces extra class declaration code.
std::optional<StringRef> Interface::getExtraClassDeclaration() const {
  auto value = def->getValueAsString("extraClassDeclaration");
  return value.empty() ? std::optional<StringRef>() : value;
}

// Return the traits extra class declaration code.
std::optional<StringRef> Interface::getExtraTraitClassDeclaration() const {
  auto value = def->getValueAsString("extraTraitClassDeclaration");
  return value.empty() ? std::optional<StringRef>() : value;
}

// Return the shared extra class declaration code.
std::optional<StringRef> Interface::getExtraSharedClassDeclaration() const {
  auto value = def->getValueAsString("extraSharedClassDeclaration");
  return value.empty() ? std::optional<StringRef>() : value;
}

std::optional<StringRef> Interface::getExtraClassOf() const {
  auto value = def->getValueAsString("extraClassOf");
  return value.empty() ? std::optional<StringRef>() : value;
}

// Return the body for this method if it has one.
std::optional<StringRef> Interface::getVerify() const {
  // Only OpInterface supports the verify method.
  if (!isa<OpInterface>(this))
    return std::nullopt;
  auto value = def->getValueAsString("verify");
  return value.empty() ? std::optional<StringRef>() : value;
}

bool Interface::verifyWithRegions() const {
  return def->getValueAsBit("verifyWithRegions");
}

//===----------------------------------------------------------------------===//
// AttrInterface
//===----------------------------------------------------------------------===//

bool AttrInterface::classof(const Interface *interface) {
  return interface->getDef().isSubClassOf("AttrInterface");
}

//===----------------------------------------------------------------------===//
// OpInterface
//===----------------------------------------------------------------------===//

bool OpInterface::classof(const Interface *interface) {
  return interface->getDef().isSubClassOf("OpInterface");
}

//===----------------------------------------------------------------------===//
// TypeInterface
//===----------------------------------------------------------------------===//

bool TypeInterface::classof(const Interface *interface) {
  return interface->getDef().isSubClassOf("TypeInterface");
}
