//===-- SBCommandInterpreter.cpp --------------------------------*- C++ -*-===//
//
// 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/lldb-types.h"

#include "SBReproducerPrivate.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Listener.h"

#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBExecutionContext.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBStringList.h"
#include "lldb/API/SBTarget.h"

#include <memory>

using namespace lldb;
using namespace lldb_private;

SBCommandInterpreterRunOptions::SBCommandInterpreterRunOptions() {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommandInterpreterRunOptions);

  m_opaque_up.reset(new CommandInterpreterRunOptions());
}

SBCommandInterpreterRunOptions::~SBCommandInterpreterRunOptions() = default;

bool SBCommandInterpreterRunOptions::GetStopOnContinue() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions,
                                   GetStopOnContinue);

  return m_opaque_up->GetStopOnContinue();
}

void SBCommandInterpreterRunOptions::SetStopOnContinue(bool stop_on_continue) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnContinue,
                     (bool), stop_on_continue);

  m_opaque_up->SetStopOnContinue(stop_on_continue);
}

bool SBCommandInterpreterRunOptions::GetStopOnError() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions,
                                   GetStopOnError);

  return m_opaque_up->GetStopOnError();
}

void SBCommandInterpreterRunOptions::SetStopOnError(bool stop_on_error) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnError,
                     (bool), stop_on_error);

  m_opaque_up->SetStopOnError(stop_on_error);
}

bool SBCommandInterpreterRunOptions::GetStopOnCrash() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions,
                                   GetStopOnCrash);

  return m_opaque_up->GetStopOnCrash();
}

void SBCommandInterpreterRunOptions::SetStopOnCrash(bool stop_on_crash) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnCrash,
                     (bool), stop_on_crash);

  m_opaque_up->SetStopOnCrash(stop_on_crash);
}

bool SBCommandInterpreterRunOptions::GetEchoCommands() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions,
                                   GetEchoCommands);

  return m_opaque_up->GetEchoCommands();
}

void SBCommandInterpreterRunOptions::SetEchoCommands(bool echo_commands) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetEchoCommands,
                     (bool), echo_commands);

  m_opaque_up->SetEchoCommands(echo_commands);
}

bool SBCommandInterpreterRunOptions::GetEchoCommentCommands() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions,
                                   GetEchoCommentCommands);

  return m_opaque_up->GetEchoCommentCommands();
}

void SBCommandInterpreterRunOptions::SetEchoCommentCommands(bool echo) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions,
                     SetEchoCommentCommands, (bool), echo);

  m_opaque_up->SetEchoCommentCommands(echo);
}

bool SBCommandInterpreterRunOptions::GetPrintResults() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions,
                                   GetPrintResults);

  return m_opaque_up->GetPrintResults();
}

void SBCommandInterpreterRunOptions::SetPrintResults(bool print_results) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetPrintResults,
                     (bool), print_results);

  m_opaque_up->SetPrintResults(print_results);
}

bool SBCommandInterpreterRunOptions::GetAddToHistory() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions,
                                   GetAddToHistory);

  return m_opaque_up->GetAddToHistory();
}

void SBCommandInterpreterRunOptions::SetAddToHistory(bool add_to_history) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetAddToHistory,
                     (bool), add_to_history);

  m_opaque_up->SetAddToHistory(add_to_history);
}

lldb_private::CommandInterpreterRunOptions *
SBCommandInterpreterRunOptions::get() const {
  return m_opaque_up.get();
}

lldb_private::CommandInterpreterRunOptions &
SBCommandInterpreterRunOptions::ref() const {
  return *m_opaque_up;
}

class CommandPluginInterfaceImplementation : public CommandObjectParsed {
public:
  CommandPluginInterfaceImplementation(CommandInterpreter &interpreter,
                                       const char *name,
                                       lldb::SBCommandPluginInterface *backend,
                                       const char *help = nullptr,
                                       const char *syntax = nullptr,
                                       uint32_t flags = 0)
      : CommandObjectParsed(interpreter, name, help, syntax, flags),
        m_backend(backend) {}

  bool IsRemovable() const override { return true; }

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    SBCommandReturnObject sb_return(result);
    SBCommandInterpreter sb_interpreter(&m_interpreter);
    SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this());
    bool ret = m_backend->DoExecute(
        debugger_sb, (char **)command.GetArgumentVector(), sb_return);
    return ret;
  }
  std::shared_ptr<lldb::SBCommandPluginInterface> m_backend;
};

