//===-- Language.cpp ------------------------------------------------------===//
//
// 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 <functional>
#include <map>
#include <mutex>

#include "lldb/Target/Language.h"

#include "lldb/Core/PluginManager.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Stream.h"

#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/Threading.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;

typedef std::unique_ptr<Language> LanguageUP;
typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap;

#define LLDB_PROPERTIES_language
#include "TargetProperties.inc"

enum {
#define LLDB_PROPERTIES_language
#include "TargetPropertiesEnum.inc"
};

LanguageProperties &Language::GetGlobalLanguageProperties() {
  static LanguageProperties g_settings;
  return g_settings;
}

llvm::StringRef LanguageProperties::GetSettingName() {
  static constexpr llvm::StringLiteral g_setting_name("language");
  return g_setting_name;
}

LanguageProperties::LanguageProperties() {
  m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
  m_collection_sp->Initialize(g_language_properties_def);
}

bool LanguageProperties::GetEnableFilterForLineBreakpoints() const {
  const uint32_t idx = ePropertyEnableFilterForLineBreakpoints;
  return GetPropertyAtIndexAs<bool>(
      idx, g_language_properties[idx].default_uint_value != 0);
}

static LanguagesMap &GetLanguagesMap() {
  static LanguagesMap *g_map = nullptr;
  static llvm::once_flag g_initialize;

  llvm::call_once(g_initialize, [] {
    g_map = new LanguagesMap(); // NOTE: INTENTIONAL LEAK due to global
                                // destructor chain
  });

  return *g_map;
}
static std::mutex &GetLanguagesMutex() {
  static std::mutex *g_mutex = nullptr;
  static llvm::once_flag g_initialize;

  llvm::call_once(g_initialize, [] {
    g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global
                                // destructor chain
  });

  return *g_mutex;
}

Language *Language::FindPlugin(lldb::LanguageType language) {
  std::lock_guard<std::mutex> guard(GetLanguagesMutex());
  LanguagesMap &map(GetLanguagesMap());
  auto iter = map.find(language), end = map.end();
  if (iter != end)
    return iter->second.get();

  Language *language_ptr = nullptr;
  LanguageCreateInstance create_callback;

  for (uint32_t idx = 0;
       (create_callback =
            PluginManager::GetLanguageCreateCallbackAtIndex(idx)) != nullptr;
       ++idx) {
    language_ptr = create_callback(language);

    if (language_ptr) {
      map[language] = std::unique_ptr<Language>(language_ptr);
      return language_ptr;
    }
  }

  return nullptr;
}

Language *Language::FindPlugin(llvm::StringRef file_path) {
  Language *result = nullptr;
  ForEach([&result, file_path](Language *language) {
    if (language->IsSourceFile(file_path)) {
      result = language;
      return IterationAction::Stop;
    }
    return IterationAction::Continue;
  });
  return result;
}

Language *Language::FindPlugin(LanguageType language,
                               llvm::StringRef file_path) {
  Language *result = FindPlugin(language);
  // Finding a language by file path is slower, we so we use this as the
  // fallback.
  if (!result)
    result = FindPlugin(file_path);
  return result;
}

void Language::ForEach(
    llvm::function_ref<IterationAction(Language *)> callback) {
  // If we want to iterate over all languages, we first have to complete the
  // LanguagesMap.
  static llvm::once_flag g_initialize;
  llvm::call_once(g_initialize, [] {
    for (unsigned lang = eLanguageTypeUnknown; lang < eNumLanguageTypes;
         ++lang) {
      FindPlugin(static_cast<lldb::LanguageType>(lang));
    }
  });

  // callback may call a method in Language that attempts to acquire the same
  // lock (such as Language::ForEach or Language::FindPlugin). To avoid a
  // deadlock, we do not use callback while holding the lock.
  std::vector<Language *> loaded_plugins;
  {
    std::lock_guard<std::mutex> guard(GetLanguagesMutex());
    LanguagesMap &map(GetLanguagesMap());
    for (const auto &entry : map) {
      if (entry.second)
        loaded_plugins.push_back(entry.second.get());
    }
  }

  for (auto *lang : loaded_plugins) {
    if (callback(lang) == IterationAction::Stop)
      break;
  }
}

