//===-- FormatEntity.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/Core/FormatEntity.h"

#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/DumpRegisterValue.h"
#include "lldb/Core/Module.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/DataFormatters/FormatClasses.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/LineEntry.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/BorrowedStackFrame.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/AnsiTerminal.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringList.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectVariable.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-forward.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Regex.h"
#include "llvm/TargetParser/Triple.h"

#include <cassert>
#include <cctype>
#include <cinttypes>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <type_traits>
#include <utility>

namespace lldb_private {
class ScriptInterpreter;
}
namespace lldb_private {
struct RegisterInfo;
}

using namespace lldb;
using namespace lldb_private;

using Definition = lldb_private::FormatEntity::Entry::Definition;
using Entry = FormatEntity::Entry;
using EntryType = FormatEntity::Entry::Type;

enum FileKind { FileError = 0, Basename, Dirname, Fullpath };

constexpr Definition g_string_entry[] = {
    Definition("*", EntryType::ParentString)};

constexpr Definition g_addr_entries[] = {
    Definition("load", EntryType::AddressLoad),
    Definition("file", EntryType::AddressFile)};

constexpr Definition g_file_child_entries[] = {
    Definition("basename", EntryType::ParentNumber, FileKind::Basename),
    Definition("dirname", EntryType::ParentNumber, FileKind::Dirname),
    Definition("fullpath", EntryType::ParentNumber, FileKind::Fullpath)};

constexpr Definition g_frame_child_entries[] = {
    Definition("index", EntryType::FrameIndex),
    Definition("pc", EntryType::FrameRegisterPC),
    Definition("fp", EntryType::FrameRegisterFP),
    Definition("sp", EntryType::FrameRegisterSP),
    Definition("flags", EntryType::FrameRegisterFlags),
    Definition("no-debug", EntryType::FrameNoDebug),
    Entry::DefinitionWithChildren("reg", EntryType::FrameRegisterByName,
                                  g_string_entry),
    Definition("is-artificial", EntryType::FrameIsArtificial),
    Definition("kind", EntryType::FrameKind),
    Definition("borrowed-info", EntryType::FrameBorrowedInfo),
};

constexpr Definition g_function_child_entries[] = {
    Definition("id", EntryType::FunctionID),
    Definition("name", EntryType::FunctionName),
    Definition("name-without-args", EntryType::FunctionNameNoArgs),
    Definition("name-with-args", EntryType::FunctionNameWithArgs),
    Definition("mangled-name", EntryType::FunctionMangledName),
    Definition("addr-offset", EntryType::FunctionAddrOffset),
    Definition("concrete-only-addr-offset-no-padding",
               EntryType::FunctionAddrOffsetConcrete),
    Definition("line-offset", EntryType::FunctionLineOffset),
    Definition("pc-offset", EntryType::FunctionPCOffset),
    Definition("initial-function", EntryType::FunctionInitial),
    Definition("changed", EntryType::FunctionChanged),
    Definition("is-optimized", EntryType::FunctionIsOptimized),
    Definition("is-inlined", EntryType::FunctionIsInlined),
    Definition("prefix", EntryType::FunctionPrefix),
    Definition("scope", EntryType::FunctionScope),
    Definition("basename", EntryType::FunctionBasename),
    Definition("name-qualifiers", EntryType::FunctionNameQualifiers),
    Definition("template-arguments", EntryType::FunctionTemplateArguments),
    Definition("formatted-arguments", EntryType::FunctionFormattedArguments),
    Definition("return-left", EntryType::FunctionReturnLeft),
    Definition("return-right", EntryType::FunctionReturnRight),
    Definition("qualifiers", EntryType::FunctionQualifiers),
    Definition("suffix", EntryType::FunctionSuffix),
};

constexpr Definition g_line_child_entries[] = {
    Entry::DefinitionWithChildren("file", EntryType::LineEntryFile,
                                  g_file_child_entries),
    Definition("number", EntryType::LineEntryLineNumber),
    Definition("column", EntryType::LineEntryColumn),
    Definition("start-addr", EntryType::LineEntryStartAddress),
    Definition("end-addr", EntryType::LineEntryEndAddress),
};

constexpr Definition g_module_child_entries[] = {Entry::DefinitionWithChildren(
    "file", EntryType::ModuleFile, g_file_child_entries)};

constexpr Definition g_process_child_entries[] = {
    Definition("id", EntryType::ProcessID),
    Definition("name", EntryType::ProcessFile, FileKind::Basename),
    Entry::DefinitionWithChildren("file", EntryType::ProcessFile,
                                  g_file_child_entries)};

constexpr Definition g_svar_child_entries[] = {
    Definition("*", EntryType::ParentString)};

constexpr Definition g_var_child_entries[] = {
    Definition("*", EntryType::ParentString)};

constexpr Definition g_thread_child_entries[] = {
    Definition("id", EntryType::ThreadID),
    Definition("protocol_id", EntryType::ThreadProtocolID),
    Definition("index", EntryType::ThreadIndexID),
    Entry::DefinitionWithChildren("info", EntryType::ThreadInfo,
                                  g_string_entry),
    Definition("queue", EntryType::ThreadQueue),
    Definition("name", EntryType::ThreadName),
    Definition("stop-reason", EntryType::ThreadStopReason),
    Definition("stop-reason-raw", EntryType::ThreadStopReasonRaw),
    Definition("return-value", EntryType::ThreadReturnValue),
    Definition("completed-expression", EntryType::ThreadCompletedExpression)};

constexpr Definition g_target_child_entries[] = {
    Definition("arch", EntryType::TargetArch),
    Entry::DefinitionWithChildren("file", EntryType::TargetFile,
                                  g_file_child_entries)};

constexpr Definition g_progress_child_entries[] = {
    Definition("count", EntryType::ProgressCount),
    Definition("message", EntryType::ProgressMessage)};

#define _TO_STR2(_val) #_val
#define _TO_STR(_val) _TO_STR2(_val)

constexpr Definition g_ansi_fg_entries[] = {
    Definition("black",
               ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END),
    Definition("red", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END),
    Definition("green",
               ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END),
    Definition("yellow",
               ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END),
    Definition("blue", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END),
    Definition("purple",
               ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END),
    Definition("cyan", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END),
    Definition("white",
               ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END),
};

constexpr Definition g_ansi_bg_entries[] = {
    Definition("black",
               ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END),
    Definition("red", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END),
    Definition("green",
               ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END),
    Definition("yellow",
               ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END),
    Definition("blue", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END),
    Definition("purple",
               ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END),
    Definition("cyan", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END),
    Definition("white",
               ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END),
};

constexpr Definition g_ansi_entries[] = {
    Entry::DefinitionWithChildren("fg", EntryType::Invalid, g_ansi_fg_entries),
    Entry::DefinitionWithChildren("bg", EntryType::Invalid, g_ansi_bg_entries),
    Definition("normal", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END),
    Definition("bold", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END),
    Definition("faint", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END),
    Definition("italic", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END),
    Definition("underline",
               ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END),
    Definition("slow-blink",
               ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END),
    Definition("fast-blink",
               ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END),
    Definition("negative",
               ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END),
    Definition("conceal",
               ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END),
    Definition("crossed-out",
               ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END),
};

constexpr Definition g_script_child_entries[] = {
    Definition("frame", EntryType::ScriptFrame),
    Definition("process", EntryType::ScriptProcess),
    Definition("target", EntryType::ScriptTarget),
    Definition("thread", EntryType::ScriptThread),
    Definition("var", EntryType::ScriptVariable),
    Definition("svar", EntryType::ScriptVariableSynthetic),
    Definition("thread", EntryType::ScriptThread)};

constexpr Definition g_top_level_entries[] = {
    Entry::DefinitionWithChildren("addr", EntryType::AddressLoadOrFile,
                                  g_addr_entries),
    Definition("addr-file-or-load", EntryType::AddressLoadOrFile),
    Entry::DefinitionWithChildren("ansi", EntryType::Invalid, g_ansi_entries),
    Definition("current-pc-arrow", EntryType::CurrentPCArrow),
    Entry::DefinitionWithChildren("file", EntryType::File,
                                  g_file_child_entries),
    Definition("language", EntryType::Lang),
    Entry::DefinitionWithChildren("frame", EntryType::Invalid,
                                  g_frame_child_entries),
    Entry::DefinitionWithChildren("function", EntryType::Invalid,
                                  g_function_child_entries),
    Entry::DefinitionWithChildren("line", EntryType::Invalid,
                                  g_line_child_entries),
    Entry::DefinitionWithChildren("module", EntryType::Invalid,
                                  g_module_child_entries),
    Entry::DefinitionWithChildren("process", EntryType::Invalid,
                                  g_process_child_entries),
    Entry::DefinitionWithChildren("script", EntryType::Invalid,
                                  g_script_child_entries),
    Entry::DefinitionWithChildren("svar", EntryType::VariableSynthetic,
                                  g_svar_child_entries, true),
    Entry::DefinitionWithChildren("thread", EntryType::Invalid,
                                  g_thread_child_entries),
    Entry::DefinitionWithChildren("target", EntryType::Invalid,
                                  g_target_child_entries),
    Entry::DefinitionWithChildren("var", EntryType::Variable,
                                  g_var_child_entries, true),
    Entry::DefinitionWithChildren("progress", EntryType::Invalid,
                                  g_progress_child_entries),
    Definition("separator", EntryType::Separator),
};

constexpr Definition g_root = Entry::DefinitionWithChildren(
    "<root>", EntryType::Root, g_top_level_entries);

FormatEntity::Entry::Entry(Type t, const char *s, const char *f)
    : string(s ? s : ""), printf_format(f ? f : ""), children_stack({{}}),
      type(t) {}

FormatEntity::Entry::Entry(llvm::StringRef s)
    : string(s.data(), s.size()), children_stack({{}}), type(Type::String) {}

FormatEntity::Entry::Entry(char ch)
    : string(1, ch), printf_format(), children_stack({{}}), type(Type::String) {
}

std::vector<Entry> &FormatEntity::Entry::GetChildren() {
  assert(level < children_stack.size());
  return children_stack[level];
}

void FormatEntity::Entry::AppendChar(char ch) {
  auto &entries = GetChildren();
  if (entries.empty() || entries.back().type != Entry::Type::String)
    entries.push_back(Entry(ch));
  else
    entries.back().string.append(1, ch);
}

void FormatEntity::Entry::AppendText(const llvm::StringRef &s) {
  auto &entries = GetChildren();
  if (entries.empty() || entries.back().type != Entry::Type::String)
    entries.push_back(Entry(s));
  else
    entries.back().string.append(s.data(), s.size());
}

void FormatEntity::Entry::AppendText(const char *cstr) {
  return AppendText(llvm::StringRef(cstr));
}

void FormatEntity::Entry::AppendEntry(const Entry &&entry) {
  auto &entries = GetChildren();
  entries.push_back(entry);
}

void FormatEntity::Entry::StartAlternative() {
  assert(type == Entry::Type::Scope);
  children_stack.emplace_back();
  level++;
}