SBCommandInterpreter::SBCommandInterpreter(CommandInterpreter *interpreter)
    : m_opaque_ptr(interpreter) {
  LLDB_RECORD_CONSTRUCTOR(SBCommandInterpreter,
                          (lldb_private::CommandInterpreter *), interpreter);

}

SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs)
    : m_opaque_ptr(rhs.m_opaque_ptr) {
  LLDB_RECORD_CONSTRUCTOR(SBCommandInterpreter,
                          (const lldb::SBCommandInterpreter &), rhs);
}

SBCommandInterpreter::~SBCommandInterpreter() = default;

const SBCommandInterpreter &SBCommandInterpreter::
operator=(const SBCommandInterpreter &rhs) {
  LLDB_RECORD_METHOD(
      const lldb::SBCommandInterpreter &,
      SBCommandInterpreter, operator=,(const lldb::SBCommandInterpreter &),
      rhs);

  m_opaque_ptr = rhs.m_opaque_ptr;
  return LLDB_RECORD_RESULT(*this);
}

bool SBCommandInterpreter::IsValid() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreter, IsValid);
  return this->operator bool();
}
SBCommandInterpreter::operator bool() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreter, operator bool);

  return m_opaque_ptr != nullptr;
}

bool SBCommandInterpreter::CommandExists(const char *cmd) {
  LLDB_RECORD_METHOD(bool, SBCommandInterpreter, CommandExists, (const char *),
                     cmd);

  return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->CommandExists(cmd)
                                          : false);
}

bool SBCommandInterpreter::AliasExists(const char *cmd) {
  LLDB_RECORD_METHOD(bool, SBCommandInterpreter, AliasExists, (const char *),
                     cmd);

  return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->AliasExists(cmd)
                                          : false);
}

bool SBCommandInterpreter::IsActive() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandInterpreter, IsActive);

  return (IsValid() ? m_opaque_ptr->IsActive() : false);
}

bool SBCommandInterpreter::WasInterrupted() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreter, WasInterrupted);

  return (IsValid() ? m_opaque_ptr->WasInterrupted() : false);
}

const char *SBCommandInterpreter::GetIOHandlerControlSequence(char ch) {
  LLDB_RECORD_METHOD(const char *, SBCommandInterpreter,
                     GetIOHandlerControlSequence, (char), ch);

  return (IsValid()
              ? m_opaque_ptr->GetDebugger()
                    .GetTopIOHandlerControlSequence(ch)
                    .GetCString()
              : nullptr);
}

lldb::ReturnStatus
SBCommandInterpreter::HandleCommand(const char *command_line,
                                    SBCommandReturnObject &result,
                                    bool add_to_history) {
  LLDB_RECORD_METHOD(lldb::ReturnStatus, SBCommandInterpreter, HandleCommand,
                     (const char *, lldb::SBCommandReturnObject &, bool),
                     command_line, result, add_to_history);

  SBExecutionContext sb_exe_ctx;
  return HandleCommand(command_line, sb_exe_ctx, result, add_to_history);
}

lldb::ReturnStatus SBCommandInterpreter::HandleCommand(
    const char *command_line, SBExecutionContext &override_context,
    SBCommandReturnObject &result, bool add_to_history) {
  LLDB_RECORD_METHOD(lldb::ReturnStatus, SBCommandInterpreter, HandleCommand,
                     (const char *, lldb::SBExecutionContext &,
                      lldb::SBCommandReturnObject &, bool),
                     command_line, override_context, result, add_to_history);


  ExecutionContext ctx, *ctx_ptr;
  if (override_context.get()) {
    ctx = override_context.get()->Lock(true);
    ctx_ptr = &ctx;
  } else
    ctx_ptr = nullptr;

  result.Clear();
  if (command_line && IsValid()) {
    result.ref().SetInteractive(false);
    m_opaque_ptr->HandleCommand(command_line,
                                add_to_history ? eLazyBoolYes : eLazyBoolNo,
                                result.ref(), ctx_ptr);
  } else {
    result->AppendError(
        "SBCommandInterpreter or the command line is not valid");
    result->SetStatus(eReturnStatusFailed);
  }


  return result.GetStatus();
}

