//===-- SymbolFileDWARFDebugMap.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 "lldb/Symbol/SymbolFileOnDemand.h"

#include "lldb/Core/Module.h"
#include "lldb/Symbol/SymbolFile.h"

#include <memory>

using namespace lldb;
using namespace lldb_private;

char SymbolFileOnDemand::ID;

SymbolFileOnDemand::SymbolFileOnDemand(
    std::unique_ptr<SymbolFile> &&symbol_file)
    : m_sym_file_impl(std::move(symbol_file)) {}

SymbolFileOnDemand::~SymbolFileOnDemand() = default;

uint32_t SymbolFileOnDemand::CalculateAbilities() {
  // Explicitly allow ability checking to pass though.
  // This should be a cheap operation.
  return m_sym_file_impl->CalculateAbilities();
}

std::recursive_mutex &SymbolFileOnDemand::GetModuleMutex() const {
  return m_sym_file_impl->GetModuleMutex();
}

void SymbolFileOnDemand::InitializeObject() {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return;
  }
  return m_sym_file_impl->InitializeObject();
}

lldb::LanguageType SymbolFileOnDemand::ParseLanguage(CompileUnit &comp_unit) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
    if (log) {
      lldb::LanguageType langType = m_sym_file_impl->ParseLanguage(comp_unit);
      if (langType != eLanguageTypeUnknown)
        LLDB_LOG(log, "Language {0} would return if hydrated.", langType);
    }
    return eLanguageTypeUnknown;
  }
  return m_sym_file_impl->ParseLanguage(comp_unit);
}

XcodeSDK SymbolFileOnDemand::ParseXcodeSDK(CompileUnit &comp_unit) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
    XcodeSDK defaultValue{};
    if (log) {
      XcodeSDK sdk = m_sym_file_impl->ParseXcodeSDK(comp_unit);
      if (!(sdk == defaultValue))
        LLDB_LOG(log, "SDK {0} would return if hydrated.", sdk.GetString());
    }
    return defaultValue;
  }
  return m_sym_file_impl->ParseXcodeSDK(comp_unit);
}

size_t SymbolFileOnDemand::ParseFunctions(CompileUnit &comp_unit) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return 0;
  }
  return m_sym_file_impl->ParseFunctions(comp_unit);
}

bool SymbolFileOnDemand::ParseLineTable(CompileUnit &comp_unit) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return false;
  }
  return m_sym_file_impl->ParseLineTable(comp_unit);
}

bool SymbolFileOnDemand::ParseDebugMacros(CompileUnit &comp_unit) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return false;
  }
  return m_sym_file_impl->ParseDebugMacros(comp_unit);
}

bool SymbolFileOnDemand::ForEachExternalModule(
    CompileUnit &comp_unit,
    llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
    llvm::function_ref<bool(Module &)> lambda) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    // Return false to not early exit.
    return false;
  }
  return m_sym_file_impl->ForEachExternalModule(comp_unit, visited_symbol_files,
                                                lambda);
}

bool SymbolFileOnDemand::ParseSupportFiles(CompileUnit &comp_unit,
                                           FileSpecList &support_files) {
  LLDB_LOG(GetLog(),
           "[{0}] {1} is not skipped: explicitly allowed to support breakpoint",
           GetSymbolFileName(), __FUNCTION__);
  // Explicitly allow this API through to support source line breakpoint.
  return m_sym_file_impl->ParseSupportFiles(comp_unit, support_files);
}

bool SymbolFileOnDemand::ParseIsOptimized(CompileUnit &comp_unit) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
    if (log) {
      bool optimized = m_sym_file_impl->ParseIsOptimized(comp_unit);
      if (optimized) {
        LLDB_LOG(log, "Would return optimized if hydrated.");
      }
    }
    return false;
  }
  return m_sym_file_impl->ParseIsOptimized(comp_unit);
}

size_t SymbolFileOnDemand::ParseTypes(CompileUnit &comp_unit) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return 0;
  }
  return m_sym_file_impl->ParseTypes(comp_unit);
}