#define ENUM_TO_CSTR(eee)                                                      \
  case FormatEntity::Entry::Type::eee:                                         \
    return #eee

const char *FormatEntity::Entry::TypeToCString(Type t) {
  switch (t) {
    ENUM_TO_CSTR(Invalid);
    ENUM_TO_CSTR(ParentNumber);
    ENUM_TO_CSTR(ParentString);
    ENUM_TO_CSTR(EscapeCode);
    ENUM_TO_CSTR(Root);
    ENUM_TO_CSTR(String);
    ENUM_TO_CSTR(Scope);
    ENUM_TO_CSTR(Variable);
    ENUM_TO_CSTR(VariableSynthetic);
    ENUM_TO_CSTR(ScriptVariable);
    ENUM_TO_CSTR(ScriptVariableSynthetic);
    ENUM_TO_CSTR(AddressLoad);
    ENUM_TO_CSTR(AddressFile);
    ENUM_TO_CSTR(AddressLoadOrFile);
    ENUM_TO_CSTR(ProcessID);
    ENUM_TO_CSTR(ProcessFile);
    ENUM_TO_CSTR(ScriptProcess);
    ENUM_TO_CSTR(ThreadID);
    ENUM_TO_CSTR(ThreadProtocolID);
    ENUM_TO_CSTR(ThreadIndexID);
    ENUM_TO_CSTR(ThreadName);
    ENUM_TO_CSTR(ThreadQueue);
    ENUM_TO_CSTR(ThreadStopReason);
    ENUM_TO_CSTR(ThreadStopReasonRaw);
    ENUM_TO_CSTR(ThreadReturnValue);
    ENUM_TO_CSTR(ThreadCompletedExpression);
    ENUM_TO_CSTR(ScriptThread);
    ENUM_TO_CSTR(ThreadInfo);
    ENUM_TO_CSTR(TargetArch);
    ENUM_TO_CSTR(TargetFile);
    ENUM_TO_CSTR(ScriptTarget);
    ENUM_TO_CSTR(ModuleFile);
    ENUM_TO_CSTR(File);
    ENUM_TO_CSTR(Lang);
    ENUM_TO_CSTR(FrameIndex);
    ENUM_TO_CSTR(FrameNoDebug);
    ENUM_TO_CSTR(FrameRegisterPC);
    ENUM_TO_CSTR(FrameRegisterSP);
    ENUM_TO_CSTR(FrameRegisterFP);
    ENUM_TO_CSTR(FrameRegisterFlags);
    ENUM_TO_CSTR(FrameRegisterByName);
    ENUM_TO_CSTR(FrameIsArtificial);
    ENUM_TO_CSTR(FrameKind);
    ENUM_TO_CSTR(FrameBorrowedInfo);
    ENUM_TO_CSTR(ScriptFrame);
    ENUM_TO_CSTR(FunctionID);
    ENUM_TO_CSTR(FunctionDidChange);
    ENUM_TO_CSTR(FunctionInitialFunction);
    ENUM_TO_CSTR(FunctionName);
    ENUM_TO_CSTR(FunctionNameWithArgs);
    ENUM_TO_CSTR(FunctionNameNoArgs);
    ENUM_TO_CSTR(FunctionMangledName);
    ENUM_TO_CSTR(FunctionPrefix);
    ENUM_TO_CSTR(FunctionScope);
    ENUM_TO_CSTR(FunctionBasename);
    ENUM_TO_CSTR(FunctionNameQualifiers);
    ENUM_TO_CSTR(FunctionTemplateArguments);
    ENUM_TO_CSTR(FunctionFormattedArguments);
    ENUM_TO_CSTR(FunctionReturnLeft);
    ENUM_TO_CSTR(FunctionReturnRight);
    ENUM_TO_CSTR(FunctionQualifiers);
    ENUM_TO_CSTR(FunctionSuffix);
    ENUM_TO_CSTR(FunctionAddrOffset);
    ENUM_TO_CSTR(FunctionAddrOffsetConcrete);
    ENUM_TO_CSTR(FunctionLineOffset);
    ENUM_TO_CSTR(FunctionPCOffset);
    ENUM_TO_CSTR(FunctionInitial);
    ENUM_TO_CSTR(FunctionChanged);
    ENUM_TO_CSTR(FunctionIsOptimized);
    ENUM_TO_CSTR(FunctionIsInlined);
    ENUM_TO_CSTR(LineEntryFile);
    ENUM_TO_CSTR(LineEntryLineNumber);
    ENUM_TO_CSTR(LineEntryColumn);
    ENUM_TO_CSTR(LineEntryStartAddress);
    ENUM_TO_CSTR(LineEntryEndAddress);
    ENUM_TO_CSTR(CurrentPCArrow);
    ENUM_TO_CSTR(ProgressCount);
    ENUM_TO_CSTR(ProgressMessage);
    ENUM_TO_CSTR(Separator);
  }
  return "???";
}

#undef ENUM_TO_CSTR

void FormatEntity::Entry::Dump(Stream &s, int depth) const {
  s.Printf("%*.*s%-20s: ", depth * 2, depth * 2, "", TypeToCString(type));
  if (fmt != eFormatDefault)
    s.Printf("lldb-format = %s, ", FormatManager::GetFormatAsCString(fmt));
  if (!string.empty())
    s.Printf("string = \"%s\"", string.c_str());
  if (!printf_format.empty())
    s.Printf("printf_format = \"%s\"", printf_format.c_str());
  if (number != 0)
    s.Printf("number = %" PRIu64 " (0x%" PRIx64 "), ", number, number);
  if (deref)
    s.Printf("deref = true, ");
  s.EOL();
  for (const auto &children : children_stack) {
    for (const auto &child : children)
      child.Dump(s, depth + 1);
  }
}

template <typename T>
static bool RunScriptFormatKeyword(Stream &s, const SymbolContext *sc,
                                   const ExecutionContext *exe_ctx, T t,
                                   const char *script_function_name) {
  Target *target = Target::GetTargetFromContexts(exe_ctx, sc);

  if (target) {
    ScriptInterpreter *script_interpreter =
        target->GetDebugger().GetScriptInterpreter();
    if (script_interpreter) {
      Status error;
      std::string script_output;

      if (script_interpreter->RunScriptFormatKeyword(script_function_name, t,
                                                     script_output, error) &&
          error.Success()) {
        s.Printf("%s", script_output.c_str());
        return true;
      } else {
        s.Printf("<error: %s>", error.AsCString());
      }
    }
  }
  return false;
}

static bool DumpAddressAndContent(Stream &s, const SymbolContext *sc,
                                  const ExecutionContext *exe_ctx,
                                  const Address &addr,
                                  bool print_file_addr_or_load_addr) {
  Target *target = Target::GetTargetFromContexts(exe_ctx, sc);

  addr_t vaddr = addr.GetLoadAddress(target);
  if (vaddr == LLDB_INVALID_ADDRESS)
    vaddr = addr.GetFileAddress();
  if (vaddr == LLDB_INVALID_ADDRESS)
    return false;

  int addr_width = 0;
  if (target)
    addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
  if (addr_width == 0)
    addr_width = 16;

  if (print_file_addr_or_load_addr) {
    ExecutionContextScope *exe_scope =
        exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
    addr.Dump(&s, exe_scope, Address::DumpStyleLoadAddress,
              Address::DumpStyleModuleWithFileAddress, 0);
  } else {
    s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
  }

  return true;
}

static bool DumpAddressOffsetFromFunction(Stream &s, const SymbolContext *sc,
                                          const ExecutionContext *exe_ctx,
                                          const Address &format_addr,
                                          bool concrete_only, bool no_padding,
                                          bool print_zero_offsets) {
  if (format_addr.IsValid()) {
    Address func_addr;

    if (sc) {
      if (sc->function) {
        func_addr = sc->function->GetAddress();
        if (sc->block && !concrete_only) {
          // Check to make sure we aren't in an inline function. If we are, use
          // the inline block range that contains "format_addr" since blocks
          // can be discontiguous.
          Block *inline_block = sc->block->GetContainingInlinedBlock();
          AddressRange inline_range;
          if (inline_block && inline_block->GetRangeContainingAddress(
                                  format_addr, inline_range))
            func_addr = inline_range.GetBaseAddress();
        }
      } else if (sc->symbol && sc->symbol->ValueIsAddress())
        func_addr = sc->symbol->GetAddressRef();
    }

    if (func_addr.IsValid()) {
      const char *addr_offset_padding = no_padding ? "" : " ";

      if (func_addr.GetModule() == format_addr.GetModule()) {
        addr_t func_file_addr = func_addr.GetFileAddress();
        addr_t addr_file_addr = format_addr.GetFileAddress();
        if (addr_file_addr > func_file_addr ||
            (addr_file_addr == func_file_addr && print_zero_offsets)) {
          s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
                   addr_file_addr - func_file_addr);
        } else if (addr_file_addr < func_file_addr) {
          s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
                   func_file_addr - addr_file_addr);
        }
        return true;
      } else {
        Target *target = Target::GetTargetFromContexts(exe_ctx, sc);
        if (target) {
          addr_t func_load_addr = func_addr.GetLoadAddress(target);
          addr_t addr_load_addr = format_addr.GetLoadAddress(target);
          if (addr_load_addr > func_load_addr ||
              (addr_load_addr == func_load_addr && print_zero_offsets)) {
            s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
                     addr_load_addr - func_load_addr);
          } else if (addr_load_addr < func_load_addr) {
            s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
                     func_load_addr - addr_load_addr);
          }
          return true;
        }
      }
    }
  }
  return false;
}