void SBCommandInterpreter::HandleCommandsFromFile(
    lldb::SBFileSpec &file, lldb::SBExecutionContext &override_context,
    lldb::SBCommandInterpreterRunOptions &options,
    lldb::SBCommandReturnObject result) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreter, HandleCommandsFromFile,
                     (lldb::SBFileSpec &, lldb::SBExecutionContext &,
                      lldb::SBCommandInterpreterRunOptions &,
                      lldb::SBCommandReturnObject),
                     file, override_context, options, result);

  if (!IsValid()) {
    result->AppendError("SBCommandInterpreter is not valid.");
    result->SetStatus(eReturnStatusFailed);
    return;
  }

  if (!file.IsValid()) {
    SBStream s;
    file.GetDescription(s);
    result->AppendErrorWithFormat("File is not valid: %s.", s.GetData());
    result->SetStatus(eReturnStatusFailed);
  }

  FileSpec tmp_spec = file.ref();
  ExecutionContext ctx, *ctx_ptr;
  if (override_context.get()) {
    ctx = override_context.get()->Lock(true);
    ctx_ptr = &ctx;
  } else
    ctx_ptr = nullptr;

  m_opaque_ptr->HandleCommandsFromFile(tmp_spec, ctx_ptr, options.ref(),
                                       result.ref());
}

int SBCommandInterpreter::HandleCompletion(
    const char *current_line, const char *cursor, const char *last_char,
    int match_start_point, int max_return_elements, SBStringList &matches) {
  LLDB_RECORD_METHOD(int, SBCommandInterpreter, HandleCompletion,
                     (const char *, const char *, const char *, int, int,
                      lldb::SBStringList &),
                     current_line, cursor, last_char, match_start_point,
                     max_return_elements, matches);

  SBStringList dummy_descriptions;
  return HandleCompletionWithDescriptions(
      current_line, cursor, last_char, match_start_point, max_return_elements,
      matches, dummy_descriptions);
}

int SBCommandInterpreter::HandleCompletionWithDescriptions(
    const char *current_line, const char *cursor, const char *last_char,
    int match_start_point, int max_return_elements, SBStringList &matches,
    SBStringList &descriptions) {
  LLDB_RECORD_METHOD(int, SBCommandInterpreter,
                     HandleCompletionWithDescriptions,
                     (const char *, const char *, const char *, int, int,
                      lldb::SBStringList &, lldb::SBStringList &),
                     current_line, cursor, last_char, match_start_point,
                     max_return_elements, matches, descriptions);

  // Sanity check the arguments that are passed in: cursor & last_char have to
  // be within the current_line.
  if (current_line == nullptr || cursor == nullptr || last_char == nullptr)
    return 0;

  if (cursor < current_line || last_char < current_line)
    return 0;

  size_t current_line_size = strlen(current_line);
  if (cursor - current_line > static_cast<ptrdiff_t>(current_line_size) ||
      last_char - current_line > static_cast<ptrdiff_t>(current_line_size))
    return 0;

  if (!IsValid())
    return 0;

  lldb_private::StringList lldb_matches, lldb_descriptions;
  CompletionResult result;
  CompletionRequest request(current_line, cursor - current_line, result);
  m_opaque_ptr->HandleCompletion(request);
  result.GetMatches(lldb_matches);
  result.GetDescriptions(lldb_descriptions);

  // Make the result array indexed from 1 again by adding the 'common prefix'
  // of all completions as element 0. This is done to emulate the old API.
  if (request.GetParsedLine().GetArgumentCount() == 0) {
    // If we got an empty string, insert nothing.
    lldb_matches.InsertStringAtIndex(0, "");
    lldb_descriptions.InsertStringAtIndex(0, "");
  } else {
    // Now figure out if there is a common substring, and if so put that in
    // element 0, otherwise put an empty string in element 0.
    std::string command_partial_str = request.GetCursorArgumentPrefix().str();

    std::string common_prefix = lldb_matches.LongestCommonPrefix();
    const size_t partial_name_len = command_partial_str.size();
    common_prefix.erase(0, partial_name_len);

    // If we matched a unique single command, add a space... Only do this if
    // the completer told us this was a complete word, however...
    if (lldb_matches.GetSize() == 1) {
      char quote_char = request.GetParsedArg().GetQuoteChar();
      common_prefix =
          Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
      if (request.GetParsedArg().IsQuoted())
        common_prefix.push_back(quote_char);
      common_prefix.push_back(' ');
    }
    lldb_matches.InsertStringAtIndex(0, common_prefix.c_str());
    lldb_descriptions.InsertStringAtIndex(0, "");
  }

  SBStringList temp_matches_list(&lldb_matches);
  matches.AppendList(temp_matches_list);
  SBStringList temp_descriptions_list(&lldb_descriptions);
  descriptions.AppendList(temp_descriptions_list);
  return result.GetNumberOfResults();
}

