//===-- SymbolFileOnDemand.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>
#include <optional>

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,
                                           SupportFileList &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);
}

std::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 std::nullopt;
  }
  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);
}

Status SymbolFileOnDemand::CalculateFrameVariableError(StackFrame &frame) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return Status();
  }
  return m_sym_file_impl->CalculateFrameVariableError(frame);
}

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,
                                      llvm::StringRef filter) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return;
  }
  return m_sym_file_impl->DumpClangAST(s, filter);
}

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(const TypeQuery &match,
                                   TypeResults &results) {
  if (!m_debug_info_enabled) {
    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
             __FUNCTION__);
    return;
  }
  return m_sym_file_impl->FindTypes(match, results);
}

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<lldb::TypeSystemSP>
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::createStringError(
        "GetTypeSystemForLanguage is skipped by SymbolFileOnDemand");
  }
  return m_sym_file_impl->GetTypeSystemForLanguage(language);
}

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

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(bool load_all_debug_info) {
  // Always return the real debug info size.
  LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
           __FUNCTION__);
  return m_sym_file_impl->GetDebugInfoSize(load_all_debug_info);
}

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::ResetStatistics() {
  LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
           __FUNCTION__);
  return m_sym_file_impl->ResetStatistics();
}

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();
}