static bool ScanBracketedRange(llvm::StringRef subpath,
                               size_t &close_bracket_index,
                               const char *&var_name_final_if_array_range,
                               int64_t &index_lower, int64_t &index_higher) {
  Log *log = GetLog(LLDBLog::DataFormatters);
  close_bracket_index = llvm::StringRef::npos;
  const size_t open_bracket_index = subpath.find('[');
  if (open_bracket_index == llvm::StringRef::npos) {
    LLDB_LOGF(log,
              "[ScanBracketedRange] no bracketed range, skipping entirely");
    return false;
  }

  close_bracket_index = subpath.find(']', open_bracket_index + 1);

  if (close_bracket_index == llvm::StringRef::npos) {
    LLDB_LOGF(log,
              "[ScanBracketedRange] no bracketed range, skipping entirely");
    return false;
  } else {
    var_name_final_if_array_range = subpath.data() + open_bracket_index;

    if (close_bracket_index - open_bracket_index == 1) {
      LLDB_LOGF(
          log,
          "[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
      index_lower = 0;
    } else {
      const size_t separator_index = subpath.find('-', open_bracket_index + 1);

      if (separator_index == llvm::StringRef::npos) {
        const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
        index_lower = ::strtoul(index_lower_cstr, nullptr, 0);
        index_higher = index_lower;
        LLDB_LOGF(log,
                  "[ScanBracketedRange] [%" PRId64
                  "] detected, high index is same",
                  index_lower);
      } else {
        const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
        const char *index_higher_cstr = subpath.data() + separator_index + 1;
        index_lower = ::strtoul(index_lower_cstr, nullptr, 0);
        index_higher = ::strtoul(index_higher_cstr, nullptr, 0);
        LLDB_LOGF(log,
                  "[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected",
                  index_lower, index_higher);
      }
      if (index_lower > index_higher && index_higher > 0) {
        LLDB_LOGF(log, "[ScanBracketedRange] swapping indices");
        const int64_t temp = index_lower;
        index_lower = index_higher;
        index_higher = temp;
      }
    }
  }
  return true;
}

static bool DumpFile(Stream &s, const FileSpec &file, FileKind file_kind) {
  switch (file_kind) {
  case FileKind::FileError:
    break;

  case FileKind::Basename:
    if (file.GetFilename()) {
      s << file.GetFilename();
      return true;
    }
    break;

  case FileKind::Dirname:
    if (file.GetDirectory()) {
      s << file.GetDirectory();
      return true;
    }
    break;

  case FileKind::Fullpath:
    if (file) {
      s << file;
      return true;
    }
    break;
  }
  return false;
}

static bool DumpRegister(Stream &s, StackFrame *frame, RegisterKind reg_kind,
                         uint32_t reg_num, Format format) {
  if (frame) {
    RegisterContext *reg_ctx = frame->GetRegisterContext().get();

    if (reg_ctx) {
      const uint32_t lldb_reg_num =
          reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
      if (lldb_reg_num != LLDB_INVALID_REGNUM) {
        const RegisterInfo *reg_info =
            reg_ctx->GetRegisterInfoAtIndex(lldb_reg_num);
        if (reg_info) {
          RegisterValue reg_value;
          if (reg_ctx->ReadRegister(reg_info, reg_value)) {
            DumpRegisterValue(reg_value, s, *reg_info, false, false, format);
            return true;
          }
        }
      }
    }
  }
  return false;
}

static ValueObjectSP ExpandIndexedExpression(ValueObject *valobj, size_t index,
                                             bool deref_pointer) {
  Log *log = GetLog(LLDBLog::DataFormatters);
  std::string name_to_deref = llvm::formatv("[{0}]", index);
  LLDB_LOG(log, "[ExpandIndexedExpression] name to deref: {0}", name_to_deref);
  ValueObject::GetValueForExpressionPathOptions options;
  ValueObject::ExpressionPathEndResultType final_value_type;
  ValueObject::ExpressionPathScanEndReason reason_to_stop;
  ValueObject::ExpressionPathAftermath what_next =
      (deref_pointer ? ValueObject::eExpressionPathAftermathDereference
                     : ValueObject::eExpressionPathAftermathNothing);
  ValueObjectSP item = valobj->GetValueForExpressionPath(
      name_to_deref, &reason_to_stop, &final_value_type, options, &what_next);
  if (!item) {
    LLDB_LOGF(log,
              "[ExpandIndexedExpression] ERROR: why stopping = %d,"
              " final_value_type %d",
              reason_to_stop, final_value_type);
  } else {
    LLDB_LOGF(log,
              "[ExpandIndexedExpression] ALL RIGHT: why stopping = %d,"
              " final_value_type %d",
              reason_to_stop, final_value_type);
  }
  return item;
}

static char ConvertValueObjectStyleToChar(
    ValueObject::ValueObjectRepresentationStyle style) {
  switch (style) {
  case ValueObject::eValueObjectRepresentationStyleLanguageSpecific:
    return '@';
  case ValueObject::eValueObjectRepresentationStyleValue:
    return 'V';
  case ValueObject::eValueObjectRepresentationStyleLocation:
    return 'L';
  case ValueObject::eValueObjectRepresentationStyleSummary:
    return 'S';
  case ValueObject::eValueObjectRepresentationStyleChildrenCount:
    return '#';
  case ValueObject::eValueObjectRepresentationStyleType:
    return 'T';
  case ValueObject::eValueObjectRepresentationStyleName:
    return 'N';
  case ValueObject::eValueObjectRepresentationStyleExpressionPath:
    return '>';
  }
  return '\0';
}

/// Options supported by format_provider<T> for integral arithmetic types.
/// See table in FormatProviders.h.
static llvm::Regex LLVMFormatPattern{"x[-+]?\\d*|n|d", llvm::Regex::IgnoreCase};

static bool DumpValueWithLLVMFormat(Stream &s, llvm::StringRef options,
                                    ValueObject &valobj) {
  std::string formatted;
  std::string llvm_format = ("{0:" + options + "}").str();

  auto type_info = valobj.GetTypeInfo();
  if ((type_info & eTypeIsInteger) && LLVMFormatPattern.match(options)) {
    if (type_info & eTypeIsSigned) {
      bool success = false;
      int64_t integer = valobj.GetValueAsSigned(0, &success);
      if (success)
        formatted = llvm::formatv(llvm_format.data(), integer);
    } else {
      bool success = false;
      uint64_t integer = valobj.GetValueAsUnsigned(0, &success);
      if (success)
        formatted = llvm::formatv(llvm_format.data(), integer);
    }
  }

  if (formatted.empty())
    return false;

  s.Write(formatted.data(), formatted.size());
  return true;
}

static bool DumpValue(Stream &s, const SymbolContext *sc,
                      const ExecutionContext *exe_ctx,
                      const FormatEntity::Entry &entry, ValueObject *valobj) {
  if (valobj == nullptr)
    return false;

  Log *log = GetLog(LLDBLog::DataFormatters);
  Format custom_format = eFormatInvalid;
  ValueObject::ValueObjectRepresentationStyle val_obj_display =
      entry.string.empty()
          ? ValueObject::eValueObjectRepresentationStyleValue
          : ValueObject::eValueObjectRepresentationStyleSummary;

  bool do_deref_pointer = entry.deref;
  bool is_script = false;
  switch (entry.type) {
  case FormatEntity::Entry::Type::ScriptVariable:
    is_script = true;
    break;

  case FormatEntity::Entry::Type::Variable:
    custom_format = entry.fmt;
    val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
    break;

  case FormatEntity::Entry::Type::ScriptVariableSynthetic:
    is_script = true;
    [[fallthrough]];
  case FormatEntity::Entry::Type::VariableSynthetic:
    custom_format = entry.fmt;
    val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
    if (!valobj->IsSynthetic()) {
      valobj = valobj->GetSyntheticValue().get();
      if (valobj == nullptr)
        return false;
    }
    break;

  default:
    return false;
  }

  ValueObject::ExpressionPathAftermath what_next =
      (do_deref_pointer ? ValueObject::eExpressionPathAftermathDereference
                        : ValueObject::eExpressionPathAftermathNothing);
  ValueObject::GetValueForExpressionPathOptions options;
  options.DontCheckDotVsArrowSyntax()
      .DoAllowBitfieldSyntax()
      .DoAllowFragileIVar()
      .SetSyntheticChildrenTraversal(
          ValueObject::GetValueForExpressionPathOptions::
              SyntheticChildrenTraversal::Both);
  ValueObject *target = nullptr;
  const char *var_name_final_if_array_range = nullptr;
  size_t close_bracket_index = llvm::StringRef::npos;
  int64_t index_lower = -1;
  int64_t index_higher = -1;
  bool is_array_range = false;
  bool was_plain_var = false;
  bool was_var_format = false;
  bool was_var_indexed = false;
  ValueObject::ExpressionPathScanEndReason reason_to_stop =
      ValueObject::eExpressionPathScanEndReasonEndOfString;
  ValueObject::ExpressionPathEndResultType final_value_type =
      ValueObject::eExpressionPathEndResultTypePlain;

  if (is_script) {
    return RunScriptFormatKeyword(s, sc, exe_ctx, valobj, entry.string.c_str());
  }

  auto split = llvm::StringRef(entry.string).split(':');
  auto subpath = split.first;
  auto llvm_format = split.second;

  // simplest case ${var}, just print valobj's value
  if (subpath.empty()) {
    if (entry.printf_format.empty() && entry.fmt == eFormatDefault &&
        entry.number == ValueObject::eValueObjectRepresentationStyleValue)
      was_plain_var = true;
    else
      was_var_format = true;
    target = valobj;
  } else // this is ${var.something} or multiple .something nested
  {
    if (subpath[0] == '[')
      was_var_indexed = true;
    ScanBracketedRange(subpath, close_bracket_index,
                       var_name_final_if_array_range, index_lower,
                       index_higher);

    Status error;

    LLDB_LOG(log, "[Debugger::FormatPrompt] symbol to expand: {0}", subpath);

    target =
        valobj
            ->GetValueForExpressionPath(subpath, &reason_to_stop,
                                        &final_value_type, options, &what_next)
            .get();

    if (!target) {
      LLDB_LOGF(log,
                "[Debugger::FormatPrompt] ERROR: why stopping = %d,"
                " final_value_type %d",
                reason_to_stop, final_value_type);
      return false;
    } else {
      LLDB_LOGF(log,
                "[Debugger::FormatPrompt] ALL RIGHT: why stopping = %d,"
                " final_value_type %d",
                reason_to_stop, final_value_type);
      target = target
                   ->GetQualifiedRepresentationIfAvailable(
                       target->GetDynamicValueType(), true)
                   .get();
    }
  }

  is_array_range =
      (final_value_type ==
           ValueObject::eExpressionPathEndResultTypeBoundedRange ||
       final_value_type ==
           ValueObject::eExpressionPathEndResultTypeUnboundedRange);

  do_deref_pointer =
      (what_next == ValueObject::eExpressionPathAftermathDereference);

  if (do_deref_pointer && !is_array_range) {
    // I have not deref-ed yet, let's do it
    // this happens when we are not going through
    // GetValueForVariableExpressionPath to get to the target ValueObject
    Status error;
    target = target->Dereference(error).get();
    if (error.Fail()) {
      LLDB_LOGF(log, "[Debugger::FormatPrompt] ERROR: %s\n",
                error.AsCString("unknown"));
      return false;
    }
    do_deref_pointer = false;
  }

  if (!target) {
    LLDB_LOGF(log, "[Debugger::FormatPrompt] could not calculate target for "
                   "prompt expression");
    return false;
  }

  // we do not want to use the summary for a bitfield of type T:n if we were
  // originally dealing with just a T - that would get us into an endless
  // recursion
  if (target->IsBitfield() && was_var_indexed) {
    // TODO: check for a (T:n)-specific summary - we should still obey that
    StreamString bitfield_name;
    bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(),
                         target->GetBitfieldBitSize());
    auto type_sp = std::make_shared<TypeNameSpecifierImpl>(
        bitfield_name.GetString(), lldb::eFormatterMatchExact);
    if (val_obj_display ==
            ValueObject::eValueObjectRepresentationStyleSummary &&
        !DataVisualization::GetSummaryForType(type_sp))
      val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
  }

  // TODO use flags for these
  const uint32_t type_info_flags =
      target->GetCompilerType().GetTypeInfo(nullptr);
  bool is_array = (type_info_flags & eTypeIsArray) != 0;
  bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
  bool is_aggregate = target->GetCompilerType().IsAggregateType();

  if ((is_array || is_pointer) && (!is_array_range) &&
      val_obj_display ==
          ValueObject::eValueObjectRepresentationStyleValue) // this should be
                                                             // wrong, but there
                                                             // are some
                                                             // exceptions
  {
    StreamString str_temp;
    LLDB_LOGF(log,
              "[Debugger::FormatPrompt] I am into array || pointer && !range");

    if (target->HasSpecialPrintableRepresentation(val_obj_display,
                                                  custom_format)) {
      // try to use the special cases
      bool success = target->DumpPrintableRepresentation(
          str_temp, val_obj_display, custom_format);
      LLDB_LOGF(log, "[Debugger::FormatPrompt] special cases did%s match",
                success ? "" : "n't");

      // should not happen
      if (success)
        s << str_temp.GetString();
      return true;
    } else {
      if (was_plain_var) // if ${var}
      {
        s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
      } else if (is_pointer) // if pointer, value is the address stored
      {
        target->DumpPrintableRepresentation(
            s, val_obj_display, custom_format,
            ValueObject::PrintableRepresentationSpecialCases::eDisable);
      }
      return true;
    }
  }

  // if directly trying to print ${var}, and this is an aggregate, display a
  // nice type @ location message
  if (is_aggregate && was_plain_var) {
    s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
    return true;
  }

  // if directly trying to print ${var%V}, and this is an aggregate, do not let
  // the user do it
  if (is_aggregate &&
      ((was_var_format &&
        val_obj_display ==
            ValueObject::eValueObjectRepresentationStyleValue))) {
    s << "<invalid use of aggregate type>";
    return true;
  }

  if (!is_array_range) {
    if (!llvm_format.empty()) {
      if (DumpValueWithLLVMFormat(s, llvm_format, *target)) {
        LLDB_LOGF(log, "dumping using llvm format");
        return true;
      } else {
        LLDB_LOG(
            log,
            "empty output using llvm format '{0}' - with type info flags {1}",
            entry.printf_format, target->GetTypeInfo());
      }
    }
    LLDB_LOGF(log, "dumping ordinary printable output");
    return target->DumpPrintableRepresentation(s, val_obj_display,
                                               custom_format);
  } else {
    LLDB_LOGF(log,
              "[Debugger::FormatPrompt] checking if I can handle as array");
    if (!is_array && !is_pointer)
      return false;
    LLDB_LOGF(log, "[Debugger::FormatPrompt] handle as array");
    StreamString special_directions_stream;
    llvm::StringRef special_directions;
    if (close_bracket_index != llvm::StringRef::npos &&
        subpath.size() > close_bracket_index) {
      ConstString additional_data(subpath.drop_front(close_bracket_index + 1));
      special_directions_stream.Printf("${%svar%s", do_deref_pointer ? "*" : "",
                                       additional_data.GetCString());

      if (entry.fmt != eFormatDefault) {
        const char format_char =
            FormatManager::GetFormatAsFormatChar(entry.fmt);
        if (format_char != '\0')
          special_directions_stream.Printf("%%%c", format_char);
        else {
          const char *format_cstr =
              FormatManager::GetFormatAsCString(entry.fmt);
          special_directions_stream.Printf("%%%s", format_cstr);
        }
      } else if (entry.number != 0) {
        const char style_char = ConvertValueObjectStyleToChar(
            (ValueObject::ValueObjectRepresentationStyle)entry.number);
        if (style_char)
          special_directions_stream.Printf("%%%c", style_char);
      }
      special_directions_stream.PutChar('}');
      special_directions =
          llvm::StringRef(special_directions_stream.GetString());
    }

    // let us display items index_lower thru index_higher of this array
    s.PutChar('[');

    if (index_higher < 0)
      index_higher = valobj->GetNumChildrenIgnoringErrors() - 1;

    uint32_t max_num_children =
        target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();

    bool success = true;
    for (int64_t index = index_lower; index <= index_higher; ++index) {
      ValueObject *item = ExpandIndexedExpression(target, index, false).get();

      if (!item) {
        LLDB_LOGF(log,
                  "[Debugger::FormatPrompt] ERROR in getting child item at "
                  "index %" PRId64,
                  index);
      } else {
        LLDB_LOGF(
            log,
            "[Debugger::FormatPrompt] special_directions for child item: %s",
            special_directions.data() ? special_directions.data() : "");
      }

      if (special_directions.empty()) {
        success &= item->DumpPrintableRepresentation(s, val_obj_display,
                                                     custom_format);
      } else {
        success &= FormatEntity::FormatStringRef(
            special_directions, s, sc, exe_ctx, nullptr, item, false, false);
      }

      if (--max_num_children == 0) {
        s.PutCString(", ...");
        break;
      }

      if (index < index_higher)
        s.PutChar(',');
    }
    s.PutChar(']');
    return success;
  }
}