int SBCommandInterpreter::HandleCompletionWithDescriptions(
    const char *current_line, uint32_t cursor_pos, int match_start_point,
    int max_return_elements, SBStringList &matches,
    SBStringList &descriptions) {
  LLDB_RECORD_METHOD(int, SBCommandInterpreter,
                     HandleCompletionWithDescriptions,
                     (const char *, uint32_t, int, int, lldb::SBStringList &,
                      lldb::SBStringList &),
                     current_line, cursor_pos, match_start_point,
                     max_return_elements, matches, descriptions);

  const char *cursor = current_line + cursor_pos;
  const char *last_char = current_line + strlen(current_line);
  return HandleCompletionWithDescriptions(
      current_line, cursor, last_char, match_start_point, max_return_elements,
      matches, descriptions);
}

int SBCommandInterpreter::HandleCompletion(const char *current_line,
                                           uint32_t cursor_pos,
                                           int match_start_point,
                                           int max_return_elements,
                                           lldb::SBStringList &matches) {
  LLDB_RECORD_METHOD(int, SBCommandInterpreter, HandleCompletion,
                     (const char *, uint32_t, int, int, lldb::SBStringList &),
                     current_line, cursor_pos, match_start_point,
                     max_return_elements, matches);

  const char *cursor = current_line + cursor_pos;
  const char *last_char = current_line + strlen(current_line);
  return HandleCompletion(current_line, cursor, last_char, match_start_point,
                          max_return_elements, matches);
}

bool SBCommandInterpreter::HasCommands() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandInterpreter, HasCommands);

  return (IsValid() ? m_opaque_ptr->HasCommands() : false);
}

bool SBCommandInterpreter::HasAliases() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandInterpreter, HasAliases);

  return (IsValid() ? m_opaque_ptr->HasAliases() : false);
}

bool SBCommandInterpreter::HasAliasOptions() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandInterpreter, HasAliasOptions);

  return (IsValid() ? m_opaque_ptr->HasAliasOptions() : false);
}

SBProcess SBCommandInterpreter::GetProcess() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBCommandInterpreter, GetProcess);

  SBProcess sb_process;
  ProcessSP process_sp;
  if (IsValid()) {
    TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
    if (target_sp) {
      std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
      process_sp = target_sp->GetProcessSP();
      sb_process.SetSP(process_sp);
    }
  }

  return LLDB_RECORD_RESULT(sb_process);
}

SBDebugger SBCommandInterpreter::GetDebugger() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBDebugger, SBCommandInterpreter,
                             GetDebugger);

  SBDebugger sb_debugger;
  if (IsValid())
    sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this());

  return LLDB_RECORD_RESULT(sb_debugger);
}

bool SBCommandInterpreter::GetPromptOnQuit() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandInterpreter, GetPromptOnQuit);

  return (IsValid() ? m_opaque_ptr->GetPromptOnQuit() : false);
}

void SBCommandInterpreter::SetPromptOnQuit(bool b) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreter, SetPromptOnQuit, (bool), b);

  if (IsValid())
    m_opaque_ptr->SetPromptOnQuit(b);
}

void SBCommandInterpreter::AllowExitCodeOnQuit(bool allow) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreter, AllowExitCodeOnQuit, (bool),
                     allow);

  if (m_opaque_ptr)
    m_opaque_ptr->AllowExitCodeOnQuit(allow);
}

bool SBCommandInterpreter::HasCustomQuitExitCode() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandInterpreter, HasCustomQuitExitCode);

  bool exited = false;
  if (m_opaque_ptr)
    m_opaque_ptr->GetQuitExitCode(exited);
  return exited;
}

int SBCommandInterpreter::GetQuitStatus() {
  LLDB_RECORD_METHOD_NO_ARGS(int, SBCommandInterpreter, GetQuitStatus);

  bool exited = false;
  return (m_opaque_ptr ? m_opaque_ptr->GetQuitExitCode(exited) : 0);
}