bool SymbolFileOnDemand::ParseImportedModules(
    const lldb_private::SymbolContext &sc,
    std::vector<SourceModule> &imported_modules) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
    if (log) {
      std::vector<SourceModule> tmp_imported_modules;
      bool succeed =
          m_sym_file_impl->ParseImportedModules(sc, tmp_imported_modules);
      if (succeed)
        LLDB_LOG(log, "{0} imported modules would be parsed if hydrated.",
                 tmp_imported_modules.size());
    }
    return false;
  }
  return m_sym_file_impl->ParseImportedModules(sc, imported_modules);
}

size_t SymbolFileOnDemand::ParseBlocksRecursive(Function &func) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return 0;
  }
  return m_sym_file_impl->ParseBlocksRecursive(func);
}

size_t SymbolFileOnDemand::ParseVariablesForContext(const SymbolContext &sc) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return 0;
  }
  return m_sym_file_impl->ParseVariablesForContext(sc);
}

Type *SymbolFileOnDemand::ResolveTypeUID(lldb::user_id_t type_uid) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
    if (log) {
      Type *resolved_type = m_sym_file_impl->ResolveTypeUID(type_uid);
      if (resolved_type)
        LLDB_LOG(log, "Type would be parsed for {0} if hydrated.", type_uid);
    }
    return nullptr;
  }
  return m_sym_file_impl->ResolveTypeUID(type_uid);
}

llvm::Optional<SymbolFile::ArrayInfo>
SymbolFileOnDemand::GetDynamicArrayInfoForUID(
    lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return llvm::None;
  }
  return m_sym_file_impl->GetDynamicArrayInfoForUID(type_uid, exe_ctx);
}

bool SymbolFileOnDemand::CompleteType(CompilerType &compiler_type) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return false;
  }
  return m_sym_file_impl->CompleteType(compiler_type);
}

CompilerDecl SymbolFileOnDemand::GetDeclForUID(lldb::user_id_t type_uid) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
    if (log) {
      CompilerDecl parsed_decl = m_sym_file_impl->GetDeclForUID(type_uid);
      if (parsed_decl != CompilerDecl()) {
        LLDB_LOG(log, "CompilerDecl {0} would be parsed for {1} if hydrated.",
                 parsed_decl.GetName(), type_uid);
      }
    }
    return CompilerDecl();
  }
  return m_sym_file_impl->GetDeclForUID(type_uid);
}

CompilerDeclContext
SymbolFileOnDemand::GetDeclContextForUID(lldb::user_id_t type_uid) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return CompilerDeclContext();
  }
  return m_sym_file_impl->GetDeclContextForUID(type_uid);
}

CompilerDeclContext
SymbolFileOnDemand::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return CompilerDeclContext();
  }
  return m_sym_file_impl->GetDeclContextContainingUID(type_uid);
}

void SymbolFileOnDemand::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return;
  }
  return m_sym_file_impl->ParseDeclsForContext(decl_ctx);
}

uint32_t
SymbolFileOnDemand::ResolveSymbolContext(const Address &so_addr,
                                         SymbolContextItem resolve_scope,
                                         SymbolContext &sc) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return 0;
  }
  return m_sym_file_impl->ResolveSymbolContext(so_addr, resolve_scope, sc);
}

uint32_t SymbolFileOnDemand::ResolveSymbolContext(
    const SourceLocationSpec &src_location_spec,
    SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return 0;
  }
  return m_sym_file_impl->ResolveSymbolContext(src_location_spec, resolve_scope,
                                               sc_list);
}

void SymbolFileOnDemand::Dump(lldb_private::Stream &s) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return;
  }
  return m_sym_file_impl->Dump(s);
}

void SymbolFileOnDemand::DumpClangAST(lldb_private::Stream &s) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return;
  }
  return m_sym_file_impl->DumpClangAST(s);
}

void SymbolFileOnDemand::FindGlobalVariables(const RegularExpression &regex,
                                             uint32_t max_matches,
                                             VariableList &variables) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return;
  }
  return m_sym_file_impl->FindGlobalVariables(regex, max_matches, variables);
}