static bool DumpRegister(Stream &s, StackFrame *frame, const char *reg_name,
                         Format format) {
  if (frame) {
    RegisterContext *reg_ctx = frame->GetRegisterContext().get();

    if (reg_ctx) {
      const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
      if (reg_info) {
        RegisterValue reg_value;
        if (reg_ctx->ReadRegister(reg_info, reg_value)) {
          DumpRegisterValue(reg_value, s, *reg_info, false, false, format);
          return true;
        }
      }
    }
  }
  return false;
}

static bool FormatThreadExtendedInfoRecurse(
    const FormatEntity::Entry &entry,
    const StructuredData::ObjectSP &thread_info_dictionary,
    const SymbolContext *sc, const ExecutionContext *exe_ctx, Stream &s) {
  llvm::StringRef path(entry.string);

  StructuredData::ObjectSP value =
      thread_info_dictionary->GetObjectForDotSeparatedPath(path);

  if (value) {
    if (value->GetType() == eStructuredDataTypeInteger) {
      const char *token_format = "0x%4.4" PRIx64;
      if (!entry.printf_format.empty())
        token_format = entry.printf_format.c_str();
      s.Printf(token_format, value->GetUnsignedIntegerValue());
      return true;
    } else if (value->GetType() == eStructuredDataTypeFloat) {
      s.Printf("%f", value->GetAsFloat()->GetValue());
      return true;
    } else if (value->GetType() == eStructuredDataTypeString) {
      s.Format("{0}", value->GetAsString()->GetValue());
      return true;
    } else if (value->GetType() == eStructuredDataTypeArray) {
      if (value->GetAsArray()->GetSize() > 0) {
        s.Printf("%zu", value->GetAsArray()->GetSize());
        return true;
      }
    } else if (value->GetType() == eStructuredDataTypeDictionary) {
      s.Printf("%zu",
               value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
      return true;
    }
  }

  return false;
}

static inline bool IsToken(const char *var_name_begin, const char *var) {
  return (::strncmp(var_name_begin, var, strlen(var)) == 0);
}

/// Parses the basename out of a demangled function name
/// that may include function arguments. Supports
/// template functions.
///
/// Returns pointers to the opening and closing parenthesis of
/// `full_name`. Can return nullptr for either parenthesis if
/// none is exists.
static std::pair<char const *, char const *>
ParseBaseName(char const *full_name) {
  const char *open_paren = strchr(full_name, '(');
  const char *close_paren = nullptr;
  const char *generic = strchr(full_name, '<');
  // if before the arguments list begins there is a template sign
  // then scan to the end of the generic args before you try to find
  // the arguments list
  if (generic && open_paren && generic < open_paren) {
    int generic_depth = 1;
    ++generic;
    for (; *generic && generic_depth > 0; generic++) {
      if (*generic == '<')
        generic_depth++;
      if (*generic == '>')
        generic_depth--;
    }
    if (*generic)
      open_paren = strchr(generic, '(');
    else
      open_paren = nullptr;
  }

  if (open_paren) {
    if (IsToken(open_paren, "(anonymous namespace)")) {
      open_paren = strchr(open_paren + strlen("(anonymous namespace)"), '(');
      if (open_paren)
        close_paren = strchr(open_paren, ')');
    } else
      close_paren = strchr(open_paren, ')');
  }

  return {open_paren, close_paren};
}

/// Writes out the function name in 'full_name' to 'out_stream'
/// but replaces each argument type with the variable name
/// and the corresponding pretty-printed value
static void PrettyPrintFunctionNameWithArgs(Stream &out_stream,
                                            char const *full_name,
                                            ExecutionContextScope *exe_scope,
                                            VariableList const &args) {
  auto [open_paren, close_paren] = ParseBaseName(full_name);
  if (open_paren)
    out_stream.Write(full_name, open_paren - full_name + 1);
  else {
    out_stream.PutCString(full_name);
    out_stream.PutChar('(');
  }

  FormatEntity::PrettyPrintFunctionArguments(out_stream, args, exe_scope);

  if (close_paren)
    out_stream.PutCString(close_paren);
  else
    out_stream.PutChar(')');
}

static VariableListSP GetFunctionVariableList(const SymbolContext &sc) {
  assert(sc.function);

  if (sc.block)
    if (Block *inline_block = sc.block->GetContainingInlinedBlock())
      return inline_block->GetBlockVariableList(true);

  return sc.function->GetBlock(true).GetBlockVariableList(true);
}

static bool PrintFunctionNameWithArgs(Stream &s,
                                      const ExecutionContext *exe_ctx,
                                      const SymbolContext &sc) {
  assert(sc.function);

  ExecutionContextScope *exe_scope =
      exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;

  const char *cstr = sc.GetPossiblyInlinedFunctionName()
                         .GetName(Mangled::ePreferDemangled)
                         .AsCString();
  if (!cstr)
    return false;

  VariableList args;
  if (auto variable_list_sp = GetFunctionVariableList(sc))
    variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
                                               args);

  if (args.GetSize() > 0) {
    PrettyPrintFunctionNameWithArgs(s, cstr, exe_scope, args);
  } else {
    s.PutCString(cstr);
  }

  return true;
}

static bool HandleFunctionNameWithArgs(Stream &s,
                                       const ExecutionContext *exe_ctx,
                                       const SymbolContext &sc) {
  Language *language_plugin = nullptr;
  bool language_plugin_handled = false;
  StreamString ss;
  if (sc.function)
    language_plugin = Language::FindPlugin(sc.function->GetLanguage());
  else if (sc.symbol)
    language_plugin = Language::FindPlugin(sc.symbol->GetLanguage());

  if (language_plugin)
    language_plugin_handled = language_plugin->GetFunctionDisplayName(
        sc, exe_ctx, Language::FunctionNameRepresentation::eNameWithArgs, ss);

  if (language_plugin_handled) {
    s << ss.GetString();
    return true;
  }

  if (sc.function)
    return PrintFunctionNameWithArgs(s, exe_ctx, sc);

  if (!sc.symbol)
    return false;

  const char *cstr = sc.symbol->GetName().AsCString(nullptr);
  if (!cstr)
    return false;

  s.PutCString(cstr);

  return true;
}