void SBCommandInterpreter::ResolveCommand(const char *command_line,
                                          SBCommandReturnObject &result) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreter, ResolveCommand,
                     (const char *, lldb::SBCommandReturnObject &),
                     command_line, result);

  result.Clear();
  if (command_line && IsValid()) {
    m_opaque_ptr->ResolveCommand(command_line, result.ref());
  } else {
    result->AppendError(
        "SBCommandInterpreter or the command line is not valid");
    result->SetStatus(eReturnStatusFailed);
  }
}

CommandInterpreter *SBCommandInterpreter::get() { return m_opaque_ptr; }

CommandInterpreter &SBCommandInterpreter::ref() {
  assert(m_opaque_ptr);
  return *m_opaque_ptr;
}

void SBCommandInterpreter::reset(
    lldb_private::CommandInterpreter *interpreter) {
  m_opaque_ptr = interpreter;
}

void SBCommandInterpreter::SourceInitFileInHomeDirectory(
    SBCommandReturnObject &result) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreter, SourceInitFileInHomeDirectory,
                     (lldb::SBCommandReturnObject &), result);

  result.Clear();
  if (IsValid()) {
    TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
    std::unique_lock<std::recursive_mutex> lock;
    if (target_sp)
      lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
    m_opaque_ptr->SourceInitFileHome(result.ref());
  } else {
    result->AppendError("SBCommandInterpreter is not valid");
    result->SetStatus(eReturnStatusFailed);
  }
}

void SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory(
    SBCommandReturnObject &result) {
  LLDB_RECORD_METHOD(void, SBCommandInterpreter,
                     SourceInitFileInCurrentWorkingDirectory,
                     (lldb::SBCommandReturnObject &), result);

  result.Clear();
  if (IsValid()) {
    TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
    std::unique_lock<std::recursive_mutex> lock;
    if (target_sp)
      lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
    m_opaque_ptr->SourceInitFileCwd(result.ref());
  } else {
    result->AppendError("SBCommandInterpreter is not valid");
    result->SetStatus(eReturnStatusFailed);
  }
}

SBBroadcaster SBCommandInterpreter::GetBroadcaster() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBroadcaster, SBCommandInterpreter,
                             GetBroadcaster);


  SBBroadcaster broadcaster(m_opaque_ptr, false);


  return LLDB_RECORD_RESULT(broadcaster);
}

const char *SBCommandInterpreter::GetBroadcasterClass() {
  LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBCommandInterpreter,
                                    GetBroadcasterClass);

  return CommandInterpreter::GetStaticBroadcasterClass().AsCString();
}

const char *SBCommandInterpreter::GetArgumentTypeAsCString(
    const lldb::CommandArgumentType arg_type) {
  LLDB_RECORD_STATIC_METHOD(const char *, SBCommandInterpreter,
                            GetArgumentTypeAsCString,
                            (const lldb::CommandArgumentType), arg_type);

  return CommandObject::GetArgumentTypeAsCString(arg_type);
}

const char *SBCommandInterpreter::GetArgumentDescriptionAsCString(
    const lldb::CommandArgumentType arg_type) {
  LLDB_RECORD_STATIC_METHOD(const char *, SBCommandInterpreter,
                            GetArgumentDescriptionAsCString,
                            (const lldb::CommandArgumentType), arg_type);

  return CommandObject::GetArgumentDescriptionAsCString(arg_type);
}

bool SBCommandInterpreter::EventIsCommandInterpreterEvent(
    const lldb::SBEvent &event) {
  LLDB_RECORD_STATIC_METHOD(bool, SBCommandInterpreter,
                            EventIsCommandInterpreterEvent,
                            (const lldb::SBEvent &), event);

  return event.GetBroadcasterClass() ==
         SBCommandInterpreter::GetBroadcasterClass();
}

bool SBCommandInterpreter::SetCommandOverrideCallback(
    const char *command_name, lldb::CommandOverrideCallback callback,
    void *baton) {
  LLDB_RECORD_DUMMY(bool, SBCommandInterpreter, SetCommandOverrideCallback,
                    (const char *, lldb::CommandOverrideCallback, void *),
                    command_name, callback, baton);

  if (command_name && command_name[0] && IsValid()) {
    llvm::StringRef command_name_str = command_name;
    CommandObject *cmd_obj =
        m_opaque_ptr->GetCommandObjectForCommand(command_name_str);
    if (cmd_obj) {
      assert(command_name_str.empty());
      cmd_obj->SetOverrideCallback(callback, baton);
      return true;
    }
  }
  return false;
}