void SymbolFileOnDemand::FindGlobalVariables(
    ConstString name, const CompilerDeclContext &parent_decl_ctx,
    uint32_t max_matches, VariableList &variables) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    Symtab *symtab = GetSymtab();
    if (!symtab) {
      LLDB_LOG(log, "[{0}] {1} is skipped - fail to get symtab",
               GetSymbolFileName(), __FUNCTION__);
      return;
    }
    Symbol *sym = symtab->FindFirstSymbolWithNameAndType(
        name, eSymbolTypeData, Symtab::eDebugAny, Symtab::eVisibilityAny);
    if (!sym) {
      LLDB_LOG(log, "[{0}] {1} is skipped - fail to find match in symtab",
               GetSymbolFileName(), __FUNCTION__);
      return;
    }
    LLDB_LOG(log, "[{0}] {1} is NOT skipped - found match in symtab",
             GetSymbolFileName(), __FUNCTION__);

    // Found match in symbol table hydrate debug info and
    // allow the FindGlobalVariables to go through.
    SetLoadDebugInfoEnabled();
  }
  return m_sym_file_impl->FindGlobalVariables(name, parent_decl_ctx,
                                              max_matches, variables);
}

void SymbolFileOnDemand::FindFunctions(const RegularExpression &regex,
                                       bool include_inlines,
                                       SymbolContextList &sc_list) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    Symtab *symtab = GetSymtab();
    if (!symtab) {
      LLDB_LOG(log, "[{0}] {1} is skipped - fail to get symtab",
               GetSymbolFileName(), __FUNCTION__);
      return;
    }
    std::vector<uint32_t> symbol_indexes;
    symtab->AppendSymbolIndexesMatchingRegExAndType(
        regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny,
        symbol_indexes);
    if (symbol_indexes.empty()) {
      LLDB_LOG(log, "[{0}] {1} is skipped - fail to find match in symtab",
               GetSymbolFileName(), __FUNCTION__);
      return;
    }
    LLDB_LOG(log, "[{0}] {1} is NOT skipped - found match in symtab",
             GetSymbolFileName(), __FUNCTION__);

    // Found match in symbol table hydrate debug info and
    // allow the FindFucntions to go through.
    SetLoadDebugInfoEnabled();
  }
  return m_sym_file_impl->FindFunctions(regex, include_inlines, sc_list);
}

void SymbolFileOnDemand::FindFunctions(
    const Module::LookupInfo &lookup_info,
    const CompilerDeclContext &parent_decl_ctx, bool include_inlines,
    SymbolContextList &sc_list) {
  ConstString name = lookup_info.GetLookupName();
  FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();
  if (!m_debug_info_enabled) {
    Log *log = GetLog();

    Symtab *symtab = GetSymtab();
    if (!symtab) {
      LLDB_LOG(log, "[{0}] {1}({2}) is skipped  - fail to get symtab",
               GetSymbolFileName(), __FUNCTION__, name);
      return;
    }

    SymbolContextList sc_list_helper;
    symtab->FindFunctionSymbols(name, name_type_mask, sc_list_helper);
    if (sc_list_helper.GetSize() == 0) {
      LLDB_LOG(log, "[{0}] {1}({2}) is skipped - fail to find match in symtab",
               GetSymbolFileName(), __FUNCTION__, name);
      return;
    }
    LLDB_LOG(log, "[{0}] {1}({2}) is NOT skipped - found match in symtab",
             GetSymbolFileName(), __FUNCTION__, name);

    // Found match in symbol table hydrate debug info and
    // allow the FindFucntions to go through.
    SetLoadDebugInfoEnabled();
  }
  return m_sym_file_impl->FindFunctions(lookup_info, parent_decl_ctx,
                                        include_inlines, sc_list);
}

void SymbolFileOnDemand::GetMangledNamesForFunction(
    const std::string &scope_qualified_name,
    std::vector<ConstString> &mangled_names) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    LLDB_LOG(log, "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
             __FUNCTION__, scope_qualified_name);
    return;
  }
  return m_sym_file_impl->GetMangledNamesForFunction(scope_qualified_name,
                                                     mangled_names);
}

void SymbolFileOnDemand::FindTypes(
    ConstString name, const CompilerDeclContext &parent_decl_ctx,
    uint32_t max_matches,
    llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
    TypeMap &types) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    LLDB_LOG(log, "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
             __FUNCTION__, name);
    return;
  }
  return m_sym_file_impl->FindTypes(name, parent_decl_ctx, max_matches,
                                    searched_symbol_files, types);
}

void SymbolFileOnDemand::FindTypes(
    llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
    llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return;
  }
  return m_sym_file_impl->FindTypes(pattern, languages, searched_symbol_files,
                                    types);
}