static bool FormatFunctionNameForLanguage(Stream &s,
                                          const ExecutionContext *exe_ctx,
                                          const SymbolContext *sc) {
  assert(sc);

  Language *language_plugin = nullptr;
  if (sc->function)
    language_plugin = Language::FindPlugin(sc->function->GetLanguage());
  else if (sc->symbol)
    language_plugin = Language::FindPlugin(sc->symbol->GetLanguage());

  if (!language_plugin)
    return false;

  FormatEntity::Entry format = language_plugin->GetFunctionNameFormat();

  // Bail on invalid or empty format.
  if (!format || format == FormatEntity::Entry(Entry::Type::Root))
    return false;

  StreamString name_stream;
  const bool success =
      FormatEntity::Format(format, name_stream, sc, exe_ctx, /*addr=*/nullptr,
                           /*valobj=*/nullptr, /*function_changed=*/false,
                           /*initial_function=*/false);
  if (success)
    s << name_stream.GetString();

  return success;
}

bool FormatEntity::FormatStringRef(const llvm::StringRef &format_str, Stream &s,
                                   const SymbolContext *sc,
                                   const ExecutionContext *exe_ctx,
                                   const Address *addr, ValueObject *valobj,
                                   bool function_changed,
                                   bool initial_function) {
  if (!format_str.empty()) {
    FormatEntity::Entry root;
    Status error = FormatEntity::Parse(format_str, root);
    if (error.Success()) {
      return FormatEntity::Format(root, s, sc, exe_ctx, addr, valobj,
                                  function_changed, initial_function);
    }
  }
  return false;
}