lldb::SBCommand SBCommandInterpreter::AddMultiwordCommand(const char *name,
                                                          const char *help) {
  LLDB_RECORD_METHOD(lldb::SBCommand, SBCommandInterpreter, AddMultiwordCommand,
                     (const char *, const char *), name, help);

  CommandObjectMultiword *new_command =
      new CommandObjectMultiword(*m_opaque_ptr, name, help);
  new_command->SetRemovable(true);
  lldb::CommandObjectSP new_command_sp(new_command);
  if (new_command_sp &&
      m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
    return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp));
  return LLDB_RECORD_RESULT(lldb::SBCommand());
}

lldb::SBCommand SBCommandInterpreter::AddCommand(
    const char *name, lldb::SBCommandPluginInterface *impl, const char *help) {
  LLDB_RECORD_METHOD(
      lldb::SBCommand, SBCommandInterpreter, AddCommand,
      (const char *, lldb::SBCommandPluginInterface *, const char *), name,
      impl, help);

  lldb::CommandObjectSP new_command_sp;
  new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>(
      *m_opaque_ptr, name, impl, help);

  if (new_command_sp &&
      m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
    return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp));
  return LLDB_RECORD_RESULT(lldb::SBCommand());
}

lldb::SBCommand
SBCommandInterpreter::AddCommand(const char *name,
                                 lldb::SBCommandPluginInterface *impl,
                                 const char *help, const char *syntax) {
  LLDB_RECORD_METHOD(lldb::SBCommand, SBCommandInterpreter, AddCommand,
                     (const char *, lldb::SBCommandPluginInterface *,
                      const char *, const char *),
                     name, impl, help, syntax);

  lldb::CommandObjectSP new_command_sp;
  new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>(
      *m_opaque_ptr, name, impl, help, syntax);

  if (new_command_sp &&
      m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
    return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp));
  return LLDB_RECORD_RESULT(lldb::SBCommand());
}

SBCommand::SBCommand() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommand); }

SBCommand::SBCommand(lldb::CommandObjectSP cmd_sp) : m_opaque_sp(cmd_sp) {}

bool SBCommand::IsValid() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommand, IsValid);
  return this->operator bool();
}
SBCommand::operator bool() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommand, operator bool);

  return m_opaque_sp.get() != nullptr;
}

const char *SBCommand::GetName() {
  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommand, GetName);

  return (IsValid() ? ConstString(m_opaque_sp->GetCommandName()).AsCString() : nullptr);
}

const char *SBCommand::GetHelp() {
  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommand, GetHelp);

  return (IsValid() ? ConstString(m_opaque_sp->GetHelp()).AsCString()
                    : nullptr);
}

const char *SBCommand::GetHelpLong() {
  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommand, GetHelpLong);

  return (IsValid() ? ConstString(m_opaque_sp->GetHelpLong()).AsCString()
                    : nullptr);
}

void SBCommand::SetHelp(const char *help) {
  LLDB_RECORD_METHOD(void, SBCommand, SetHelp, (const char *), help);

  if (IsValid())
    m_opaque_sp->SetHelp(help);
}

void SBCommand::SetHelpLong(const char *help) {
  LLDB_RECORD_METHOD(void, SBCommand, SetHelpLong, (const char *), help);

  if (IsValid())
    m_opaque_sp->SetHelpLong(help);
}

lldb::SBCommand SBCommand::AddMultiwordCommand(const char *name,
                                               const char *help) {
  LLDB_RECORD_METHOD(lldb::SBCommand, SBCommand, AddMultiwordCommand,
                     (const char *, const char *), name, help);

  if (!IsValid())
    return LLDB_RECORD_RESULT(lldb::SBCommand());
  if (!m_opaque_sp->IsMultiwordObject())
    return LLDB_RECORD_RESULT(lldb::SBCommand());
  CommandObjectMultiword *new_command = new CommandObjectMultiword(
      m_opaque_sp->GetCommandInterpreter(), name, help);
  new_command->SetRemovable(true);
  lldb::CommandObjectSP new_command_sp(new_command);
  if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp))
    return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp));
  return LLDB_RECORD_RESULT(lldb::SBCommand());
}