llvm::Expected<LanguageType>
Language::GetExceptionLanguageForLanguage(llvm::StringRef lang_name) {
  LanguageType language = Language::GetLanguageTypeFromString(lang_name);
  LanguageType exception_language = eLanguageTypeUnknown;

  llvm::StringRef error_context;
  switch (language) {
  case eLanguageTypeC89:
  case eLanguageTypeC:
  case eLanguageTypeC99:
  case eLanguageTypeC11:
    exception_language = eLanguageTypeC;
    break;
  case eLanguageTypeC_plus_plus:
  case eLanguageTypeC_plus_plus_03:
  case eLanguageTypeC_plus_plus_11:
  case eLanguageTypeC_plus_plus_14:
    exception_language = eLanguageTypeC_plus_plus;
    break;
  case eLanguageTypeObjC_plus_plus:
    error_context =
        "Set exception breakpoints separately for c++ and objective-c";
    break;
  case eLanguageTypeUnknown:
    error_context = "Unknown language type for exception breakpoint";
    break;
  default:
    if (Language *languagePlugin = Language::FindPlugin(language)) {
      if (languagePlugin->SupportsExceptionBreakpointsOnThrow() ||
          languagePlugin->SupportsExceptionBreakpointsOnCatch()) {
        exception_language = language;
        break;
      }
    }
    error_context = "Unsupported language type for exception breakpoint";
  }
  if (!error_context.empty())
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   error_context);
  return exception_language;
}

bool Language::IsTopLevelFunction(Function &function) { return false; }

lldb::TypeCategoryImplSP Language::GetFormatters() { return nullptr; }

HardcodedFormatters::HardcodedFormatFinder Language::GetHardcodedFormats() {
  return {};
}

HardcodedFormatters::HardcodedSummaryFinder Language::GetHardcodedSummaries() {
  return {};
}

HardcodedFormatters::HardcodedSyntheticFinder
Language::GetHardcodedSynthetics() {
  return {};
}

std::vector<FormattersMatchCandidate>
Language::GetPossibleFormattersMatches(ValueObject &valobj,
                                       lldb::DynamicValueType use_dynamic) {
  return {};
}

struct language_name_pair {
  const char *name;
  LanguageType type;
};

struct language_name_pair language_names[] = {
    // To allow GetNameForLanguageType to be a simple array lookup, the first
    // part of this array must follow enum LanguageType exactly.
    {"unknown", eLanguageTypeUnknown},
    {"c89", eLanguageTypeC89},
    {"c", eLanguageTypeC},
    {"ada83", eLanguageTypeAda83},
    {"c++", eLanguageTypeC_plus_plus},
    {"cobol74", eLanguageTypeCobol74},
    {"cobol85", eLanguageTypeCobol85},
    {"fortran77", eLanguageTypeFortran77},
    {"fortran90", eLanguageTypeFortran90},
    {"pascal83", eLanguageTypePascal83},
    {"modula2", eLanguageTypeModula2},
    {"java", eLanguageTypeJava},
    {"c99", eLanguageTypeC99},
    {"ada95", eLanguageTypeAda95},
    {"fortran95", eLanguageTypeFortran95},
    {"pli", eLanguageTypePLI},
    {"objective-c", eLanguageTypeObjC},
    {"objective-c++", eLanguageTypeObjC_plus_plus},
    {"upc", eLanguageTypeUPC},
    {"d", eLanguageTypeD},
    {"python", eLanguageTypePython},
    {"opencl", eLanguageTypeOpenCL},
    {"go", eLanguageTypeGo},
    {"modula3", eLanguageTypeModula3},
    {"haskell", eLanguageTypeHaskell},
    {"c++03", eLanguageTypeC_plus_plus_03},
    {"c++11", eLanguageTypeC_plus_plus_11},
    {"ocaml", eLanguageTypeOCaml},
    {"rust", eLanguageTypeRust},
    {"c11", eLanguageTypeC11},
    {"swift", eLanguageTypeSwift},
    {"julia", eLanguageTypeJulia},
    {"dylan", eLanguageTypeDylan},
    {"c++14", eLanguageTypeC_plus_plus_14},
    {"fortran03", eLanguageTypeFortran03},
    {"fortran08", eLanguageTypeFortran08},
    {"renderscript", eLanguageTypeRenderScript},
    {"bliss", eLanguageTypeBLISS},
    {"kotlin", eLanguageTypeKotlin},
    {"zig", eLanguageTypeZig},
    {"crystal", eLanguageTypeCrystal},
    {"<invalid language>",
     static_cast<LanguageType>(
         0x0029)}, // Not yet taken by any language in the DWARF spec
                   // and thus has no entry in LanguageType
    {"c++17", eLanguageTypeC_plus_plus_17},
    {"c++20", eLanguageTypeC_plus_plus_20},
    {"c17", eLanguageTypeC17},
    {"fortran18", eLanguageTypeFortran18},
    {"ada2005", eLanguageTypeAda2005},
    {"ada2012", eLanguageTypeAda2012},
    {"HIP", eLanguageTypeHIP},
    {"assembly", eLanguageTypeAssembly},
    {"c-sharp", eLanguageTypeC_sharp},
    {"mojo", eLanguageTypeMojo},
    // Vendor Extensions
    {"assembler", eLanguageTypeMipsAssembler},
    // Now synonyms, in arbitrary order
    {"objc", eLanguageTypeObjC},
    {"objc++", eLanguageTypeObjC_plus_plus},
    {"pascal", eLanguageTypePascal83}};