bool FormatEntity::Format(const Entry &entry, Stream &s,
                          const SymbolContext *sc,
                          const ExecutionContext *exe_ctx, const Address *addr,
                          ValueObject *valobj, bool function_changed,
                          bool initial_function) {
  switch (entry.type) {
  case Entry::Type::Invalid:
  case Entry::Type::ParentNumber: // Only used for
                                  // FormatEntity::Entry::Definition encoding
  case Entry::Type::ParentString: // Only used for
                                  // FormatEntity::Entry::Definition encoding
    return false;
  case Entry::Type::EscapeCode:
    if (Target *target = Target::GetTargetFromContexts(exe_ctx, sc)) {
      Debugger &debugger = target->GetDebugger();
      if (debugger.GetUseColor()) {
        s.PutCString(entry.string);
      }
    }
    // Always return true, so colors being disabled is transparent.
    return true;

  case Entry::Type::Root:
    for (const auto &child : entry.children_stack[0]) {
      if (!Format(child, s, sc, exe_ctx, addr, valobj, function_changed,
                  initial_function)) {
        return false; // If any item of root fails, then the formatting fails
      }
    }
    return true; // Only return true if all items succeeded

  case Entry::Type::String:
    s.PutCString(entry.string);
    return true;

  case Entry::Type::Scope: {
    StreamString scope_stream;
    auto format_children = [&](const std::vector<Entry> &children) {
      scope_stream.Clear();
      for (const auto &child : children) {
        if (!Format(child, scope_stream, sc, exe_ctx, addr, valobj,
                    function_changed, initial_function))
          return false;
      }
      return true;
    };

    for (auto &children : entry.children_stack) {
      if (format_children(children)) {
        s.Write(scope_stream.GetString().data(),
                scope_stream.GetString().size());
        return true;
      }
    }

    return true; // Scopes always successfully print themselves
  }

  case Entry::Type::Variable:
  case Entry::Type::VariableSynthetic:
  case Entry::Type::ScriptVariable:
  case Entry::Type::ScriptVariableSynthetic:
    return DumpValue(s, sc, exe_ctx, entry, valobj);

  case Entry::Type::AddressFile:
  case Entry::Type::AddressLoad:
  case Entry::Type::AddressLoadOrFile:
    return (
        addr != nullptr && addr->IsValid() &&
        DumpAddressAndContent(s, sc, exe_ctx, *addr,
                              entry.type == Entry::Type::AddressLoadOrFile));

  case Entry::Type::ProcessID:
    if (exe_ctx) {
      Process *process = exe_ctx->GetProcessPtr();
      if (process) {
        const char *format = "%" PRIu64;
        if (!entry.printf_format.empty())
          format = entry.printf_format.c_str();
        s.Printf(format, process->GetID());
        return true;
      }
    }
    return false;

  case Entry::Type::ProcessFile:
    if (exe_ctx) {
      Process *process = exe_ctx->GetProcessPtr();
      if (process) {
        Module *exe_module = process->GetTarget().GetExecutableModulePointer();
        if (exe_module) {
          if (DumpFile(s, exe_module->GetFileSpec(), (FileKind)entry.number))
            return true;
        }
      }
    }
    return false;

  case Entry::Type::ScriptProcess:
    if (exe_ctx) {
      Process *process = exe_ctx->GetProcessPtr();
      if (process)
        return RunScriptFormatKeyword(s, sc, exe_ctx, process,
                                      entry.string.c_str());
    }
    return false;

  case Entry::Type::ThreadID:
    if (exe_ctx) {
      Thread *thread = exe_ctx->GetThreadPtr();
      if (thread) {
        const char *format = "0x%4.4" PRIx64;
        if (!entry.printf_format.empty()) {
          // Watch for the special "tid" format...
          if (entry.printf_format == "tid") {
            // TODO(zturner): Rather than hardcoding this to be platform
            // specific, it should be controlled by a setting and the default
            // value of the setting can be different depending on the platform.
            Target &target = thread->GetProcess()->GetTarget();
            ArchSpec arch(target.GetArchitecture());
            llvm::Triple::OSType ostype = arch.IsValid()
                                              ? arch.GetTriple().getOS()
                                              : llvm::Triple::UnknownOS;
            if (ostype == llvm::Triple::FreeBSD ||
                ostype == llvm::Triple::Linux ||
                ostype == llvm::Triple::NetBSD ||
                ostype == llvm::Triple::OpenBSD) {
              format = "%" PRIu64;
            }
          } else {
            format = entry.printf_format.c_str();
          }
        }
        s.Printf(format, thread->GetID());
        return true;
      }
    }
    return false;

  case Entry::Type::ThreadProtocolID:
    if (exe_ctx) {
      Thread *thread = exe_ctx->GetThreadPtr();
      if (thread) {
        const char *format = "0x%4.4" PRIx64;
        if (!entry.printf_format.empty())
          format = entry.printf_format.c_str();
        s.Printf(format, thread->GetProtocolID());
        return true;
      }
    }
    return false;

  case Entry::Type::ThreadIndexID:
    if (exe_ctx) {
      Thread *thread = exe_ctx->GetThreadPtr();
      if (thread) {
        const char *format = "%" PRIu32;
        if (!entry.printf_format.empty())
          format = entry.printf_format.c_str();
        s.Printf(format, thread->GetIndexID());
        return true;
      }
    }
    return false;

  case Entry::Type::ThreadName:
    if (exe_ctx) {
      Thread *thread = exe_ctx->GetThreadPtr();
      if (thread) {
        const char *cstr = thread->GetName();
        if (cstr && cstr[0]) {
          s.PutCString(cstr);
          return true;
        }
      }
    }
    return false;

  case Entry::Type::ThreadQueue:
    if (exe_ctx) {
      Thread *thread = exe_ctx->GetThreadPtr();
      if (thread) {
        const char *cstr = thread->GetQueueName();
        if (cstr && cstr[0]) {
          s.PutCString(cstr);
          return true;
        }
      }
    }
    return false;

  case Entry::Type::ThreadStopReason:
    if (exe_ctx) {
      if (Thread *thread = exe_ctx->GetThreadPtr()) {
        std::string stop_description = thread->GetStopDescription();
        if (!stop_description.empty()) {
          s.PutCString(stop_description);
          return true;
        }
      }
    }
    return false;

  case Entry::Type::ThreadStopReasonRaw:
    if (exe_ctx) {
      if (Thread *thread = exe_ctx->GetThreadPtr()) {
        std::string stop_description = thread->GetStopDescriptionRaw();
        if (!stop_description.empty()) {
          s.PutCString(stop_description);
          return true;
        }
      }
    }
    return false;

  case Entry::Type::ThreadReturnValue:
    if (exe_ctx) {
      Thread *thread = exe_ctx->GetThreadPtr();
      if (thread) {
        StopInfoSP stop_info_sp = thread->GetStopInfo();
        if (stop_info_sp && stop_info_sp->IsValid()) {
          ValueObjectSP return_valobj_sp =
              StopInfo::GetReturnValueObject(stop_info_sp);
          if (return_valobj_sp) {
            if (llvm::Error error = return_valobj_sp->Dump(s)) {
              s << "error: " << toString(std::move(error));
              return false;
            }
            return true;
          }
        }
      }
    }
    return false;

  case Entry::Type::ThreadCompletedExpression:
    if (exe_ctx) {
      Thread *thread = exe_ctx->GetThreadPtr();
      if (thread) {
        StopInfoSP stop_info_sp = thread->GetStopInfo();
        if (stop_info_sp && stop_info_sp->IsValid()) {
          ExpressionVariableSP expression_var_sp =
              StopInfo::GetExpressionVariable(stop_info_sp);
          if (expression_var_sp && expression_var_sp->GetValueObject()) {
            if (llvm::Error error =
                    expression_var_sp->GetValueObject()->Dump(s)) {
              s << "error: " << toString(std::move(error));
              return false;
            }
            return true;
          }
        }
      }
    }
    return false;

  case Entry::Type::ScriptThread:
    if (exe_ctx) {
      Thread *thread = exe_ctx->GetThreadPtr();
      if (thread)
        return RunScriptFormatKeyword(s, sc, exe_ctx, thread,
                                      entry.string.c_str());
    }
    return false;

  case Entry::Type::ThreadInfo:
    if (exe_ctx) {
      Thread *thread = exe_ctx->GetThreadPtr();
      if (thread) {
        StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
        if (object_sp &&
            object_sp->GetType() == eStructuredDataTypeDictionary) {
          if (FormatThreadExtendedInfoRecurse(entry, object_sp, sc, exe_ctx, s))
            return true;
        }
      }
    }
    return false;

  case Entry::Type::TargetArch:
    if (exe_ctx) {
      Target *target = exe_ctx->GetTargetPtr();
      if (target) {
        const ArchSpec &arch = target->GetArchitecture();
        if (arch.IsValid()) {
          s.PutCString(arch.GetArchitectureName());
          return true;
        }
      }
    }
    return false;

  case Entry::Type::TargetFile:
    if (exe_ctx) {
      if (Target *target = exe_ctx->GetTargetPtr()) {
        if (Module *exe_module = target->GetExecutableModulePointer()) {
          if (DumpFile(s, exe_module->GetFileSpec(), (FileKind)entry.number))
            return true;
        }
      }
    }
    return false;

  case Entry::Type::ScriptTarget:
    if (exe_ctx) {
      Target *target = exe_ctx->GetTargetPtr();
      if (target)
        return RunScriptFormatKeyword(s, sc, exe_ctx, target,
                                      entry.string.c_str());
    }
    return false;

  case Entry::Type::ModuleFile:
    if (sc) {
      Module *module = sc->module_sp.get();
      if (module) {
        if (DumpFile(s, module->GetFileSpec(), (FileKind)entry.number))
          return true;
      }
    }
    return false;

  case Entry::Type::File:
    if (sc) {
      CompileUnit *cu = sc->comp_unit;
      if (cu) {
        if (DumpFile(s, cu->GetPrimaryFile(), (FileKind)entry.number))
          return true;
      }
    }
    return false;

  case Entry::Type::Lang:
    if (sc) {
      CompileUnit *cu = sc->comp_unit;
      if (cu) {
        const char *lang_name =
            Language::GetNameForLanguageType(cu->GetLanguage());
        if (lang_name) {
          s.PutCString(lang_name);
          return true;
        }
      }
    }
    return false;

  case Entry::Type::FrameIndex:
    if (exe_ctx) {
      StackFrame *frame = exe_ctx->GetFramePtr();
      if (frame) {
        const char *format = "%" PRIu32;
        if (!entry.printf_format.empty())
          format = entry.printf_format.c_str();
        s.Printf(format, frame->GetFrameIndex());
        return true;
      }
    }
    return false;

  case Entry::Type::FrameRegisterPC:
    if (exe_ctx) {
      StackFrame *frame = exe_ctx->GetFramePtr();
      if (frame) {
        const Address &pc_addr = frame->GetFrameCodeAddress();
        if (pc_addr.IsValid())
          if (DumpAddressAndContent(s, sc, exe_ctx, pc_addr, false))
            return true;
      }
    }
    return false;

  case Entry::Type::FrameRegisterSP:
    if (exe_ctx) {
      StackFrame *frame = exe_ctx->GetFramePtr();
      if (frame) {
        if (DumpRegister(s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP,
                         (lldb::Format)entry.number))
          return true;
      }
    }
    return false;

  case Entry::Type::FrameRegisterFP:
    if (exe_ctx) {
      StackFrame *frame = exe_ctx->GetFramePtr();
      if (frame) {
        if (DumpRegister(s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP,
                         (lldb::Format)entry.number))
          return true;
      }
    }
    return false;

  case Entry::Type::FrameRegisterFlags:
    if (exe_ctx) {
      StackFrame *frame = exe_ctx->GetFramePtr();
      if (frame) {
        if (DumpRegister(s, frame, eRegisterKindGeneric,
                         LLDB_REGNUM_GENERIC_FLAGS, (lldb::Format)entry.number))
          return true;
      }
    }
    return false;

  case Entry::Type::FrameNoDebug:
    if (exe_ctx) {
      StackFrame *frame = exe_ctx->GetFramePtr();
      if (frame) {
        return !frame->HasDebugInformation();
      }
    }
    return true;

  case Entry::Type::FrameRegisterByName:
    if (exe_ctx) {
      StackFrame *frame = exe_ctx->GetFramePtr();
      if (frame) {
        if (DumpRegister(s, frame, entry.string.c_str(),
                         (lldb::Format)entry.number))
          return true;
      }
    }
    return false;

  case Entry::Type::FrameIsArtificial: {
    if (exe_ctx)
      if (StackFrame *frame = exe_ctx->GetFramePtr())
        return frame->IsArtificial();
    return false;
  }

  case Entry::Type::FrameKind: {
    if (exe_ctx)
      if (StackFrame *frame = exe_ctx->GetFramePtr()) {
        if (frame->IsSynthetic())
          s.PutCString(" [synthetic]");
        else if (frame->IsHistorical())
          s.PutCString(" [history]");
        return true;
      }
    return false;
  }

  case Entry::Type::FrameBorrowedInfo: {
    if (exe_ctx)
      if (StackFrame *frame = exe_ctx->GetFramePtr()) {
        if (BorrowedStackFrame *borrowed_frame =
                llvm::dyn_cast<BorrowedStackFrame>(frame)) {
          if (lldb::StackFrameSP borrowed_from_sp =
                  borrowed_frame->GetBorrowedFrame()) {
            s.Printf(" [borrowed from frame #%u]",
                     borrowed_from_sp->GetFrameIndex());
            return true;
          }
        }
      }
    return false;
  }

  case Entry::Type::ScriptFrame:
    if (exe_ctx) {
      StackFrame *frame = exe_ctx->GetFramePtr();
      if (frame)
        return RunScriptFormatKeyword(s, sc, exe_ctx, frame,
                                      entry.string.c_str());
    }
    return false;

  case Entry::Type::FunctionID:
    if (sc) {
      if (sc->function) {
        s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
        return true;
      } else if (sc->symbol) {
        s.Printf("symbol[%u]", sc->symbol->GetID());
        return true;
      }
    }
    return false;

  case Entry::Type::FunctionDidChange:
    return function_changed;

  case Entry::Type::FunctionInitialFunction:
    return initial_function;

  case Entry::Type::FunctionName: {
    if (sc) {
      Language *language_plugin = nullptr;
      bool language_plugin_handled = false;
      StreamString ss;

      if (sc->function)
        language_plugin = Language::FindPlugin(sc->function->GetLanguage());
      else if (sc->symbol)
        language_plugin = Language::FindPlugin(sc->symbol->GetLanguage());

      if (language_plugin)
        language_plugin_handled = language_plugin->GetFunctionDisplayName(
            *sc, exe_ctx, Language::FunctionNameRepresentation::eName, ss);

      if (language_plugin_handled) {
        s << ss.GetString();
        return true;
      }

      const char *name = sc->GetPossiblyInlinedFunctionName()
                             .GetName(Mangled::NamePreference::ePreferDemangled)
                             .AsCString();
      if (name) {
        s.PutCString(name);
        return true;
      }
    }

    // Fallback to frame methods if available.
    if (exe_ctx) {
      StackFrame *frame = exe_ctx->GetFramePtr();
      if (frame) {
        const char *name = frame->GetFunctionName();
        if (name) {
          s.PutCString(name);
          return true;
        }
      }
    }
    return false;
  }

  case Entry::Type::FunctionNameNoArgs: {
    if (sc) {
      Language *language_plugin = nullptr;
      bool language_plugin_handled = false;
      StreamString ss;
      if (sc->function)
        language_plugin = Language::FindPlugin(sc->function->GetLanguage());
      else if (sc->symbol)
        language_plugin = Language::FindPlugin(sc->symbol->GetLanguage());

      if (language_plugin)
        language_plugin_handled = language_plugin->GetFunctionDisplayName(
            *sc, exe_ctx, Language::FunctionNameRepresentation::eNameWithNoArgs,
            ss);

      if (language_plugin_handled) {
        s << ss.GetString();
        return true;
      }

      const char *name =
          sc->GetPossiblyInlinedFunctionName()
              .GetName(
                  Mangled::NamePreference::ePreferDemangledWithoutArguments)
              .AsCString();
      if (name) {
        s.PutCString(name);
        return true;
      }
    }

    // Fallback to frame methods if available.
    if (exe_ctx) {
      StackFrame *frame = exe_ctx->GetFramePtr();
      if (frame) {
        const char *name = frame->GetFunctionName();
        if (name) {
          s.PutCString(name);
          return true;
        }
      }
    }
    return false;
  }

  case Entry::Type::FunctionPrefix:
  case Entry::Type::FunctionScope:
  case Entry::Type::FunctionBasename:
  case Entry::Type::FunctionNameQualifiers:
  case Entry::Type::FunctionTemplateArguments:
  case Entry::Type::FunctionFormattedArguments:
  case Entry::Type::FunctionReturnRight:
  case Entry::Type::FunctionReturnLeft:
  case Entry::Type::FunctionSuffix:
  case Entry::Type::FunctionQualifiers: {
    Language *language_plugin = nullptr;
    if (sc->function)
      language_plugin = Language::FindPlugin(sc->function->GetLanguage());
    else if (sc->symbol)
      language_plugin = Language::FindPlugin(sc->symbol->GetLanguage());

    if (!language_plugin)
      return false;

    return language_plugin->HandleFrameFormatVariable(*sc, exe_ctx, entry.type,
                                                      s);
  }

  case Entry::Type::FunctionNameWithArgs: {
    if (sc) {
      if (FormatFunctionNameForLanguage(s, exe_ctx, sc))
        return true;

      if (HandleFunctionNameWithArgs(s, exe_ctx, *sc))
        return true;
    }

    // Fallback to frame methods if available.
    if (exe_ctx) {
      StackFrame *frame = exe_ctx->GetFramePtr();
      if (frame) {
        const char *name = frame->GetDisplayFunctionName();
        if (name) {
          s.PutCString(name);
          return true;
        }
      }
    }
    return false;
  }
  case Entry::Type::FunctionMangledName: {
    if (!sc)
      return false;

    const char *name = sc->GetPossiblyInlinedFunctionName()
                           .GetName(Mangled::NamePreference::ePreferMangled)
                           .AsCString();
    if (!name)
      return false;

    s.PutCString(name);

    return true;
  }
  case Entry::Type::FunctionAddrOffset:
    if (addr) {
      if (DumpAddressOffsetFromFunction(s, sc, exe_ctx, *addr, false, false,
                                        false))
        return true;
    }
    return false;

  case Entry::Type::FunctionAddrOffsetConcrete:
    if (addr) {
      if (DumpAddressOffsetFromFunction(s, sc, exe_ctx, *addr, true, true,
                                        true))
        return true;
    }
    return false;

  case Entry::Type::FunctionLineOffset:
    if (sc)
      return (DumpAddressOffsetFromFunction(
          s, sc, exe_ctx, sc->line_entry.range.GetBaseAddress(), false, false,
          false));
    return false;

  case Entry::Type::FunctionPCOffset:
    if (exe_ctx) {
      StackFrame *frame = exe_ctx->GetFramePtr();
      if (frame)
        if (DumpAddressOffsetFromFunction(s, sc, exe_ctx,
                                          frame->GetFrameCodeAddress(), false,
                                          false, false))
          return true;
    }
    return false;

  case Entry::Type::FunctionChanged:
    return function_changed;

  case Entry::Type::FunctionIsOptimized: {
    bool is_optimized = false;
    if (sc && sc->function && sc->function->GetIsOptimized()) {
      is_optimized = true;
    }
    return is_optimized;
  }

  case Entry::Type::FunctionIsInlined: {
    return sc && sc->block && sc->block->GetInlinedFunctionInfo();
  }

  case Entry::Type::FunctionInitial:
    return initial_function;

  case Entry::Type::LineEntryFile:
    if (sc && sc->line_entry.IsValid()) {
      if (DumpFile(s, sc->line_entry.GetFile(), (FileKind)entry.number))
        return true;
    }
    return false;

  case Entry::Type::LineEntryLineNumber:
    if (sc && sc->line_entry.IsValid()) {
      const char *format = "%" PRIu32;
      if (!entry.printf_format.empty())
        format = entry.printf_format.c_str();
      s.Printf(format, sc->line_entry.line);
      return true;
    }
    return false;

  case Entry::Type::LineEntryColumn:
    if (sc && sc->line_entry.IsValid() && sc->line_entry.column) {
      const char *format = "%" PRIu32;
      if (!entry.printf_format.empty())
        format = entry.printf_format.c_str();
      s.Printf(format, sc->line_entry.column);
      return true;
    }
    return false;

  case Entry::Type::LineEntryStartAddress:
  case Entry::Type::LineEntryEndAddress:
    if (sc && sc->line_entry.range.GetBaseAddress().IsValid()) {
      Address addr = sc->line_entry.range.GetBaseAddress();

      if (entry.type == Entry::Type::LineEntryEndAddress)
        addr.Slide(sc->line_entry.range.GetByteSize());
      if (DumpAddressAndContent(s, sc, exe_ctx, addr, false))
        return true;
    }
    return false;

  case Entry::Type::CurrentPCArrow:
    if (addr && exe_ctx && exe_ctx->GetFramePtr()) {
      RegisterContextSP reg_ctx =
          exe_ctx->GetFramePtr()->GetRegisterContextSP();
      if (reg_ctx) {
        addr_t pc_loadaddr = reg_ctx->GetPC();
        if (pc_loadaddr != LLDB_INVALID_ADDRESS) {
          Address pc;
          pc.SetLoadAddress(pc_loadaddr, exe_ctx->GetTargetPtr());
          if (pc == *addr) {
            s.Printf("-> ");
            return true;
          }
        }
      }
      s.Printf("   ");
      return true;
    }
    return false;

  case Entry::Type::ProgressCount:
    if (Target *target = Target::GetTargetFromContexts(exe_ctx, sc)) {
      if (auto progress = target->GetDebugger().GetCurrentProgressReport()) {
        if (progress->total != UINT64_MAX) {
          s.Format("[{0:N}/{1:N}]", progress->completed, progress->total);
          return true;
        }
      }
    }
    return false;

  case Entry::Type::ProgressMessage:
    if (Target *target = Target::GetTargetFromContexts(exe_ctx, sc)) {
      if (auto progress = target->GetDebugger().GetCurrentProgressReport()) {
        s.PutCString(progress->message);
        return true;
      }
    }
    return false;

  case Entry::Type::Separator:
    if (Target *target = Target::GetTargetFromContexts(exe_ctx, sc)) {
      s << target->GetDebugger().GetSeparator();
      return true;
    }
    return false;
  }

  return false;
}