void SymbolFileOnDemand::GetTypes(SymbolContextScope *sc_scope,
                                  TypeClass type_mask, TypeList &type_list) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return;
  }
  return m_sym_file_impl->GetTypes(sc_scope, type_mask, type_list);
}

llvm::Expected<TypeSystem &>
SymbolFileOnDemand::GetTypeSystemForLanguage(LanguageType language) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    LLDB_LOG(log, "[{0}] {1} is skipped for language type {2}",
             GetSymbolFileName(), __FUNCTION__, language);
    return llvm::make_error<llvm::StringError>(
        "GetTypeSystemForLanguage is skipped by SymbolFileOnDemand",
        llvm::inconvertibleErrorCode());
  }
  return m_sym_file_impl->GetTypeSystemForLanguage(language);
}

CompilerDeclContext
SymbolFileOnDemand::FindNamespace(ConstString name,
                                  const CompilerDeclContext &parent_decl_ctx) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
             __FUNCTION__, name);
    return SymbolFile::FindNamespace(name, parent_decl_ctx);
  }
  return m_sym_file_impl->FindNamespace(name, parent_decl_ctx);
}

std::vector<std::unique_ptr<lldb_private::CallEdge>>
SymbolFileOnDemand::ParseCallEdgesInFunction(UserID func_id) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
    if (log) {
      std::vector<std::unique_ptr<lldb_private::CallEdge>> call_edges =
          m_sym_file_impl->ParseCallEdgesInFunction(func_id);
      if (call_edges.size() > 0) {
        LLDB_LOG(log, "{0} call edges would be parsed for {1} if hydrated.",
                 call_edges.size(), func_id.GetID());
      }
    }
    return {};
  }
  return m_sym_file_impl->ParseCallEdgesInFunction(func_id);
}

lldb::UnwindPlanSP
SymbolFileOnDemand::GetUnwindPlan(const Address &address,
                                  const RegisterInfoResolver &resolver) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return nullptr;
  }
  return m_sym_file_impl->GetUnwindPlan(address, resolver);
}

llvm::Expected<lldb::addr_t>
SymbolFileOnDemand::GetParameterStackSize(Symbol &symbol) {
  if (!m_debug_info_enabled) {
    Log *log = GetLog();
    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
    if (log) {
      llvm::Expected<lldb::addr_t> stack_size =
          m_sym_file_impl->GetParameterStackSize(symbol);
      if (stack_size) {
        LLDB_LOG(log, "{0} stack size would return for symbol {1} if hydrated.",
                 *stack_size, symbol.GetName());
      }
    }
    return SymbolFile::GetParameterStackSize(symbol);
  }
  return m_sym_file_impl->GetParameterStackSize(symbol);
}

void SymbolFileOnDemand::PreloadSymbols() {
  m_preload_symbols = true;
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return;
  }
  return m_sym_file_impl->PreloadSymbols();
}

uint64_t SymbolFileOnDemand::GetDebugInfoSize() {
  // Always return the real debug info size.
  LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
           __FUNCTION__);
  return m_sym_file_impl->GetDebugInfoSize();
}

StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoParseTime() {
  // Always return the real parse time.
  LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
           __FUNCTION__);
  return m_sym_file_impl->GetDebugInfoParseTime();
}

StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoIndexTime() {
  // Always return the real index time.
  LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
           __FUNCTION__);
  return m_sym_file_impl->GetDebugInfoIndexTime();
}

void SymbolFileOnDemand::SetLoadDebugInfoEnabled() {
  if (m_debug_info_enabled)
    return;
  LLDB_LOG(GetLog(), "[{0}] Hydrate debug info", GetSymbolFileName());
  m_debug_info_enabled = true;
  InitializeObject();
  if (m_preload_symbols)
    PreloadSymbols();
}

uint32_t SymbolFileOnDemand::GetNumCompileUnits() {
  LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration",
           GetSymbolFileName(), __FUNCTION__);
  return m_sym_file_impl->GetNumCompileUnits();
}

CompUnitSP SymbolFileOnDemand::GetCompileUnitAtIndex(uint32_t idx) {
  LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration",
           GetSymbolFileName(), __FUNCTION__);
  return m_sym_file_impl->GetCompileUnitAtIndex(idx);
}

uint32_t SymbolFileOnDemand::GetAbilities() {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return 0;
  }
  return m_sym_file_impl->GetAbilities();
}