static uint32_t num_languages =
    sizeof(language_names) / sizeof(struct language_name_pair);

LanguageType Language::GetLanguageTypeFromString(llvm::StringRef string) {
  for (const auto &L : language_names) {
    if (string.equals_insensitive(L.name))
      return L.type;
  }

  return eLanguageTypeUnknown;
}

const char *Language::GetNameForLanguageType(LanguageType language) {
  if (language < num_languages)
    return language_names[language].name;
  else
    return language_names[eLanguageTypeUnknown].name;
}

llvm::StringRef Language::GetDisplayNameForLanguageType(LanguageType language) {
  return SourceLanguage(language).GetDescription();
}

void Language::PrintSupportedLanguagesForExpressions(Stream &s,
                                                     llvm::StringRef prefix,
                                                     llvm::StringRef suffix) {
  auto supported = Language::GetLanguagesSupportingTypeSystemsForExpressions();
  for (size_t idx = 0; idx < num_languages; ++idx) {
    auto const &lang = language_names[idx];
    if (supported[lang.type])
      s << prefix << lang.name << suffix;
  }
}

void Language::PrintAllLanguages(Stream &s, const char *prefix,
                                 const char *suffix) {
  for (uint32_t i = 1; i < num_languages; i++) {
    s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
  }
}

void Language::ForAllLanguages(
    llvm::function_ref<IterationAction(lldb::LanguageType)> callback) {
  for (uint32_t i = 1; i < num_languages; i++) {
    if (callback(language_names[i].type) == IterationAction::Stop)
      break;
  }
}

bool Language::LanguageIsCPlusPlus(LanguageType language) {
  switch (language) {
  case eLanguageTypeC_plus_plus:
  case eLanguageTypeC_plus_plus_03:
  case eLanguageTypeC_plus_plus_11:
  case eLanguageTypeC_plus_plus_14:
  case eLanguageTypeC_plus_plus_17:
  case eLanguageTypeC_plus_plus_20:
  case eLanguageTypeObjC_plus_plus:
    return true;
  default:
    return false;
  }
}

bool Language::LanguageIsObjC(LanguageType language) {
  switch (language) {
  case eLanguageTypeObjC:
  case eLanguageTypeObjC_plus_plus:
    return true;
  default:
    return false;
  }
}

bool Language::LanguageIsC(LanguageType language) {
  switch (language) {
  case eLanguageTypeC:
  case eLanguageTypeC89:
  case eLanguageTypeC99:
  case eLanguageTypeC11:
    return true;
  default:
    return false;
  }
}