lldb::SBCommand SBCommand::AddCommand(const char *name,
                                      lldb::SBCommandPluginInterface *impl,
                                      const char *help) {
  LLDB_RECORD_METHOD(
      lldb::SBCommand, SBCommand, AddCommand,
      (const char *, lldb::SBCommandPluginInterface *, const char *), name,
      impl, help);

  if (!IsValid())
    return LLDB_RECORD_RESULT(lldb::SBCommand());
  if (!m_opaque_sp->IsMultiwordObject())
    return LLDB_RECORD_RESULT(lldb::SBCommand());
  lldb::CommandObjectSP new_command_sp;
  new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>(
      m_opaque_sp->GetCommandInterpreter(), name, impl, help);
  if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp))
    return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp));
  return LLDB_RECORD_RESULT(lldb::SBCommand());
}

lldb::SBCommand SBCommand::AddCommand(const char *name,
                                      lldb::SBCommandPluginInterface *impl,
                                      const char *help, const char *syntax) {
  LLDB_RECORD_METHOD(lldb::SBCommand, SBCommand, AddCommand,
                     (const char *, lldb::SBCommandPluginInterface *,
                      const char *, const char *),
                     name, impl, help, syntax);

  if (!IsValid())
    return LLDB_RECORD_RESULT(lldb::SBCommand());
  if (!m_opaque_sp->IsMultiwordObject())
    return LLDB_RECORD_RESULT(lldb::SBCommand());
  lldb::CommandObjectSP new_command_sp;
  new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>(
      m_opaque_sp->GetCommandInterpreter(), name, impl, help, syntax);
  if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp))
    return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp));
  return LLDB_RECORD_RESULT(lldb::SBCommand());
}

uint32_t SBCommand::GetFlags() {
  LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBCommand, GetFlags);

  return (IsValid() ? m_opaque_sp->GetFlags().Get() : 0);
}