static bool DumpCommaSeparatedChildEntryNames(Stream &s,
                                              const Definition *parent) {
  if (parent->children) {
    const size_t n = parent->num_children;
    for (size_t i = 0; i < n; ++i) {
      if (i > 0)
        s.PutCString(", ");
      s.Printf("\"%s\"", parent->children[i].name);
    }
    return true;
  }
  return false;
}

static Status ParseEntry(const llvm::StringRef &format_str,
                         const Definition *parent, FormatEntity::Entry &entry) {
  Status error;

  const size_t sep_pos = format_str.find_first_of(".[:");
  const char sep_char =
      (sep_pos == llvm::StringRef::npos) ? '\0' : format_str[sep_pos];
  llvm::StringRef key = format_str.substr(0, sep_pos);

  const size_t n = parent->num_children;
  for (size_t i = 0; i < n; ++i) {
    const Definition *entry_def = parent->children + i;
    if (key == entry_def->name || entry_def->name[0] == '*') {
      llvm::StringRef value;
      if (sep_char)
        value =
            format_str.substr(sep_pos + (entry_def->keep_separator ? 0 : 1));
      switch (entry_def->type) {
      case FormatEntity::Entry::Type::ParentString:
        entry.string = format_str.str();
        return error; // Success

      case FormatEntity::Entry::Type::ParentNumber:
        entry.number = entry_def->data;
        return error; // Success

      case FormatEntity::Entry::Type::EscapeCode:
        entry.type = entry_def->type;
        entry.string = entry_def->string;
        return error; // Success

      default:
        entry.type = entry_def->type;
        break;
      }

      if (value.empty()) {
        if (entry_def->type == FormatEntity::Entry::Type::Invalid) {
          if (entry_def->children) {
            StreamString error_strm;
            error_strm.Printf("'%s' can't be specified on its own, you must "
                              "access one of its children: ",
                              entry_def->name);
            DumpCommaSeparatedChildEntryNames(error_strm, entry_def);
            error =
                Status::FromErrorStringWithFormat("%s", error_strm.GetData());
          } else if (sep_char == ':') {
            // Any value whose separator is a with a ':' means this value has a
            // string argument that needs to be stored in the entry (like
            // "${script.var:}"). In this case the string value is the empty
            // string which is ok.
          } else {
            error = Status::FromErrorStringWithFormat(
                "%s", "invalid entry definitions");
          }
        }
      } else {
        if (entry_def->children) {
          error = ParseEntry(value, entry_def, entry);
        } else if (sep_char == ':') {
          // Any value whose separator is a with a ':' means this value has a
          // string argument that needs to be stored in the entry (like
          // "${script.var:modulename.function}")
          entry.string = value.str();
        } else {
          error = Status::FromErrorStringWithFormat(
              "'%s' followed by '%s' but it has no children", key.str().c_str(),
              value.str().c_str());
        }
      }
      return error;
    }
  }
  StreamString error_strm;
  if (parent->type == FormatEntity::Entry::Type::Root)
    error_strm.Printf(
        "invalid top level item '%s'. Valid top level items are: ",
        key.str().c_str());
  else
    error_strm.Printf("invalid member '%s' in '%s'. Valid members are: ",
                      key.str().c_str(), parent->name);
  DumpCommaSeparatedChildEntryNames(error_strm, parent);
  error = Status::FromErrorStringWithFormat("%s", error_strm.GetData());
  return error;
}

static const Definition *FindEntry(const llvm::StringRef &format_str,
                                   const Definition *parent,
                                   llvm::StringRef &remainder) {
  Status error;

  std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split('.');
  const size_t n = parent->num_children;
  for (size_t i = 0; i < n; ++i) {
    const Definition *entry_def = parent->children + i;
    if (p.first == entry_def->name || entry_def->name[0] == '*') {
      if (p.second.empty()) {
        if (format_str.back() == '.')
          remainder = format_str.drop_front(format_str.size() - 1);
        else
          remainder = llvm::StringRef(); // Exact match
        return entry_def;
      } else {
        if (entry_def->children) {
          return FindEntry(p.second, entry_def, remainder);
        } else {
          remainder = p.second;
          return entry_def;
        }
      }
    }
  }
  remainder = format_str;
  return parent;
}