bool Language::LanguageIsCFamily(LanguageType language) {
  switch (language) {
  case eLanguageTypeC:
  case eLanguageTypeC89:
  case eLanguageTypeC99:
  case eLanguageTypeC11:
  case eLanguageTypeC_plus_plus:
  case eLanguageTypeC_plus_plus_03:
  case eLanguageTypeC_plus_plus_11:
  case eLanguageTypeC_plus_plus_14:
  case eLanguageTypeC_plus_plus_17:
  case eLanguageTypeC_plus_plus_20:
  case eLanguageTypeObjC_plus_plus:
  case eLanguageTypeObjC:
    return true;
  default:
    return false;
  }
}

bool Language::LanguageIsPascal(LanguageType language) {
  switch (language) {
  case eLanguageTypePascal83:
    return true;
  default:
    return false;
  }
}

LanguageType Language::GetPrimaryLanguage(LanguageType language) {
  switch (language) {
  case eLanguageTypeC_plus_plus:
  case eLanguageTypeC_plus_plus_03:
  case eLanguageTypeC_plus_plus_11:
  case eLanguageTypeC_plus_plus_14:
  case eLanguageTypeC_plus_plus_17:
  case eLanguageTypeC_plus_plus_20:
    return eLanguageTypeC_plus_plus;
  case eLanguageTypeC:
  case eLanguageTypeC89:
  case eLanguageTypeC99:
  case eLanguageTypeC11:
    return eLanguageTypeC;
  case eLanguageTypeObjC:
  case eLanguageTypeObjC_plus_plus:
    return eLanguageTypeObjC;
  case eLanguageTypePascal83:
  case eLanguageTypeCobol74:
  case eLanguageTypeCobol85:
  case eLanguageTypeFortran77:
  case eLanguageTypeFortran90:
  case eLanguageTypeFortran95:
  case eLanguageTypeFortran03:
  case eLanguageTypeFortran08:
  case eLanguageTypeAda83:
  case eLanguageTypeAda95:
  case eLanguageTypeModula2:
  case eLanguageTypeJava:
  case eLanguageTypePLI:
  case eLanguageTypeUPC:
  case eLanguageTypeD:
  case eLanguageTypePython:
  case eLanguageTypeOpenCL:
  case eLanguageTypeGo:
  case eLanguageTypeModula3:
  case eLanguageTypeHaskell:
  case eLanguageTypeOCaml:
  case eLanguageTypeRust:
  case eLanguageTypeSwift:
  case eLanguageTypeJulia:
  case eLanguageTypeDylan:
  case eLanguageTypeMipsAssembler:
  case eLanguageTypeMojo:
  case eLanguageTypeUnknown:
  default:
    return language;
  }
}

std::set<lldb::LanguageType> Language::GetSupportedLanguages() {
  std::set<lldb::LanguageType> supported_languages;
  ForEach([&](Language *lang) {
    supported_languages.emplace(lang->GetLanguageType());
    return IterationAction::Continue;
  });
  return supported_languages;
}

LanguageSet Language::GetLanguagesSupportingTypeSystems() {
  return PluginManager::GetAllTypeSystemSupportedLanguagesForTypes();
}

LanguageSet Language::GetLanguagesSupportingTypeSystemsForExpressions() {
  return PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions();
}

LanguageSet Language::GetLanguagesSupportingREPLs() {
  return PluginManager::GetREPLAllTypeSystemSupportedLanguages();
}

std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() {
  return nullptr;
}

const char *Language::GetLanguageSpecificTypeLookupHelp() { return nullptr; }

size_t Language::TypeScavenger::Find(ExecutionContextScope *exe_scope,
                                     const char *key, ResultSet &results,
                                     bool append) {
  if (!exe_scope || !exe_scope->CalculateTarget().get())
    return false;

  if (!key || !key[0])
    return false;

  if (!append)
    results.clear();

  size_t old_size = results.size();

  if (this->Find_Impl(exe_scope, key, results))
    return results.size() - old_size;
  return 0;
}