void SBCommand::SetFlags(uint32_t flags) {
  LLDB_RECORD_METHOD(void, SBCommand, SetFlags, (uint32_t), flags);

  if (IsValid())
    m_opaque_sp->GetFlags().Set(flags);
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBCommandInterpreterRunOptions>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreterRunOptions, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions,
                             GetStopOnContinue, ());
  LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions,
                       SetStopOnContinue, (bool));
  LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions,
                             GetStopOnError, ());
  LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnError,
                       (bool));
  LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions,
                             GetStopOnCrash, ());
  LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnCrash,
                       (bool));
  LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions,
                             GetEchoCommands, ());
  LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetEchoCommands,
                       (bool));
  LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions,
                             GetEchoCommentCommands, ());
  LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions,
                       SetEchoCommentCommands, (bool));
  LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions,
                             GetPrintResults, ());
  LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetPrintResults,
                       (bool));
  LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions,
                             GetAddToHistory, ());
  LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetAddToHistory,
                       (bool));
  LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreter,
                            (lldb_private::CommandInterpreter *));
  LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreter,
                            (const lldb::SBCommandInterpreter &));
  LLDB_REGISTER_METHOD(
      const lldb::SBCommandInterpreter &,
      SBCommandInterpreter, operator=,(const lldb::SBCommandInterpreter &));
  LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreter, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreter, operator bool, ());
  LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, CommandExists,
                       (const char *));
  LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, AliasExists,
                       (const char *));
  LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, IsActive, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreter, WasInterrupted, ());
  LLDB_REGISTER_METHOD(const char *, SBCommandInterpreter,
                       GetIOHandlerControlSequence, (char));
  LLDB_REGISTER_METHOD(lldb::ReturnStatus, SBCommandInterpreter,
                       HandleCommand,
                       (const char *, lldb::SBCommandReturnObject &, bool));
  LLDB_REGISTER_METHOD(lldb::ReturnStatus, SBCommandInterpreter,
                       HandleCommand,
                       (const char *, lldb::SBExecutionContext &,
                        lldb::SBCommandReturnObject &, bool));
  LLDB_REGISTER_METHOD(void, SBCommandInterpreter, HandleCommandsFromFile,
                       (lldb::SBFileSpec &, lldb::SBExecutionContext &,
                        lldb::SBCommandInterpreterRunOptions &,
                        lldb::SBCommandReturnObject));
  LLDB_REGISTER_METHOD(int, SBCommandInterpreter, HandleCompletion,
                       (const char *, const char *, const char *, int, int,
                        lldb::SBStringList &));
  LLDB_REGISTER_METHOD(int, SBCommandInterpreter,
                       HandleCompletionWithDescriptions,
                       (const char *, const char *, const char *, int, int,
                        lldb::SBStringList &, lldb::SBStringList &));
  LLDB_REGISTER_METHOD(int, SBCommandInterpreter,
                       HandleCompletionWithDescriptions,
                       (const char *, uint32_t, int, int,
                        lldb::SBStringList &, lldb::SBStringList &));
  LLDB_REGISTER_METHOD(
      int, SBCommandInterpreter, HandleCompletion,
      (const char *, uint32_t, int, int, lldb::SBStringList &));
  LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, HasCommands, ());
  LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, HasAliases, ());
  LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, HasAliasOptions, ());
  LLDB_REGISTER_METHOD(lldb::SBProcess, SBCommandInterpreter, GetProcess, ());
  LLDB_REGISTER_METHOD(lldb::SBDebugger, SBCommandInterpreter, GetDebugger,
                       ());
  LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, GetPromptOnQuit, ());
  LLDB_REGISTER_METHOD(void, SBCommandInterpreter, SetPromptOnQuit, (bool));
  LLDB_REGISTER_METHOD(void, SBCommandInterpreter, AllowExitCodeOnQuit,
                       (bool));
  LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, HasCustomQuitExitCode, ());
  LLDB_REGISTER_METHOD(int, SBCommandInterpreter, GetQuitStatus, ());
  LLDB_REGISTER_METHOD(void, SBCommandInterpreter, ResolveCommand,
                       (const char *, lldb::SBCommandReturnObject &));
  LLDB_REGISTER_METHOD(void, SBCommandInterpreter,
                       SourceInitFileInHomeDirectory,
                       (lldb::SBCommandReturnObject &));
  LLDB_REGISTER_METHOD(void, SBCommandInterpreter,
                       SourceInitFileInCurrentWorkingDirectory,
                       (lldb::SBCommandReturnObject &));
  LLDB_REGISTER_METHOD(lldb::SBBroadcaster, SBCommandInterpreter,
                       GetBroadcaster, ());
  LLDB_REGISTER_STATIC_METHOD(const char *, SBCommandInterpreter,
                              GetBroadcasterClass, ());
  LLDB_REGISTER_STATIC_METHOD(const char *, SBCommandInterpreter,
                              GetArgumentTypeAsCString,
                              (const lldb::CommandArgumentType));
  LLDB_REGISTER_STATIC_METHOD(const char *, SBCommandInterpreter,
                              GetArgumentDescriptionAsCString,
                              (const lldb::CommandArgumentType));
  LLDB_REGISTER_STATIC_METHOD(bool, SBCommandInterpreter,
                              EventIsCommandInterpreterEvent,
                              (const lldb::SBEvent &));
  LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommandInterpreter,
                       AddMultiwordCommand, (const char *, const char *));
  LLDB_REGISTER_METHOD(
      lldb::SBCommand, SBCommandInterpreter, AddCommand,
      (const char *, lldb::SBCommandPluginInterface *, const char *));
  LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommandInterpreter, AddCommand,
                       (const char *, lldb::SBCommandPluginInterface *,
                        const char *, const char *));
  LLDB_REGISTER_CONSTRUCTOR(SBCommand, ());
  LLDB_REGISTER_METHOD(bool, SBCommand, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBCommand, operator bool, ());
  LLDB_REGISTER_METHOD(const char *, SBCommand, GetName, ());
  LLDB_REGISTER_METHOD(const char *, SBCommand, GetHelp, ());
  LLDB_REGISTER_METHOD(const char *, SBCommand, GetHelpLong, ());
  LLDB_REGISTER_METHOD(void, SBCommand, SetHelp, (const char *));
  LLDB_REGISTER_METHOD(void, SBCommand, SetHelpLong, (const char *));
  LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommand, AddMultiwordCommand,
                       (const char *, const char *));
  LLDB_REGISTER_METHOD(
      lldb::SBCommand, SBCommand, AddCommand,
      (const char *, lldb::SBCommandPluginInterface *, const char *));
  LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommand, AddCommand,
                       (const char *, lldb::SBCommandPluginInterface *,
                        const char *, const char *));
  LLDB_REGISTER_METHOD(uint32_t, SBCommand, GetFlags, ());
  LLDB_REGISTER_METHOD(void, SBCommand, SetFlags, (uint32_t));
}

}
}