static Status ParseInternal(llvm::StringRef &format, Entry &parent_entry,
                            uint32_t depth) {
  Status error;
  while (!format.empty() && error.Success()) {
    const size_t non_special_chars = format.find_first_of("${}\\|");

    if (non_special_chars == llvm::StringRef::npos) {
      // No special characters, just string bytes so add them and we are done
      parent_entry.AppendText(format);
      return error;
    }

    if (non_special_chars > 0) {
      // We have a special character, so add all characters before these as a
      // plain string
      parent_entry.AppendText(format.substr(0, non_special_chars));
      format = format.drop_front(non_special_chars);
    }

    switch (format[0]) {
    case '\0':
      return error;

    case '{': {
      format = format.drop_front(); // Skip the '{'
      Entry scope_entry(Entry::Type::Scope);
      error = ParseInternal(format, scope_entry, depth + 1);
      if (error.Fail())
        return error;
      parent_entry.AppendEntry(std::move(scope_entry));
    } break;

    case '}':
      if (depth == 0)
        error = Status::FromErrorString("unmatched '}' character");
      else
        format =
            format
                .drop_front(); // Skip the '}' as we are at the end of the scope
      return error;

    case '|':
      format = format.drop_front(); // Skip the '|'
      if (parent_entry.type == Entry::Type::Scope)
        parent_entry.StartAlternative();
      else
        parent_entry.AppendChar('|');
      break;

    case '\\': {
      format = format.drop_front(); // Skip the '\' character
      if (format.empty()) {
        error = Status::FromErrorString(
            "'\\' character was not followed by another character");
        return error;
      }

      const char desens_char = format[0];
      format = format.drop_front(); // Skip the desensitized char character
      switch (desens_char) {
      case 'a':
        parent_entry.AppendChar('\a');
        break;
      case 'b':
        parent_entry.AppendChar('\b');
        break;
      case 'f':
        parent_entry.AppendChar('\f');
        break;
      case 'n':
        parent_entry.AppendChar('\n');
        break;
      case 'r':
        parent_entry.AppendChar('\r');
        break;
      case 't':
        parent_entry.AppendChar('\t');
        break;
      case 'v':
        parent_entry.AppendChar('\v');
        break;
      case '\'':
        parent_entry.AppendChar('\'');
        break;
      case '\\':
        parent_entry.AppendChar('\\');
        break;
      case '0':
        // 1 to 3 octal chars
        {
          // Make a string that can hold onto the initial zero char, up to 3
          // octal digits, and a terminating NULL.
          char oct_str[5] = {0, 0, 0, 0, 0};

          int i;
          for (i = 0; (format[i] >= '0' && format[i] <= '7') && i < 4; ++i)
            oct_str[i] = format[i];

          // We don't want to consume the last octal character since the main
          // for loop will do this for us, so we advance p by one less than i
          // (even if i is zero)
          format = format.drop_front(i);
          unsigned long octal_value = ::strtoul(oct_str, nullptr, 8);
          if (octal_value <= UINT8_MAX) {
            parent_entry.AppendChar((char)octal_value);
          } else {
            error = Status::FromErrorString(
                "octal number is larger than a single byte");
            return error;
          }
        }
        break;

      case 'x':
        // hex number in the format
        if (isxdigit(format[0])) {
          // Make a string that can hold onto two hex chars plus a
          // NULL terminator
          char hex_str[3] = {0, 0, 0};
          hex_str[0] = format[0];

          format = format.drop_front();

          if (isxdigit(format[0])) {
            hex_str[1] = format[0];
            format = format.drop_front();
          }

          unsigned long hex_value = strtoul(hex_str, nullptr, 16);
          if (hex_value <= UINT8_MAX) {
            parent_entry.AppendChar((char)hex_value);
          } else {
            error = Status::FromErrorString(
                "hex number is larger than a single byte");
            return error;
          }
        } else {
          parent_entry.AppendChar(desens_char);
        }
        break;

      default:
        // Just desensitize any other character by just printing what came
        // after the '\'
        parent_entry.AppendChar(desens_char);
        break;
      }
    } break;

    case '$':
      format = format.drop_front(); // Skip the '$'
      if (format.empty() || format.front() != '{') {
        // Print '$' when not followed by '{'.
        parent_entry.AppendText("$");
      } else {
        format = format.drop_front(); // Skip the '{'

        llvm::StringRef variable, variable_format;
        error = FormatEntity::ExtractVariableInfo(format, variable,
                                                  variable_format);
        if (error.Fail())
          return error;
        bool verify_is_thread_id = false;
        Entry entry;
        if (!variable_format.empty()) {
          entry.printf_format = variable_format.str();

          // If the format contains a '%' we are going to assume this is a
          // printf style format. So if you want to format your thread ID
          // using "0x%llx" you can use: ${thread.id%0x%llx}
          //
          // If there is no '%' in the format, then it is assumed to be a
          // LLDB format name, or one of the extended formats specified in
          // the switch statement below.

          if (entry.printf_format.find('%') == std::string::npos) {
            bool clear_printf = false;

            if (entry.printf_format.size() == 1) {
              switch (entry.printf_format[0]) {
              case '@': // if this is an @ sign, print ObjC description
                entry.number = ValueObject::
                    eValueObjectRepresentationStyleLanguageSpecific;
                clear_printf = true;
                break;
              case 'V': // if this is a V, print the value using the default
                        // format
                entry.number =
                    ValueObject::eValueObjectRepresentationStyleValue;
                clear_printf = true;
                break;
              case 'L': // if this is an L, print the location of the value
                entry.number =
                    ValueObject::eValueObjectRepresentationStyleLocation;
                clear_printf = true;
                break;
              case 'S': // if this is an S, print the summary after all
                entry.number =
                    ValueObject::eValueObjectRepresentationStyleSummary;
                clear_printf = true;
                break;
              case '#': // if this is a '#', print the number of children
                entry.number =
                    ValueObject::eValueObjectRepresentationStyleChildrenCount;
                clear_printf = true;
                break;
              case 'T': // if this is a 'T', print the type
                entry.number = ValueObject::eValueObjectRepresentationStyleType;
                clear_printf = true;
                break;
              case 'N': // if this is a 'N', print the name
                entry.number = ValueObject::eValueObjectRepresentationStyleName;
                clear_printf = true;
                break;
              case '>': // if this is a '>', print the expression path
                entry.number =
                    ValueObject::eValueObjectRepresentationStyleExpressionPath;
                clear_printf = true;
                break;
              }
            }

            if (entry.number == 0) {
              if (FormatManager::GetFormatFromCString(
                      entry.printf_format.c_str(), entry.fmt)) {
                clear_printf = true;
              } else if (entry.printf_format == "tid") {
                verify_is_thread_id = true;
              } else {
                error = Status::FromErrorStringWithFormat(
                    "invalid format: '%s'", entry.printf_format.c_str());
                return error;
              }
            }

            // Our format string turned out to not be a printf style format
            // so lets clear the string
            if (clear_printf)
              entry.printf_format.clear();
          }
        }

        // Check for dereferences
        if (variable[0] == '*') {
          entry.deref = true;
          variable = variable.drop_front();
        }

        error = ParseEntry(variable, &g_root, entry);
        if (error.Fail())
          return error;

        llvm::StringRef entry_string(entry.string);
        if (entry_string.contains(':')) {
          auto [_, llvm_format] = entry_string.split(':');
          if (!llvm_format.empty() && !LLVMFormatPattern.match(llvm_format)) {
            error = Status::FromErrorStringWithFormat(
                "invalid llvm format: '%s'", llvm_format.data());
            return error;
          }
        }

        if (verify_is_thread_id) {
          if (entry.type != Entry::Type::ThreadID &&
              entry.type != Entry::Type::ThreadProtocolID) {
            error = Status::FromErrorString(
                "the 'tid' format can only be used on "
                "${thread.id} and ${thread.protocol_id}");
          }
        }

        switch (entry.type) {
        case Entry::Type::Variable:
        case Entry::Type::VariableSynthetic:
          if (entry.number == 0) {
            if (entry.string.empty())
              entry.number = ValueObject::eValueObjectRepresentationStyleValue;
            else
              entry.number =
                  ValueObject::eValueObjectRepresentationStyleSummary;
          }
          break;
        default:
          // Make sure someone didn't try to dereference anything but ${var}
          // or ${svar}
          if (entry.deref) {
            error = Status::FromErrorStringWithFormat(
                "${%s} can't be dereferenced, only ${var} and ${svar} can.",
                variable.str().c_str());
            return error;
          }
        }
        parent_entry.AppendEntry(std::move(entry));
      }
      break;
    }
  }
  return error;
}

Status FormatEntity::ExtractVariableInfo(llvm::StringRef &format_str,
                                         llvm::StringRef &variable_name,
                                         llvm::StringRef &variable_format) {
  Status error;
  variable_name = llvm::StringRef();
  variable_format = llvm::StringRef();

  const size_t paren_pos = format_str.find('}');
  if (paren_pos != llvm::StringRef::npos) {
    const size_t percent_pos = format_str.find('%');
    if (percent_pos < paren_pos) {
      if (percent_pos > 0) {
        if (percent_pos > 1)
          variable_name = format_str.substr(0, percent_pos);
        variable_format =
            format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
      }
    } else {
      variable_name = format_str.substr(0, paren_pos);
    }
    // Strip off elements and the formatting and the trailing '}'
    format_str = format_str.substr(paren_pos + 1);
  } else {
    error = Status::FromErrorStringWithFormat(
        "missing terminating '}' character for '${%s'",
        format_str.str().c_str());
  }
  return error;
}

bool FormatEntity::FormatFileSpec(const FileSpec &file_spec, Stream &s,
                                  llvm::StringRef variable_name,
                                  llvm::StringRef variable_format) {
  if (variable_name.empty() || variable_name == ".fullpath") {
    file_spec.Dump(s.AsRawOstream());
    return true;
  } else if (variable_name == ".basename") {
    s.PutCString(file_spec.GetFilename().GetStringRef());
    return true;
  } else if (variable_name == ".dirname") {
    s.PutCString(file_spec.GetFilename().GetStringRef());
    return true;
  }
  return false;
}

static std::string MakeMatch(const llvm::StringRef &prefix,
                             const char *suffix) {
  std::string match(prefix.str());
  match.append(suffix);
  return match;
}

static void AddMatches(const Definition *def, const llvm::StringRef &prefix,
                       const llvm::StringRef &match_prefix,
                       StringList &matches) {
  const size_t n = def->num_children;
  if (n > 0) {
    for (size_t i = 0; i < n; ++i) {
      if (match_prefix.empty())
        matches.AppendString(MakeMatch(prefix, def->children[i].name));
      else if (strncmp(def->children[i].name, match_prefix.data(),
                       match_prefix.size()) == 0)
        matches.AppendString(
            MakeMatch(prefix, def->children[i].name + match_prefix.size()));
    }
  }
}

void FormatEntity::AutoComplete(CompletionRequest &request) {
  llvm::StringRef str = request.GetCursorArgumentPrefix();

  const size_t dollar_pos = str.rfind('$');
  if (dollar_pos == llvm::StringRef::npos)
    return;

  // Hitting TAB after $ at the end of the string add a "{"
  if (dollar_pos == str.size() - 1) {
    std::string match = str.str();
    match.append("{");
    request.AddCompletion(match);
    return;
  }

  if (str[dollar_pos + 1] != '{')
    return;

  const size_t close_pos = str.find('}', dollar_pos + 2);
  if (close_pos != llvm::StringRef::npos)
    return;

  const size_t format_pos = str.find('%', dollar_pos + 2);
  if (format_pos != llvm::StringRef::npos)
    return;

  llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
  if (partial_variable.empty()) {
    // Suggest all top level entities as we are just past "${"
    StringList new_matches;
    AddMatches(&g_root, str, llvm::StringRef(), new_matches);
    request.AddCompletions(new_matches);
    return;
  }

  // We have a partially specified variable, find it
  llvm::StringRef remainder;
  const Definition *entry_def = FindEntry(partial_variable, &g_root, remainder);
  if (!entry_def)
    return;

  const size_t n = entry_def->num_children;

  if (remainder.empty()) {
    // Exact match
    if (n > 0) {
      // "${thread.info" <TAB>
      request.AddCompletion(MakeMatch(str, "."));
    } else {
      // "${thread.id" <TAB>
      request.AddCompletion(MakeMatch(str, "}"));
    }
  } else if (remainder == ".") {
    // "${thread." <TAB>
    StringList new_matches;
    AddMatches(entry_def, str, llvm::StringRef(), new_matches);
    request.AddCompletions(new_matches);
  } else {
    // We have a partial match
    // "${thre" <TAB>
    StringList new_matches;
    AddMatches(entry_def, str, remainder, new_matches);
    request.AddCompletions(new_matches);
  }
}

void FormatEntity::PrettyPrintFunctionArguments(
    Stream &out_stream, VariableList const &args,
    ExecutionContextScope *exe_scope) {
  const size_t num_args = args.GetSize();
  for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
    std::string buffer;

    VariableSP var_sp(args.GetVariableAtIndex(arg_idx));
    ValueObjectSP var_value_sp(ValueObjectVariable::Create(exe_scope, var_sp));
    StreamString ss;
    llvm::StringRef var_representation;
    const char *var_name = var_value_sp->GetName().GetCString();
    if (var_value_sp->GetCompilerType().IsValid()) {
      if (exe_scope && exe_scope->CalculateTarget())
        var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(
            exe_scope->CalculateTarget()
                ->TargetProperties::GetPreferDynamicValue(),
            exe_scope->CalculateTarget()
                ->TargetProperties::GetEnableSyntheticValue());
      if (var_value_sp->GetCompilerType().IsAggregateType() &&
          DataVisualization::ShouldPrintAsOneLiner(*var_value_sp)) {
        static StringSummaryFormat format(TypeSummaryImpl::Flags()
                                              .SetHideItemNames(false)
                                              .SetShowMembersOneLiner(true),
                                          "");
        format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
        var_representation = buffer;
      } else
        var_value_sp->DumpPrintableRepresentation(
            ss,
            ValueObject::ValueObjectRepresentationStyle::
                eValueObjectRepresentationStyleSummary,
            eFormatDefault,
            ValueObject::PrintableRepresentationSpecialCases::eAllow, false);
    }

    if (!ss.GetString().empty())
      var_representation = ss.GetString();
    if (arg_idx > 0)
      out_stream.PutCString(", ");
    if (var_value_sp->GetError().Success()) {
      if (!var_representation.empty())
        out_stream.Printf("%s=%s", var_name, var_representation.str().c_str());
      else
        out_stream.Printf("%s=%s at %s", var_name,
                          var_value_sp->GetTypeName().GetCString(),
                          var_value_sp->GetLocationAsCString());
    } else
      out_stream.Printf("%s=<unavailable>", var_name);
  }
}

Status FormatEntity::Parse(const llvm::StringRef &format_str, Entry &entry) {
  entry.Clear();
  entry.type = Entry::Type::Root;
  llvm::StringRef modifiable_format(format_str);
  return ParseInternal(modifiable_format, entry, 0);
}