bool Language::ImageListTypeScavenger::Find_Impl(
    ExecutionContextScope *exe_scope, const char *key, ResultSet &results) {
  bool result = false;

  Target *target = exe_scope->CalculateTarget().get();
  if (target) {
    const auto &images(target->GetImages());
    TypeQuery query(key);
    TypeResults type_results;
    images.FindTypes(nullptr, query, type_results);
    for (const auto &match : type_results.GetTypeMap().Types()) {
      if (match) {
        CompilerType compiler_type(match->GetFullCompilerType());
        compiler_type = AdjustForInclusion(compiler_type);
        if (!compiler_type)
          continue;
        std::unique_ptr<Language::TypeScavenger::Result> scavengeresult(
            new Result(compiler_type));
        results.insert(std::move(scavengeresult));
        result = true;
      }
    }
  }

  return result;
}

std::pair<llvm::StringRef, llvm::StringRef>
Language::GetFormatterPrefixSuffix(llvm::StringRef type_hint) {
  return std::pair<llvm::StringRef, llvm::StringRef>();
}

bool Language::DemangledNameContainsPath(llvm::StringRef path,
                                         ConstString demangled) const {
  // The base implementation does a simple contains comparision:
  if (path.empty())
    return false;
  return demangled.GetStringRef().contains(path);
}

DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper() {
  return nullptr;
}

LazyBool Language::IsLogicalTrue(ValueObject &valobj, Status &error) {
  return eLazyBoolCalculate;
}

bool Language::IsNilReference(ValueObject &valobj) { return false; }

bool Language::IsUninitializedReference(ValueObject &valobj) { return false; }

bool Language::GetFunctionDisplayName(const SymbolContext &sc,
                                      const ExecutionContext *exe_ctx,
                                      FunctionNameRepresentation representation,
                                      Stream &s) {
  return false;
}

void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on,
                                               Stream &s) {
  GetDefaultExceptionResolverDescription(catch_on, throw_on, s);
}

void Language::GetDefaultExceptionResolverDescription(bool catch_on,
                                                      bool throw_on,
                                                      Stream &s) {
  s.Printf("Exception breakpoint (catch: %s throw: %s)",
           catch_on ? "on" : "off", throw_on ? "on" : "off");
}

std::optional<bool> Language::GetBooleanFromString(llvm::StringRef str) const {
  return llvm::StringSwitch<std::optional<bool>>(str)
      .Case("true", {true})
      .Case("false", {false})
      .Default({});
}

// Constructor
Language::Language() = default;

// Destructor
Language::~Language() = default;

static std::optional<llvm::dwarf::SourceLanguage>
ToDwarfSourceLanguage(lldb::LanguageType language_type) {
  if (language_type <= lldb::eLanguageTypeLastStandardLanguage)
    return static_cast<llvm::dwarf::SourceLanguage>(language_type);

  switch (language_type) {
  case eLanguageTypeMipsAssembler:
    return llvm::dwarf::DW_LANG_Mips_Assembler;
  default:
    return std::nullopt;
  }
}

SourceLanguage::SourceLanguage(lldb::LanguageType language_type) {
  std::optional<llvm::dwarf::SourceLanguage> dwarf_lang =
      ToDwarfSourceLanguage(language_type);
  if (!dwarf_lang)
    return;

  auto lname = llvm::dwarf::toDW_LNAME(*dwarf_lang);
  if (!lname)
    return;
  name = lname->first;
  version = lname->second;
}

lldb::LanguageType SourceLanguage::AsLanguageType() const {
  if (auto lang = llvm::dwarf::toDW_LANG((llvm::dwarf::SourceLanguageName)name,
                                         version))
    return (lldb::LanguageType)*lang;
  return lldb::eLanguageTypeUnknown;
}

llvm::StringRef SourceLanguage::GetDescription() const {
  return llvm::dwarf::LanguageDescription(
      static_cast<llvm::dwarf::SourceLanguageName>(name), version);
}
bool SourceLanguage::IsC() const { return name == llvm::dwarf::DW_LNAME_C; }

bool SourceLanguage::IsObjC() const {
  return name == llvm::dwarf::DW_LNAME_ObjC;
}

bool SourceLanguage::IsCPlusPlus() const {
  return name == llvm::dwarf::DW_LNAME_C_plus_plus;
}
