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

#include "lldb/Core/Debugger.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/SaveCoreOptions.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StringList.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/ErrorExtras.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <memory>
#include <mutex>
#include <string>
#include <utility>
#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h"
#endif

using namespace lldb;
using namespace lldb_private;

typedef bool (*PluginInitCallback)();
typedef void (*PluginTermCallback)();

struct PluginInfo {
  PluginInfo() = default;

  PluginInfo(const PluginInfo &) = delete;
  PluginInfo &operator=(const PluginInfo &) = delete;

  PluginInfo(PluginInfo &&other)
      : library(std::move(other.library)),
        plugin_init_callback(
            std::exchange(other.plugin_init_callback, nullptr)),
        plugin_term_callback(
            std::exchange(other.plugin_term_callback, nullptr)) {}

  PluginInfo &operator=(PluginInfo &&other) {
    library = std::move(other.library);
    plugin_init_callback = std::exchange(other.plugin_init_callback, nullptr);
    plugin_term_callback = std::exchange(other.plugin_term_callback, nullptr);
    return *this;
  }

  ~PluginInfo() {
    if (!library.isValid())
      return;
    if (!plugin_term_callback)
      return;
    plugin_term_callback();
  }

  static llvm::Expected<PluginInfo> Create(const FileSpec &path);

private:
  llvm::sys::DynamicLibrary library;
  PluginInitCallback plugin_init_callback = nullptr;
  PluginTermCallback plugin_term_callback = nullptr;
};

typedef llvm::SmallDenseMap<FileSpec, PluginInfo> DynamicPluginMap;

namespace {
enum class PluginLifecycle { Uninitialized, Initialized, Terminated };

struct PluginRegistry {
  std::recursive_mutex mutex;
  DynamicPluginMap map;

  void Initialize() {
    std::lock_guard<std::recursive_mutex> guard(mutex);
    lifecycle = PluginLifecycle::Initialized;
  }

  void Terminate() {
    std::lock_guard<std::recursive_mutex> guard(mutex);
    lifecycle = PluginLifecycle::Terminated;
    map.clear();
  }

  // Only after Terminate() is a leftover PluginInstances registration a bug;
  // exiting in any other state (e.g. `import lldb`, which never calls
  // Terminate()) is supported and leaves plugins registered.
  bool IsTerminated() const { return lifecycle == PluginLifecycle::Terminated; }

private:
  PluginLifecycle lifecycle = PluginLifecycle::Uninitialized;
};
} // namespace

// Never destroyed: at static-destruction time the PluginInstances containers
// (separate statics, arbitrary teardown order) still call IsTerminated(), and
// the map's PluginInfo terminate callbacks must not run when the containers
// they unregister from may already be gone. Terminate() clears the map
// explicitly while everything is alive. The static pointer keeps it reachable,
// so this is not a LeakSanitizer leak.
static PluginRegistry &GetPluginRegistry() {
  static PluginRegistry *g_registry = new PluginRegistry();
  return *g_registry;
}

static std::recursive_mutex &GetPluginMapMutex() {
  return GetPluginRegistry().mutex;
}

static DynamicPluginMap &GetPluginMap() { return GetPluginRegistry().map; }

static bool PluginIsLoaded(const FileSpec &plugin_file_spec) {
  std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
  return GetPluginMap().contains(plugin_file_spec);
}

static void SetPluginInfo(const FileSpec &plugin_file_spec,
                          PluginInfo plugin_info) {
  std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
  DynamicPluginMap &plugin_map = GetPluginMap();
  assert(!plugin_map.contains(plugin_file_spec));
  plugin_map.try_emplace(plugin_file_spec, std::move(plugin_info));
}

template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
  return reinterpret_cast<FPtrTy>(VPtr);
}

static constexpr llvm::StringLiteral g_plugin_prefix = "liblldbPlugin";
struct PluginDir {
  enum LoadPolicy {
    /// Try to load anything that looks like a shared library.
    LoadAnyDylib,

    /// Only load shared libraries who's filename start with g_plugin_prefix.
    LoadOnlyWithLLDBPrefix,
  };

  PluginDir(FileSpec path, LoadPolicy policy)
      : path(std::move(path)), policy(policy) {}

  explicit operator bool() const { return FileSystem::Instance().Exists(path); }

  /// The path to the plugin directory.
  const FileSpec path;

  /// Filter when looking for plugins.
  const LoadPolicy policy;
};

llvm::Expected<PluginInfo> PluginInfo::Create(const FileSpec &path) {
  PluginInfo plugin_info;
  std::string error;
  plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary(
      path.GetPath().c_str(), &error);
  if (!plugin_info.library.isValid())
    return llvm::createStringError(error);

  // Look for files that follow the convention <g_plugin_prefix><name>.<ext>, in
  // which case we need to call lldb_initialize_<name> and
  // lldb_terminate_<name>.
  llvm::StringRef file_name =
      path.GetFileNameStrippingExtension().GetStringRef();
  if (file_name.starts_with(g_plugin_prefix)) {
    llvm::StringRef plugin_name = file_name.substr(g_plugin_prefix.size());
    std::string init_symbol =
        llvm::Twine("lldb_initialize_" + plugin_name).str();

    if (auto *init_fn = CastToFPtr<PluginInitCallback>(
            plugin_info.library.getAddressOfSymbol(init_symbol.c_str()))) {
      if (!init_fn())
        return llvm::createStringErrorV("initializer '{0}' returned false",
                                        init_symbol);
      const std::string term_symbol =
          llvm::Twine("lldb_terminate_" + plugin_name).str();
      plugin_info.plugin_term_callback = CastToFPtr<PluginTermCallback>(
          plugin_info.library.getAddressOfSymbol(term_symbol.c_str()));
    }
    return plugin_info;
  }

  // Look for the legacy LLDBPluginInitialize/LLDBPluginTerminate symbols.
  if (auto *init_fn = CastToFPtr<PluginInitCallback>(
          plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"))) {
    if (!init_fn())
      return llvm::createStringError(
          "initializer 'LLDBPluginInitialize' returned false");

    plugin_info.plugin_init_callback = init_fn;
    plugin_info.plugin_term_callback = CastToFPtr<PluginTermCallback>(
        plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
    return plugin_info;
  }

  return llvm::createStringError("no initialize symbol found");
}

static FileSystem::EnumerateDirectoryResult
LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
                   llvm::StringRef path) {
  namespace fs = llvm::sys::fs;

  static constexpr std::array<llvm::StringLiteral, 3>
      g_shared_library_extension = {".dylib", ".so", ".dll"};

  // If we have a regular file, a symbolic link or unknown file type, try and
  // process the file. We must handle unknown as sometimes the directory
  // enumeration might be enumerating a file system that doesn't have correct
  // file type information.
  if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
      ft == fs::file_type::type_unknown) {
    FileSpec plugin_file_spec(path);
    FileSystem::Instance().Resolve(plugin_file_spec);

    // Don't try to load unknown extensions.
    if (!llvm::is_contained(g_shared_library_extension,
                            plugin_file_spec.GetFileNameExtension()))
      return FileSystem::eEnumerateDirectoryResultNext;

    // Don't try to load libraries that don't start with g_plugin_prefix if so
    // requested.
    PluginDir::LoadPolicy *policy = (PluginDir::LoadPolicy *)baton;
    if (*policy == PluginDir::LoadOnlyWithLLDBPrefix &&
        !plugin_file_spec.GetFilename().GetStringRef().starts_with(
            g_plugin_prefix))
      return FileSystem::eEnumerateDirectoryResultNext;

    // Don't try to load an already loaded plugin again.
    if (PluginIsLoaded(plugin_file_spec))
      return FileSystem::eEnumerateDirectoryResultNext;

    llvm::Expected<PluginInfo> plugin_info =
        PluginInfo::Create(plugin_file_spec);
    if (plugin_info) {
      SetPluginInfo(plugin_file_spec, std::move(*plugin_info));
    } else {
      // Cache an empty plugin info so we don't try to load it again and again.
      SetPluginInfo(plugin_file_spec, PluginInfo());

      LLDB_LOG_ERROR(GetLog(LLDBLog::Host), plugin_info.takeError(),
                     "could not load plugin: {0}");
    }

    return FileSystem::eEnumerateDirectoryResultNext;
  }

  if (ft == fs::file_type::directory_file ||
      ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) {
    // Try and recurse into anything that a directory or symbolic link. We must
    // also do this for unknown as sometimes the directory enumeration might be
    // enumerating a file system that doesn't have correct file type
    // information.
    return FileSystem::eEnumerateDirectoryResultEnter;
  }

  return FileSystem::eEnumerateDirectoryResultNext;
}

void PluginManager::Initialize() {
  GetPluginRegistry().Initialize();

  static const bool find_directories = true;
  static const bool find_files = true;
  static const bool find_other = true;

  // Directories to scan for plugins. Unlike the plugin directories, which are
  // meant exclusively for LLDB, the shared library directory is likely to
  // contain unrelated shared libraries that we do not want to load. Therefore,
  // limit the scan to libraries that start with g_plugin_prefix.
  const std::array<PluginDir, 3> plugin_dirs = {
      PluginDir(HostInfo::GetShlibDir(), PluginDir::LoadOnlyWithLLDBPrefix),
      PluginDir(HostInfo::GetSystemPluginDir(), PluginDir::LoadAnyDylib),
      PluginDir(HostInfo::GetUserPluginDir(), PluginDir::LoadAnyDylib)};

  for (const PluginDir &plugin_dir : plugin_dirs) {
    if (plugin_dir) {
      FileSystem::Instance().EnumerateDirectory(
          plugin_dir.path.GetPath().c_str(), find_directories, find_files,
          find_other, LoadPluginCallback, (void *)&plugin_dir.policy);
    }
  }
}

void PluginManager::Terminate() { GetPluginRegistry().Terminate(); }

llvm::ArrayRef<PluginNamespace> PluginManager::GetPluginNamespaces() {
  static PluginNamespace PluginNamespaces[] = {

      {
          "abi",
          PluginManager::GetABIPluginInfo,
          PluginManager::SetABIPluginEnabled,
      },

      {
          "architecture",
          PluginManager::GetArchitecturePluginInfo,
          PluginManager::SetArchitecturePluginEnabled,
      },

      {
          "disassembler",
          PluginManager::GetDisassemblerPluginInfo,
          PluginManager::SetDisassemblerPluginEnabled,
      },

      {
          "dynamic-loader",
          PluginManager::GetDynamicLoaderPluginInfo,
          PluginManager::SetDynamicLoaderPluginEnabled,
      },

      {
          "emulate-instruction",
          PluginManager::GetEmulateInstructionPluginInfo,
          PluginManager::SetEmulateInstructionPluginEnabled,
      },

      {
          "instrumentation-runtime",
          PluginManager::GetInstrumentationRuntimePluginInfo,
          PluginManager::SetInstrumentationRuntimePluginEnabled,
      },

      {
          "jit-loader",
          PluginManager::GetJITLoaderPluginInfo,
          PluginManager::SetJITLoaderPluginEnabled,
      },

      {
          "language",
          PluginManager::GetLanguagePluginInfo,
          PluginManager::SetLanguagePluginEnabled,
      },

      {
          "language-runtime",
          PluginManager::GetLanguageRuntimePluginInfo,
          PluginManager::SetLanguageRuntimePluginEnabled,
      },

      {
          "memory-history",
          PluginManager::GetMemoryHistoryPluginInfo,
          PluginManager::SetMemoryHistoryPluginEnabled,
      },

      {
          "object-container",
          PluginManager::GetObjectContainerPluginInfo,
          PluginManager::SetObjectContainerPluginEnabled,
      },

      {
          "object-file",
          PluginManager::GetObjectFilePluginInfo,
          PluginManager::SetObjectFilePluginEnabled,
      },

      {
          "operating-system",
          PluginManager::GetOperatingSystemPluginInfo,
          PluginManager::SetOperatingSystemPluginEnabled,
      },

      {
          "platform",
          PluginManager::GetPlatformPluginInfo,
          PluginManager::SetPlatformPluginEnabled,
      },

      {
          "process",
          PluginManager::GetProcessPluginInfo,
          PluginManager::SetProcessPluginEnabled,
      },

      {
          "repl",
          PluginManager::GetREPLPluginInfo,
          PluginManager::SetREPLPluginEnabled,
      },

      {
          "register-type-builder",
          PluginManager::GetRegisterTypeBuilderPluginInfo,
          PluginManager::SetRegisterTypeBuilderPluginEnabled,
      },

      {
          "script-interpreter",
          PluginManager::GetScriptInterpreterPluginInfo,
          PluginManager::SetScriptInterpreterPluginEnabled,
      },

      {
          "scripted-interface",
          PluginManager::GetScriptedInterfacePluginInfo,
          PluginManager::SetScriptedInterfacePluginEnabled,
      },

      {
          "structured-data",
          PluginManager::GetStructuredDataPluginInfo,
          PluginManager::SetStructuredDataPluginEnabled,
      },

      {
          "symbol-file",
          PluginManager::GetSymbolFilePluginInfo,
          PluginManager::SetSymbolFilePluginEnabled,
      },

      {
          "symbol-locator",
          PluginManager::GetSymbolLocatorPluginInfo,
          PluginManager::SetSymbolLocatorPluginEnabled,
      },

      {
          "symbol-vendor",
          PluginManager::GetSymbolVendorPluginInfo,
          PluginManager::SetSymbolVendorPluginEnabled,
      },

      {
          "system-runtime",
          PluginManager::GetSystemRuntimePluginInfo,
          PluginManager::SetSystemRuntimePluginEnabled,
      },

      {
          "trace",
          PluginManager::GetTracePluginInfo,
          PluginManager::SetTracePluginEnabled,
      },

      {
          "trace-exporter",
          PluginManager::GetTraceExporterPluginInfo,
          PluginManager::SetTraceExporterPluginEnabled,
      },

      {
          "type-system",
          PluginManager::GetTypeSystemPluginInfo,
          PluginManager::SetTypeSystemPluginEnabled,
      },

      {
          "unwind-assembly",
          PluginManager::GetUnwindAssemblyPluginInfo,
          PluginManager::SetUnwindAssemblyPluginEnabled,
      },
  };

  return PluginNamespaces;
}

llvm::json::Object PluginManager::GetJSON(llvm::StringRef pattern) {
  llvm::json::Object plugin_stats;

  for (const PluginNamespace &plugin_ns : GetPluginNamespaces()) {
    llvm::json::Array namespace_stats;

    for (const RegisteredPluginInfo &plugin : plugin_ns.get_info()) {
      if (MatchPluginName(pattern, plugin_ns, plugin)) {
        llvm::json::Object plugin_json;
        plugin_json.try_emplace("name", plugin.name);
        plugin_json.try_emplace("enabled", plugin.enabled);
        namespace_stats.emplace_back(std::move(plugin_json));
      }
    }
    if (!namespace_stats.empty())
      plugin_stats.try_emplace(plugin_ns.name, std::move(namespace_stats));
  }

  return plugin_stats;
}

bool PluginManager::MatchPluginName(llvm::StringRef pattern,
                                    const PluginNamespace &plugin_ns,
                                    const RegisteredPluginInfo &plugin_info) {
  // The empty pattern matches all plugins.
  if (pattern.empty())
    return true;

  // Check if the pattern matches the namespace.
  if (pattern == plugin_ns.name)
    return true;

  // Check if the pattern matches the qualified name.
  std::string qualified_name = (plugin_ns.name + "." + plugin_info.name).str();
  return pattern == qualified_name;
}

template <typename Callback> struct PluginInstance {
  typedef Callback CallbackType;

  PluginInstance() = default;
  PluginInstance(llvm::StringRef name, llvm::StringRef description,
                 Callback create_callback,
                 DebuggerInitializeCallback debugger_init_callback = nullptr)
      : name(name), description(description), enabled(true),
        create_callback(create_callback),
        debugger_init_callback(debugger_init_callback) {}

  llvm::StringRef name;
  llvm::StringRef description;
  bool enabled;
  Callback create_callback;
  DebuggerInitializeCallback debugger_init_callback;
};

template <typename Instance> class PluginInstances {
public:
  ~PluginInstances() {
    // Only meaningful after a real teardown; see PluginRegistry::IsTerminated.
    if (!GetPluginRegistry().IsTerminated())
      return;
#ifndef NDEBUG
    for (const auto &instance : m_instances)
      llvm::errs() << llvm::formatv("Use `image lookup -va {0:x}` to find out "
                                    "which callback was not removed\n",
                                    instance.create_callback);
#endif
    assert(m_instances.empty() && "forgot to unregister plugin?");
  }

  template <typename... Args>
  bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
                      typename Instance::CallbackType callback,
                      Args &&...args) {
    if (!callback)
      return false;
    assert(!name.empty());

    std::lock_guard<std::mutex> guard(m_mutex);
    m_instances.emplace_back(name, description, callback,
                             std::forward<Args>(args)...);
    return true;
  }

  bool UnregisterPlugin(typename Instance::CallbackType callback) {
    if (!callback)
      return false;

    std::lock_guard<std::mutex> guard(m_mutex);
    auto pos = m_instances.begin();
    auto end = m_instances.end();
    for (; pos != end; ++pos) {
      if (pos->create_callback == callback) {
        m_instances.erase(pos);
        return true;
      }
    }
    return false;
  }

  llvm::StringRef GetDescriptionAtIndex(uint32_t idx) {
    if (auto instance = GetInstanceAtIndex(idx))
      return instance->description;
    return "";
  }

  llvm::StringRef GetNameAtIndex(uint32_t idx) {
    if (auto instance = GetInstanceAtIndex(idx))
      return instance->name;
    return "";
  }

  typename Instance::CallbackType GetCallbackForName(llvm::StringRef name) {
    if (auto instance = GetInstanceForName(name))
      return instance->create_callback;
    return nullptr;
  }

  llvm::SmallVector<typename Instance::CallbackType> GetCreateCallbacks() {
    llvm::SmallVector<Instance> snapshot = GetSnapshot();
    llvm::SmallVector<typename Instance::CallbackType> result;
    result.reserve(snapshot.size());
    for (const auto &instance : snapshot)
      result.push_back(instance.create_callback);
    return result;
  }

  void PerformDebuggerCallback(Debugger &debugger) {
    for (const auto &instance : GetSnapshot()) {
      if (instance.debugger_init_callback)
        instance.debugger_init_callback(debugger);
    }
  }

  // Return a copy of all the enabled instances.
  // Note that this is a copy of the internal state so modifications
  // to the returned instances will not be reflected back to instances
  // stored by the PluginInstances object.
  llvm::SmallVector<Instance> GetSnapshot(bool enabled_only = true) const {
    std::lock_guard<std::mutex> guard(m_mutex);

    llvm::SmallVector<Instance> enabled_instances;
    enabled_instances.reserve(m_instances.size());
    for (const auto &instance : m_instances) {
      if (!enabled_only || instance.enabled)
        enabled_instances.push_back(instance);
    }
    return enabled_instances;
  }

  std::optional<Instance> GetInstanceAtIndex(uint32_t idx) {
    uint32_t count = 0;

    return FindEnabledInstance(
        [&](const Instance &instance) { return count++ == idx; });
  }

  std::optional<Instance> GetInstanceForName(llvm::StringRef name,
                                             bool enabled_only = true) {
    if (name.empty())
      return std::nullopt;

    auto predicate = [&](const Instance &instance) {
      return instance.name == name;
    };
    if (enabled_only)
      return FindEnabledInstance(predicate);

    return FindInstance(predicate);
  }

  std::optional<Instance>
  FindEnabledInstance(std::function<bool(const Instance &)> predicate) const {
    for (const auto &instance : GetSnapshot()) {
      if (predicate(instance))
        return instance;
    }
    return std::nullopt;
  }

  std::optional<Instance>
  FindInstance(std::function<bool(const Instance &)> predicate) const {
    std::lock_guard<std::mutex> guard(m_mutex);
    for (const auto &instance : m_instances) {
      if (predicate(instance))
        return instance;
    }
    return std::nullopt;
  }

  // Return a list of all the registered plugin instances. This includes both
  // enabled and disabled instances. The instances are listed in the order they
  // were registered which is the order they would be queried if they were all
  // enabled.
  llvm::SmallVector<RegisteredPluginInfo> GetPluginInfoForAllInstances() {
    std::lock_guard<std::mutex> guard(m_mutex);

    // Lookup the plugin info for each instance in the sorted order.
    llvm::SmallVector<RegisteredPluginInfo> plugin_infos;
    plugin_infos.reserve(m_instances.size());

    for (const Instance &instance : m_instances)
      plugin_infos.push_back(
          {instance.name, instance.description, instance.enabled});

    return plugin_infos;
  }

  bool SetInstanceEnabled(llvm::StringRef name, bool enable) {
    std::lock_guard<std::mutex> guard(m_mutex);
    auto it = llvm::find_if(m_instances, [&](const Instance &instance) {
      return instance.name == name;
    });

    if (it == m_instances.end())
      return false;

    it->enabled = enable;
    return true;
  }

private:
  mutable std::mutex m_mutex;
  llvm::SmallVector<Instance> m_instances;
};

#pragma mark ABI

typedef PluginInstance<ABICreateInstance> ABIInstance;
typedef PluginInstances<ABIInstance> ABIInstances;

static ABIInstances &GetABIInstances() {
  static ABIInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(llvm::StringRef name,
                                   llvm::StringRef description,
                                   ABICreateInstance create_callback) {
  return GetABIInstances().RegisterPlugin(name, description, create_callback);
}

bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
  return GetABIInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<ABICreateInstance> PluginManager::GetABICreateCallbacks() {
  return GetABIInstances().GetCreateCallbacks();
}

#pragma mark Architecture

typedef PluginInstance<ArchitectureCreateInstance> ArchitectureInstance;
typedef PluginInstances<ArchitectureInstance> ArchitectureInstances;

static ArchitectureInstances &GetArchitectureInstances() {
  static ArchitectureInstances g_instances;
  return g_instances;
}

void PluginManager::RegisterPlugin(llvm::StringRef name,
                                   llvm::StringRef description,
                                   ArchitectureCreateInstance create_callback) {
  GetArchitectureInstances().RegisterPlugin(name, description, create_callback);
}

void PluginManager::UnregisterPlugin(
    ArchitectureCreateInstance create_callback) {
  auto &instances = GetArchitectureInstances();
  instances.UnregisterPlugin(create_callback);
}

std::unique_ptr<Architecture>
PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
  for (const auto &instances : GetArchitectureInstances().GetSnapshot()) {
    if (auto plugin_up = instances.create_callback(arch))
      return plugin_up;
  }
  return nullptr;
}

#pragma mark Disassembler

typedef PluginInstance<DisassemblerCreateInstance> DisassemblerInstance;
typedef PluginInstances<DisassemblerInstance> DisassemblerInstances;

static DisassemblerInstances &GetDisassemblerInstances() {
  static DisassemblerInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(llvm::StringRef name,
                                   llvm::StringRef description,
                                   DisassemblerCreateInstance create_callback) {
  return GetDisassemblerInstances().RegisterPlugin(name, description,
                                                   create_callback);
}

bool PluginManager::UnregisterPlugin(
    DisassemblerCreateInstance create_callback) {
  return GetDisassemblerInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<DisassemblerCreateInstance>
PluginManager::GetDisassemblerCreateCallbacks() {
  return GetDisassemblerInstances().GetCreateCallbacks();
}

DisassemblerCreateInstance
PluginManager::GetDisassemblerCreateCallbackForPluginName(
    llvm::StringRef name) {
  return GetDisassemblerInstances().GetCallbackForName(name);
}

#pragma mark DynamicLoader

typedef PluginInstance<DynamicLoaderCreateInstance> DynamicLoaderInstance;
typedef PluginInstances<DynamicLoaderInstance> DynamicLoaderInstances;

static DynamicLoaderInstances &GetDynamicLoaderInstances() {
  static DynamicLoaderInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    DynamicLoaderCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback) {
  return GetDynamicLoaderInstances().RegisterPlugin(
      name, description, create_callback, debugger_init_callback);
}

bool PluginManager::UnregisterPlugin(
    DynamicLoaderCreateInstance create_callback) {
  return GetDynamicLoaderInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<DynamicLoaderCreateInstance>
PluginManager::GetDynamicLoaderCreateCallbacks() {
  return GetDynamicLoaderInstances().GetCreateCallbacks();
}

DynamicLoaderCreateInstance
PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
    llvm::StringRef name) {
  return GetDynamicLoaderInstances().GetCallbackForName(name);
}

#pragma mark JITLoader

typedef PluginInstance<JITLoaderCreateInstance> JITLoaderInstance;
typedef PluginInstances<JITLoaderInstance> JITLoaderInstances;

static JITLoaderInstances &GetJITLoaderInstances() {
  static JITLoaderInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    JITLoaderCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback) {
  return GetJITLoaderInstances().RegisterPlugin(
      name, description, create_callback, debugger_init_callback);
}

bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
  return GetJITLoaderInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<JITLoaderCreateInstance>
PluginManager::GetJITLoaderCreateCallbacks() {
  return GetJITLoaderInstances().GetCreateCallbacks();
}

#pragma mark EmulateInstruction

typedef PluginInstance<EmulateInstructionCreateInstance>
    EmulateInstructionInstance;
typedef PluginInstances<EmulateInstructionInstance> EmulateInstructionInstances;

static EmulateInstructionInstances &GetEmulateInstructionInstances() {
  static EmulateInstructionInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    EmulateInstructionCreateInstance create_callback) {
  return GetEmulateInstructionInstances().RegisterPlugin(name, description,
                                                         create_callback);
}

bool PluginManager::UnregisterPlugin(
    EmulateInstructionCreateInstance create_callback) {
  return GetEmulateInstructionInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<EmulateInstructionCreateInstance>
PluginManager::GetEmulateInstructionCreateCallbacks() {
  return GetEmulateInstructionInstances().GetCreateCallbacks();
}

EmulateInstructionCreateInstance
PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
    llvm::StringRef name) {
  return GetEmulateInstructionInstances().GetCallbackForName(name);
}

#pragma mark OperatingSystem

typedef PluginInstance<OperatingSystemCreateInstance> OperatingSystemInstance;
typedef PluginInstances<OperatingSystemInstance> OperatingSystemInstances;

static OperatingSystemInstances &GetOperatingSystemInstances() {
  static OperatingSystemInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    OperatingSystemCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback) {
  return GetOperatingSystemInstances().RegisterPlugin(
      name, description, create_callback, debugger_init_callback);
}

bool PluginManager::UnregisterPlugin(
    OperatingSystemCreateInstance create_callback) {
  return GetOperatingSystemInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<OperatingSystemCreateInstance>
PluginManager::GetOperatingSystemCreateCallbacks() {
  return GetOperatingSystemInstances().GetCreateCallbacks();
}

OperatingSystemCreateInstance
PluginManager::GetOperatingSystemCreateCallbackForPluginName(
    llvm::StringRef name) {
  return GetOperatingSystemInstances().GetCallbackForName(name);
}

#pragma mark Language

typedef PluginInstance<LanguageCreateInstance> LanguageInstance;
typedef PluginInstances<LanguageInstance> LanguageInstances;

static LanguageInstances &GetLanguageInstances() {
  static LanguageInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    LanguageCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback) {
  return GetLanguageInstances().RegisterPlugin(
      name, description, create_callback, debugger_init_callback);
}

bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
  return GetLanguageInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<LanguageCreateInstance>
PluginManager::GetLanguageCreateCallbacks() {
  return GetLanguageInstances().GetCreateCallbacks();
}

#pragma mark LanguageRuntime

struct LanguageRuntimeInstance
    : public PluginInstance<LanguageRuntimeCreateInstance> {
  LanguageRuntimeInstance(
      llvm::StringRef name, llvm::StringRef description,
      CallbackType create_callback,
      DebuggerInitializeCallback debugger_init_callback,
      LanguageRuntimeGetCommandObject command_callback,
      LanguageRuntimeGetExceptionPrecondition precondition_callback)
      : PluginInstance<LanguageRuntimeCreateInstance>(
            name, description, create_callback, debugger_init_callback),
        command_callback(command_callback),
        precondition_callback(precondition_callback) {}

  LanguageRuntimeGetCommandObject command_callback;
  LanguageRuntimeGetExceptionPrecondition precondition_callback;
};

typedef PluginInstances<LanguageRuntimeInstance> LanguageRuntimeInstances;

static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
  static LanguageRuntimeInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    LanguageRuntimeCreateInstance create_callback,
    LanguageRuntimeGetCommandObject command_callback,
    LanguageRuntimeGetExceptionPrecondition precondition_callback) {
  return GetLanguageRuntimeInstances().RegisterPlugin(
      name, description, create_callback, nullptr, command_callback,
      precondition_callback);
}

bool PluginManager::UnregisterPlugin(
    LanguageRuntimeCreateInstance create_callback) {
  return GetLanguageRuntimeInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<LanguageRuntimeCallbacks>
PluginManager::GetLanguageRuntimeCallbacks() {
  auto instances = GetLanguageRuntimeInstances().GetSnapshot();
  llvm::SmallVector<LanguageRuntimeCallbacks> result;
  result.reserve(instances.size());
  for (auto &instance : instances)
    result.push_back({instance.create_callback, instance.command_callback,
                      instance.precondition_callback});
  return result;
}

#pragma mark SystemRuntime

typedef PluginInstance<SystemRuntimeCreateInstance> SystemRuntimeInstance;
typedef PluginInstances<SystemRuntimeInstance> SystemRuntimeInstances;

static SystemRuntimeInstances &GetSystemRuntimeInstances() {
  static SystemRuntimeInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    SystemRuntimeCreateInstance create_callback) {
  return GetSystemRuntimeInstances().RegisterPlugin(name, description,
                                                    create_callback);
}

bool PluginManager::UnregisterPlugin(
    SystemRuntimeCreateInstance create_callback) {
  return GetSystemRuntimeInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<SystemRuntimeCreateInstance>
PluginManager::GetSystemRuntimeCreateCallbacks() {
  return GetSystemRuntimeInstances().GetCreateCallbacks();
}

#pragma mark ObjectFile

struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> {
  ObjectFileInstance(
      llvm::StringRef name, llvm::StringRef description,
      CallbackType create_callback,
      ObjectFileCreateMemoryInstance create_memory_callback,
      ObjectFileGetModuleSpecifications get_module_specifications,
      ObjectFileSaveCore save_core,
      DebuggerInitializeCallback debugger_init_callback)
      : PluginInstance<ObjectFileCreateInstance>(
            name, description, create_callback, debugger_init_callback),
        create_memory_callback(create_memory_callback),
        get_module_specifications(get_module_specifications),
        save_core(save_core) {}

  ObjectFileCreateMemoryInstance create_memory_callback;
  ObjectFileGetModuleSpecifications get_module_specifications;
  ObjectFileSaveCore save_core;
};
typedef PluginInstances<ObjectFileInstance> ObjectFileInstances;

static ObjectFileInstances &GetObjectFileInstances() {
  static ObjectFileInstances g_instances;
  return g_instances;
}

bool PluginManager::IsRegisteredObjectFilePluginName(llvm::StringRef name) {
  if (name.empty())
    return false;

  return GetObjectFileInstances().GetInstanceForName(name).has_value();
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    ObjectFileCreateInstance create_callback,
    ObjectFileCreateMemoryInstance create_memory_callback,
    ObjectFileGetModuleSpecifications get_module_specifications,
    ObjectFileSaveCore save_core,
    DebuggerInitializeCallback debugger_init_callback) {
  return GetObjectFileInstances().RegisterPlugin(
      name, description, create_callback, create_memory_callback,
      get_module_specifications, save_core, debugger_init_callback);
}

bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
  return GetObjectFileInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<ObjectFileCallbacks> PluginManager::GetObjectFileCallbacks() {
  auto instances = GetObjectFileInstances().GetSnapshot();
  llvm::SmallVector<ObjectFileCallbacks> result;
  result.reserve(instances.size());
  for (auto &instance : instances)
    result.push_back({instance.create_callback, instance.create_memory_callback,
                      instance.get_module_specifications, instance.save_core});
  return result;
}

ObjectFileCreateMemoryInstance
PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
    llvm::StringRef name) {
  if (auto instance = GetObjectFileInstances().GetInstanceForName(name))
    return instance->create_memory_callback;
  return nullptr;
}

Status PluginManager::SaveCore(lldb_private::SaveCoreOptions &options) {
  Status error;
  if (!options.GetOutputFile()) {
    error = Status::FromErrorString("No output file specified");
    return error;
  }

  if (!options.GetProcess()) {
    error = Status::FromErrorString("Invalid process");
    return error;
  }

  error = options.EnsureValidConfiguration();
  if (error.Fail())
    return error;

  if (!options.GetPluginName().has_value()) {
    // Try saving core directly from the process plugin first.
    llvm::Expected<bool> ret =
        options.GetProcess()->SaveCore(options.GetOutputFile()->GetPath());
    if (!ret)
      return Status::FromError(ret.takeError());
    if (ret.get())
      return Status();
  }

  // Fall back to object plugins.
  const auto &plugin_name = options.GetPluginName().value_or("");
  auto instances = GetObjectFileInstances().GetSnapshot();
  for (auto &instance : instances) {
    if (plugin_name.empty() || instance.name == plugin_name) {
      // TODO: Refactor the instance.save_core() to not require a process and
      // get it from options instead.
      if (instance.save_core &&
          instance.save_core(options.GetProcess(), options, error))
        return error;
    }
  }

  // Check to see if any of the object file plugins tried and failed to save.
  // if any failure, return the error message.
  if (error.Fail())
    return error;

  // Report only for the plugin that was specified.
  if (!plugin_name.empty())
    return Status::FromErrorStringWithFormatv(
        "The \"{}\" plugin is not able to save a core for this process.",
        plugin_name);

  return Status::FromErrorString(
      "no ObjectFile plugins were able to save a core for this process");
}

llvm::SmallVector<llvm::StringRef> PluginManager::GetSaveCorePluginNames() {
  llvm::SmallVector<llvm::StringRef> plugin_names;
  auto instances = GetObjectFileInstances().GetSnapshot();
  for (auto &instance : instances) {
    if (instance.save_core)
      plugin_names.emplace_back(instance.name);
  }
  return plugin_names;
}

#pragma mark ObjectContainer

struct ObjectContainerInstance
    : public PluginInstance<ObjectContainerCreateInstance> {
  ObjectContainerInstance(
      llvm::StringRef name, llvm::StringRef description,
      CallbackType create_callback,
      ObjectContainerCreateMemoryInstance create_memory_callback,
      ObjectFileGetModuleSpecifications get_module_specifications)
      : PluginInstance<ObjectContainerCreateInstance>(name, description,
                                                      create_callback),
        create_memory_callback(create_memory_callback),
        get_module_specifications(get_module_specifications) {}

  ObjectContainerCreateMemoryInstance create_memory_callback;
  ObjectFileGetModuleSpecifications get_module_specifications;
};
typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances;

static ObjectContainerInstances &GetObjectContainerInstances() {
  static ObjectContainerInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    ObjectContainerCreateInstance create_callback,
    ObjectFileGetModuleSpecifications get_module_specifications,
    ObjectContainerCreateMemoryInstance create_memory_callback) {
  return GetObjectContainerInstances().RegisterPlugin(
      name, description, create_callback, create_memory_callback,
      get_module_specifications);
}

bool PluginManager::UnregisterPlugin(
    ObjectContainerCreateInstance create_callback) {
  return GetObjectContainerInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<ObjectContainerCallbacks>
PluginManager::GetObjectContainerCallbacks() {
  auto instances = GetObjectContainerInstances().GetSnapshot();
  llvm::SmallVector<ObjectContainerCallbacks> result;
  result.reserve(instances.size());
  for (auto &instance : instances)
    result.push_back({instance.create_callback, instance.create_memory_callback,
                      instance.get_module_specifications});
  return result;
}

#pragma mark Platform

typedef PluginInstance<PlatformCreateInstance> PlatformInstance;
typedef PluginInstances<PlatformInstance> PlatformInstances;

static PlatformInstances &GetPlatformInstances() {
  static PlatformInstances g_platform_instances;
  return g_platform_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    PlatformCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback) {
  return GetPlatformInstances().RegisterPlugin(
      name, description, create_callback, debugger_init_callback);
}

bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
  return GetPlatformInstances().UnregisterPlugin(create_callback);
}

llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
  return GetPlatformInstances().GetNameAtIndex(idx);
}

llvm::StringRef
PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
  return GetPlatformInstances().GetDescriptionAtIndex(idx);
}

PlatformCreateInstance
PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) {
  return GetPlatformInstances().GetCallbackForName(name);
}

llvm::SmallVector<PlatformCreateInstance>
PluginManager::GetPlatformCreateCallbacks() {
  return GetPlatformInstances().GetCreateCallbacks();
}

void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
                                             CompletionRequest &request) {
  for (const auto &instance : GetPlatformInstances().GetSnapshot()) {
    if (instance.name.starts_with(name))
      request.AddCompletion(instance.name);
  }
}

#pragma mark Process

typedef PluginInstance<ProcessCreateInstance> ProcessInstance;
typedef PluginInstances<ProcessInstance> ProcessInstances;

static ProcessInstances &GetProcessInstances() {
  static ProcessInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    ProcessCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback) {
  return GetProcessInstances().RegisterPlugin(
      name, description, create_callback, debugger_init_callback);
}

bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
  return GetProcessInstances().UnregisterPlugin(create_callback);
}

llvm::StringRef PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
  return GetProcessInstances().GetNameAtIndex(idx);
}

llvm::StringRef
PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
  return GetProcessInstances().GetDescriptionAtIndex(idx);
}

ProcessCreateInstance
PluginManager::GetProcessCreateCallbackForPluginName(llvm::StringRef name) {
  return GetProcessInstances().GetCallbackForName(name);
}

llvm::SmallVector<ProcessCreateInstance>
PluginManager::GetProcessCreateCallbacks() {
  return GetProcessInstances().GetCreateCallbacks();
}

void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
                                            CompletionRequest &request) {
  for (const auto &instance : GetProcessInstances().GetSnapshot()) {
    if (instance.name.starts_with(name))
      request.AddCompletion(instance.name, instance.description);
  }
}

#pragma mark ProtocolServer

typedef PluginInstance<ProtocolServerCreateInstance> ProtocolServerInstance;
typedef PluginInstances<ProtocolServerInstance> ProtocolServerInstances;

static ProtocolServerInstances &GetProtocolServerInstances() {
  static ProtocolServerInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    ProtocolServerCreateInstance create_callback) {
  return GetProtocolServerInstances().RegisterPlugin(name, description,
                                                     create_callback);
}

bool PluginManager::UnregisterPlugin(
    ProtocolServerCreateInstance create_callback) {
  return GetProtocolServerInstances().UnregisterPlugin(create_callback);
}

llvm::StringRef
PluginManager::GetProtocolServerPluginNameAtIndex(uint32_t idx) {
  return GetProtocolServerInstances().GetNameAtIndex(idx);
}

ProtocolServerCreateInstance
PluginManager::GetProtocolCreateCallbackForPluginName(llvm::StringRef name) {
  return GetProtocolServerInstances().GetCallbackForName(name);
}

#pragma mark RegisterTypeBuilder

struct RegisterTypeBuilderInstance
    : public PluginInstance<RegisterTypeBuilderCreateInstance> {
  RegisterTypeBuilderInstance(llvm::StringRef name, llvm::StringRef description,
                              CallbackType create_callback)
      : PluginInstance<RegisterTypeBuilderCreateInstance>(name, description,
                                                          create_callback) {}
};

typedef PluginInstances<RegisterTypeBuilderInstance>
    RegisterTypeBuilderInstances;

static RegisterTypeBuilderInstances &GetRegisterTypeBuilderInstances() {
  static RegisterTypeBuilderInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    RegisterTypeBuilderCreateInstance create_callback) {
  return GetRegisterTypeBuilderInstances().RegisterPlugin(name, description,
                                                          create_callback);
}

bool PluginManager::UnregisterPlugin(
    RegisterTypeBuilderCreateInstance create_callback) {
  return GetRegisterTypeBuilderInstances().UnregisterPlugin(create_callback);
}

lldb::RegisterTypeBuilderSP
PluginManager::GetRegisterTypeBuilder(Target &target) {
  // We assume that RegisterTypeBuilderClang is the only instance of this plugin
  // type and is always present.
  auto instance = GetRegisterTypeBuilderInstances().GetInstanceAtIndex(0);
  assert(instance);
  return instance->create_callback(target);
}

#pragma mark ScriptInterpreter

struct ScriptInterpreterInstance
    : public PluginInstance<ScriptInterpreterCreateInstance> {
  ScriptInterpreterInstance(llvm::StringRef name, llvm::StringRef description,
                            CallbackType create_callback,
                            lldb::ScriptLanguage language,
                            ScriptInterpreterGetPath get_path_callback)
      : PluginInstance<ScriptInterpreterCreateInstance>(name, description,
                                                        create_callback),
        language(language), get_path_callback(get_path_callback) {}

  lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
  ScriptInterpreterGetPath get_path_callback = nullptr;
};

typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances;

static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
  static ScriptInterpreterInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    lldb::ScriptLanguage script_language,
    ScriptInterpreterCreateInstance create_callback,
    ScriptInterpreterGetPath get_path_callback) {
  return GetScriptInterpreterInstances().RegisterPlugin(
      name, description, create_callback, script_language, get_path_callback);
}

bool PluginManager::UnregisterPlugin(
    ScriptInterpreterCreateInstance create_callback) {
  return GetScriptInterpreterInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<ScriptInterpreterCreateInstance>
PluginManager::GetScriptInterpreterCreateCallbacks() {
  return GetScriptInterpreterInstances().GetCreateCallbacks();
}

lldb::ScriptInterpreterSP
PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
                                               Debugger &debugger) {
  const auto instances = GetScriptInterpreterInstances().GetSnapshot();
  ScriptInterpreterCreateInstance none_instance = nullptr;
  for (const auto &instance : instances) {
    if (instance.language == lldb::eScriptLanguageNone)
      none_instance = instance.create_callback;

    if (script_lang == instance.language)
      return instance.create_callback(debugger);
  }

  // If we didn't find one, return the ScriptInterpreter for the null language.
  assert(none_instance != nullptr);
  return none_instance(debugger);
}

FileSpec PluginManager::GetScriptInterpreterLibraryPath(
    lldb::ScriptLanguage script_lang) {
  const auto instances = GetScriptInterpreterInstances().GetSnapshot();
  for (const auto &instance : instances) {
    if (instance.language == script_lang && instance.get_path_callback)
      return instance.get_path_callback();
  }
  return FileSpec();
}

#pragma mark SyntheticFrameProvider

typedef PluginInstance<SyntheticFrameProviderCreateInstance>
    SyntheticFrameProviderInstance;
typedef PluginInstance<ScriptedFrameProviderCreateInstance>
    ScriptedFrameProviderInstance;
typedef PluginInstances<SyntheticFrameProviderInstance>
    SyntheticFrameProviderInstances;
typedef PluginInstances<ScriptedFrameProviderInstance>
    ScriptedFrameProviderInstances;

static SyntheticFrameProviderInstances &GetSyntheticFrameProviderInstances() {
  static SyntheticFrameProviderInstances g_instances;
  return g_instances;
}

static ScriptedFrameProviderInstances &GetScriptedFrameProviderInstances() {
  static ScriptedFrameProviderInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    SyntheticFrameProviderCreateInstance create_native_callback,
    ScriptedFrameProviderCreateInstance create_scripted_callback) {
  if (create_native_callback)
    return GetSyntheticFrameProviderInstances().RegisterPlugin(
        name, description, create_native_callback);
  else if (create_scripted_callback)
    return GetScriptedFrameProviderInstances().RegisterPlugin(
        name, description, create_scripted_callback);
  return false;
}

bool PluginManager::UnregisterPlugin(
    SyntheticFrameProviderCreateInstance create_callback) {
  return GetSyntheticFrameProviderInstances().UnregisterPlugin(create_callback);
}

bool PluginManager::UnregisterPlugin(
    ScriptedFrameProviderCreateInstance create_callback) {
  return GetScriptedFrameProviderInstances().UnregisterPlugin(create_callback);
}

SyntheticFrameProviderCreateInstance
PluginManager::GetSyntheticFrameProviderCreateCallbackForPluginName(
    llvm::StringRef name) {
  return GetSyntheticFrameProviderInstances().GetCallbackForName(name);
}

llvm::SmallVector<ScriptedFrameProviderCreateInstance>
PluginManager::GetScriptedFrameProviderCreateCallbacks() {
  return GetScriptedFrameProviderInstances().GetCreateCallbacks();
}

#pragma mark StructuredDataPlugin

struct StructuredDataPluginInstance
    : public PluginInstance<StructuredDataPluginCreateInstance> {
  StructuredDataPluginInstance(
      llvm::StringRef name, llvm::StringRef description,
      CallbackType create_callback,
      DebuggerInitializeCallback debugger_init_callback,
      StructuredDataFilterLaunchInfo filter_callback)
      : PluginInstance<StructuredDataPluginCreateInstance>(
            name, description, create_callback, debugger_init_callback),
        filter_callback(filter_callback) {}

  StructuredDataFilterLaunchInfo filter_callback = nullptr;
};

typedef PluginInstances<StructuredDataPluginInstance>
    StructuredDataPluginInstances;

static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
  static StructuredDataPluginInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    StructuredDataPluginCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback,
    StructuredDataFilterLaunchInfo filter_callback) {
  return GetStructuredDataPluginInstances().RegisterPlugin(
      name, description, create_callback, debugger_init_callback,
      filter_callback);
}

bool PluginManager::UnregisterPlugin(
    StructuredDataPluginCreateInstance create_callback) {
  return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<StructuredDataPluginCallbacks>
PluginManager::GetStructuredDataPluginCallbacks() {
  auto instances = GetStructuredDataPluginInstances().GetSnapshot();
  llvm::SmallVector<StructuredDataPluginCallbacks> result;
  result.reserve(instances.size());
  for (auto &instance : instances)
    result.push_back({instance.create_callback, instance.filter_callback});
  return result;
}

#pragma mark SymbolFile

typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance;
typedef PluginInstances<SymbolFileInstance> SymbolFileInstances;

static SymbolFileInstances &GetSymbolFileInstances() {
  static SymbolFileInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    SymbolFileCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback) {
  return GetSymbolFileInstances().RegisterPlugin(
      name, description, create_callback, debugger_init_callback);
}

bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
  return GetSymbolFileInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<SymbolFileCreateInstance>
PluginManager::GetSymbolFileCreateCallbacks() {
  return GetSymbolFileInstances().GetCreateCallbacks();
}

#pragma mark SymbolVendor

typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance;
typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances;

static SymbolVendorInstances &GetSymbolVendorInstances() {
  static SymbolVendorInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(llvm::StringRef name,
                                   llvm::StringRef description,
                                   SymbolVendorCreateInstance create_callback) {
  return GetSymbolVendorInstances().RegisterPlugin(name, description,
                                                   create_callback);
}

bool PluginManager::UnregisterPlugin(
    SymbolVendorCreateInstance create_callback) {
  return GetSymbolVendorInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<SymbolVendorCreateInstance>
PluginManager::GetSymbolVendorCreateCallbacks() {
  return GetSymbolVendorInstances().GetCreateCallbacks();
}

#pragma mark SymbolLocator

struct SymbolLocatorInstance
    : public PluginInstance<SymbolLocatorCreateInstance> {
  SymbolLocatorInstance(
      llvm::StringRef name, llvm::StringRef description,
      CallbackType create_callback,
      SymbolLocatorLocateExecutableObjectFile locate_executable_object_file,
      SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file,
      SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,
      SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,
      DebuggerInitializeCallback debugger_init_callback)
      : PluginInstance<SymbolLocatorCreateInstance>(
            name, description, create_callback, debugger_init_callback),
        locate_executable_object_file(locate_executable_object_file),
        locate_executable_symbol_file(locate_executable_symbol_file),
        download_object_symbol_file(download_object_symbol_file),
        find_symbol_file_in_bundle(find_symbol_file_in_bundle) {}

  SymbolLocatorLocateExecutableObjectFile locate_executable_object_file;
  SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file;
  SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file;
  SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle;
};
typedef PluginInstances<SymbolLocatorInstance> SymbolLocatorInstances;

static SymbolLocatorInstances &GetSymbolLocatorInstances() {
  static SymbolLocatorInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    SymbolLocatorCreateInstance create_callback,
    SymbolLocatorLocateExecutableObjectFile locate_executable_object_file,
    SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file,
    SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,
    SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,
    DebuggerInitializeCallback debugger_init_callback) {
  return GetSymbolLocatorInstances().RegisterPlugin(
      name, description, create_callback, locate_executable_object_file,
      locate_executable_symbol_file, download_object_symbol_file,
      find_symbol_file_in_bundle, debugger_init_callback);
}

bool PluginManager::UnregisterPlugin(
    SymbolLocatorCreateInstance create_callback) {
  return GetSymbolLocatorInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<SymbolLocatorCreateInstance>
PluginManager::GetSymbolLocatorCreateCallbacks() {
  return GetSymbolLocatorInstances().GetCreateCallbacks();
}

ModuleSpec
PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec,
                                          StatisticsMap &map) {
  auto instances = GetSymbolLocatorInstances().GetSnapshot();
  for (auto &instance : instances) {
    if (instance.locate_executable_object_file) {
      StatsDuration time;
      std::optional<ModuleSpec> result;
      {
        ElapsedTime elapsed(time);
        result = instance.locate_executable_object_file(module_spec);
      }
      map.add(instance.name, time.get().count());
      if (result)
        return *result;
    }
  }
  return {};
}

FileSpec PluginManager::LocateExecutableSymbolFile(
    const ModuleSpec &module_spec, const FileSpecList &default_search_paths,
    StatisticsMap &map) {
  auto instances = GetSymbolLocatorInstances().GetSnapshot();
  for (auto &instance : instances) {
    if (instance.locate_executable_symbol_file) {
      StatsDuration time;
      std::optional<FileSpec> result;
      {
        ElapsedTime elapsed(time);
        result = instance.locate_executable_symbol_file(module_spec,
                                                        default_search_paths);
      }
      map.add(instance.name, time.get().count());
      if (result)
        return *result;
    }
  }
  return {};
}

bool PluginManager::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
                                                Status &error,
                                                bool force_lookup,
                                                bool copy_executable) {
  auto instances = GetSymbolLocatorInstances().GetSnapshot();
  for (auto &instance : instances) {
    if (instance.download_object_symbol_file) {
      if (instance.download_object_symbol_file(module_spec, error, force_lookup,
                                               copy_executable))
        return true;
    }
  }
  return false;
}

FileSpec PluginManager::FindSymbolFileInBundle(const FileSpec &symfile_bundle,
                                               const UUID *uuid,
                                               const ArchSpec *arch) {
  auto instances = GetSymbolLocatorInstances().GetSnapshot();
  for (auto &instance : instances) {
    if (instance.find_symbol_file_in_bundle) {
      std::optional<FileSpec> result =
          instance.find_symbol_file_in_bundle(symfile_bundle, uuid, arch);
      if (result)
        return *result;
    }
  }
  return {};
}

#pragma mark Trace

struct TraceInstance : public PluginInstance<TraceCreateInstanceFromBundle> {
  TraceInstance(
      llvm::StringRef name, llvm::StringRef description,
      CallbackType create_callback_from_bundle,
      TraceCreateInstanceForLiveProcess create_callback_for_live_process,
      llvm::StringRef schema, DebuggerInitializeCallback debugger_init_callback)
      : PluginInstance<TraceCreateInstanceFromBundle>(
            name, description, create_callback_from_bundle,
            debugger_init_callback),
        schema(schema),
        create_callback_for_live_process(create_callback_for_live_process) {}

  llvm::StringRef schema;
  TraceCreateInstanceForLiveProcess create_callback_for_live_process;
};

typedef PluginInstances<TraceInstance> TraceInstances;

static TraceInstances &GetTracePluginInstances() {
  static TraceInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    TraceCreateInstanceFromBundle create_callback_from_bundle,
    TraceCreateInstanceForLiveProcess create_callback_for_live_process,
    llvm::StringRef schema, DebuggerInitializeCallback debugger_init_callback) {
  return GetTracePluginInstances().RegisterPlugin(
      name, description, create_callback_from_bundle,
      create_callback_for_live_process, schema, debugger_init_callback);
}

bool PluginManager::UnregisterPlugin(
    TraceCreateInstanceFromBundle create_callback_from_bundle) {
  return GetTracePluginInstances().UnregisterPlugin(
      create_callback_from_bundle);
}

TraceCreateInstanceFromBundle
PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) {
  return GetTracePluginInstances().GetCallbackForName(plugin_name);
}

TraceCreateInstanceForLiveProcess
PluginManager::GetTraceCreateCallbackForLiveProcess(
    llvm::StringRef plugin_name) {
  if (auto instance = GetTracePluginInstances().GetInstanceForName(plugin_name))
    return instance->create_callback_for_live_process;

  return nullptr;
}

llvm::StringRef PluginManager::GetTraceSchema(llvm::StringRef plugin_name) {
  if (auto instance = GetTracePluginInstances().GetInstanceForName(plugin_name))
    return instance->schema;
  return llvm::StringRef();
}

llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
  if (auto instance = GetTracePluginInstances().GetInstanceAtIndex(index))
    return instance->schema;
  return llvm::StringRef();
}

#pragma mark TraceExporter

struct TraceExporterInstance
    : public PluginInstance<TraceExporterCreateInstance> {
  TraceExporterInstance(
      llvm::StringRef name, llvm::StringRef description,
      TraceExporterCreateInstance create_instance,
      ThreadTraceExportCommandCreator create_thread_trace_export_command)
      : PluginInstance<TraceExporterCreateInstance>(name, description,
                                                    create_instance),
        create_thread_trace_export_command(create_thread_trace_export_command) {
  }

  ThreadTraceExportCommandCreator create_thread_trace_export_command;
};

typedef PluginInstances<TraceExporterInstance> TraceExporterInstances;

static TraceExporterInstances &GetTraceExporterInstances() {
  static TraceExporterInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    TraceExporterCreateInstance create_callback,
    ThreadTraceExportCommandCreator create_thread_trace_export_command) {
  return GetTraceExporterInstances().RegisterPlugin(
      name, description, create_callback, create_thread_trace_export_command);
}

TraceExporterCreateInstance
PluginManager::GetTraceExporterCreateCallback(llvm::StringRef plugin_name) {
  return GetTraceExporterInstances().GetCallbackForName(plugin_name);
}

bool PluginManager::UnregisterPlugin(
    TraceExporterCreateInstance create_callback) {
  return GetTraceExporterInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<TraceExporterCallbacks>
PluginManager::GetTraceExporterCallbacks() {
  auto instances = GetTraceExporterInstances().GetSnapshot();
  llvm::SmallVector<TraceExporterCallbacks> result;
  result.reserve(instances.size());
  for (auto &instance : instances)
    result.push_back({instance.name, instance.create_callback,
                      instance.create_thread_trace_export_command});
  return result;
}

#pragma mark UnwindAssembly

typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances;

static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
  static UnwindAssemblyInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    UnwindAssemblyCreateInstance create_callback) {
  return GetUnwindAssemblyInstances().RegisterPlugin(name, description,
                                                     create_callback);
}

bool PluginManager::UnregisterPlugin(
    UnwindAssemblyCreateInstance create_callback) {
  return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<UnwindAssemblyCreateInstance>
PluginManager::GetUnwindAssemblyCreateCallbacks() {
  return GetUnwindAssemblyInstances().GetCreateCallbacks();
}

#pragma mark MemoryHistory

typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance;
typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances;

static MemoryHistoryInstances &GetMemoryHistoryInstances() {
  static MemoryHistoryInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    MemoryHistoryCreateInstance create_callback) {
  return GetMemoryHistoryInstances().RegisterPlugin(name, description,
                                                    create_callback);
}

bool PluginManager::UnregisterPlugin(
    MemoryHistoryCreateInstance create_callback) {
  return GetMemoryHistoryInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<MemoryHistoryCreateInstance>
PluginManager::GetMemoryHistoryCreateCallbacks() {
  return GetMemoryHistoryInstances().GetCreateCallbacks();
}

#pragma mark InstrumentationRuntime

struct InstrumentationRuntimeInstance
    : public PluginInstance<InstrumentationRuntimeCreateInstance> {
  InstrumentationRuntimeInstance(
      llvm::StringRef name, llvm::StringRef description,
      CallbackType create_callback,
      InstrumentationRuntimeGetType get_type_callback)
      : PluginInstance<InstrumentationRuntimeCreateInstance>(name, description,
                                                             create_callback),
        get_type_callback(get_type_callback) {}

  InstrumentationRuntimeGetType get_type_callback = nullptr;
};

struct InstrumentationRuntimeInstances
    : public PluginInstances<InstrumentationRuntimeInstance> {

  InstrumentationRuntimeGetType GetTypeCallbackForName(llvm::StringRef name,
                                                       bool enabled_only) {
    if (auto instance = GetInstanceForName(name, enabled_only))
      return instance->get_type_callback;
    return nullptr;
  }
};

static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
  static InstrumentationRuntimeInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    InstrumentationRuntimeCreateInstance create_callback,
    InstrumentationRuntimeGetType get_type_callback) {
  return GetInstrumentationRuntimeInstances().RegisterPlugin(
      name, description, create_callback, get_type_callback);
}

bool PluginManager::UnregisterPlugin(
    InstrumentationRuntimeCreateInstance create_callback) {
  return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<InstrumentationRuntimeCallbacks>
PluginManager::GetInstrumentationRuntimeCallbacks(bool enabled_only) {
  auto instances =
      GetInstrumentationRuntimeInstances().GetSnapshot(enabled_only);
  llvm::SmallVector<InstrumentationRuntimeCallbacks> result;
  result.reserve(instances.size());
  for (auto &instance : instances)
    result.push_back({instance.create_callback, instance.get_type_callback});
  return result;
}

#pragma mark TypeSystem

struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> {
  TypeSystemInstance(llvm::StringRef name, llvm::StringRef description,
                     CallbackType create_callback,
                     LanguageSet supported_languages_for_types,
                     LanguageSet supported_languages_for_expressions)
      : PluginInstance<TypeSystemCreateInstance>(name, description,
                                                 create_callback),
        supported_languages_for_types(supported_languages_for_types),
        supported_languages_for_expressions(
            supported_languages_for_expressions) {}

  LanguageSet supported_languages_for_types;
  LanguageSet supported_languages_for_expressions;
};

typedef PluginInstances<TypeSystemInstance> TypeSystemInstances;

static TypeSystemInstances &GetTypeSystemInstances() {
  static TypeSystemInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    TypeSystemCreateInstance create_callback,
    LanguageSet supported_languages_for_types,
    LanguageSet supported_languages_for_expressions) {
  return GetTypeSystemInstances().RegisterPlugin(
      name, description, create_callback, supported_languages_for_types,
      supported_languages_for_expressions);
}

bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
  return GetTypeSystemInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<TypeSystemCreateInstance>
PluginManager::GetTypeSystemCreateCallbacks() {
  return GetTypeSystemInstances().GetCreateCallbacks();
}

LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
  const auto instances = GetTypeSystemInstances().GetSnapshot();
  LanguageSet all;
  for (unsigned i = 0; i < instances.size(); ++i)
    all.bitvector |= instances[i].supported_languages_for_types.bitvector;
  return all;
}

LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
  const auto instances = GetTypeSystemInstances().GetSnapshot();
  LanguageSet all;
  for (unsigned i = 0; i < instances.size(); ++i)
    all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
  return all;
}

#pragma mark ScriptedInterfaces

struct ScriptedInterfaceInstance
    : public PluginInstance<ScriptedInterfaceCreateInstance> {
  ScriptedInterfaceInstance(llvm::StringRef name, llvm::StringRef description,
                            ScriptedInterfaceCreateInstance create_callback,
                            lldb::ScriptLanguage language,
                            ScriptedInterfaceUsages usages)
      : PluginInstance<ScriptedInterfaceCreateInstance>(name, description,
                                                        create_callback),
        language(language), usages(usages) {}

  lldb::ScriptLanguage language;
  ScriptedInterfaceUsages usages;
};

typedef PluginInstances<ScriptedInterfaceInstance> ScriptedInterfaceInstances;

static ScriptedInterfaceInstances &GetScriptedInterfaceInstances() {
  static ScriptedInterfaceInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    llvm::StringRef name, llvm::StringRef description,
    ScriptedInterfaceCreateInstance create_callback,
    lldb::ScriptLanguage language, ScriptedInterfaceUsages usages) {
  return GetScriptedInterfaceInstances().RegisterPlugin(
      name, description, create_callback, language, usages);
}

bool PluginManager::UnregisterPlugin(
    ScriptedInterfaceCreateInstance create_callback) {
  return GetScriptedInterfaceInstances().UnregisterPlugin(create_callback);
}

uint32_t PluginManager::GetNumScriptedInterfaces() {
  return GetScriptedInterfaceInstances().GetSnapshot().size();
}

llvm::StringRef PluginManager::GetScriptedInterfaceNameAtIndex(uint32_t index) {
  return GetScriptedInterfaceInstances().GetNameAtIndex(index);
}

llvm::StringRef
PluginManager::GetScriptedInterfaceDescriptionAtIndex(uint32_t index) {
  return GetScriptedInterfaceInstances().GetDescriptionAtIndex(index);
}

lldb::ScriptLanguage
PluginManager::GetScriptedInterfaceLanguageAtIndex(uint32_t idx) {
  if (auto instance = GetScriptedInterfaceInstances().GetInstanceAtIndex(idx))
    return instance->language;
  return ScriptLanguage::eScriptLanguageNone;
}

ScriptedInterfaceUsages
PluginManager::GetScriptedInterfaceUsagesAtIndex(uint32_t idx) {
  if (auto instance = GetScriptedInterfaceInstances().GetInstanceAtIndex(idx))
    return instance->usages;
  return {};
}

#pragma mark REPL

struct REPLInstance : public PluginInstance<REPLCreateInstance> {
  REPLInstance(llvm::StringRef name, llvm::StringRef description,
               CallbackType create_callback, LanguageSet supported_languages)
      : PluginInstance<REPLCreateInstance>(name, description, create_callback),
        supported_languages(supported_languages) {}

  LanguageSet supported_languages;
};

typedef PluginInstances<REPLInstance> REPLInstances;

static REPLInstances &GetREPLInstances() {
  static REPLInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(llvm::StringRef name,
                                   llvm::StringRef description,
                                   REPLCreateInstance create_callback,
                                   LanguageSet supported_languages) {
  return GetREPLInstances().RegisterPlugin(name, description, create_callback,
                                           supported_languages);
}

bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
  return GetREPLInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<REPLCallbacks> PluginManager::GetREPLCallbacks() {
  auto instances = GetREPLInstances().GetSnapshot();
  llvm::SmallVector<REPLCallbacks> result;
  result.reserve(instances.size());
  for (auto &instance : instances)
    result.push_back({instance.create_callback, instance.supported_languages});
  return result;
}

LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
  const auto instances = GetREPLInstances().GetSnapshot();
  LanguageSet all;
  for (unsigned i = 0; i < instances.size(); ++i)
    all.bitvector |= instances[i].supported_languages.bitvector;
  return all;
}

#pragma mark Highlighter

struct HighlighterInstance : public PluginInstance<HighlighterCreateInstance> {
  HighlighterInstance(llvm::StringRef name, llvm::StringRef description,
                      CallbackType create_callback)
      : PluginInstance<HighlighterCreateInstance>(name, description,
                                                  create_callback) {}
};

typedef PluginInstances<HighlighterInstance> HighlighterInstances;

static HighlighterInstances &GetHighlighterInstances() {
  static HighlighterInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(llvm::StringRef name,
                                   llvm::StringRef description,
                                   HighlighterCreateInstance create_callback) {
  return GetHighlighterInstances().RegisterPlugin(name, description,
                                                  create_callback);
}

bool PluginManager::UnregisterPlugin(
    HighlighterCreateInstance create_callback) {
  return GetHighlighterInstances().UnregisterPlugin(create_callback);
}

llvm::SmallVector<HighlighterCreateInstance>
PluginManager::GetHighlighterCreateCallbacks() {
  return GetHighlighterInstances().GetCreateCallbacks();
}

#pragma mark PluginManager

void PluginManager::DebuggerInitialize(Debugger &debugger) {
  GetDynamicLoaderInstances().PerformDebuggerCallback(debugger);
  GetJITLoaderInstances().PerformDebuggerCallback(debugger);
  GetObjectFileInstances().PerformDebuggerCallback(debugger);
  GetPlatformInstances().PerformDebuggerCallback(debugger);
  GetProcessInstances().PerformDebuggerCallback(debugger);
  GetSymbolFileInstances().PerformDebuggerCallback(debugger);
  GetSymbolLocatorInstances().PerformDebuggerCallback(debugger);
  GetOperatingSystemInstances().PerformDebuggerCallback(debugger);
  GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
  GetTracePluginInstances().PerformDebuggerCallback(debugger);
  GetScriptedInterfaceInstances().PerformDebuggerCallback(debugger);
  GetLanguageInstances().PerformDebuggerCallback(debugger);
}

// This is the preferred new way to register plugin specific settings.  e.g.
// This will put a plugin's settings under e.g.
// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins(
    Debugger &debugger, llvm::StringRef plugin_type_name,
    llvm::StringRef plugin_type_desc, bool can_create) {
  lldb::OptionValuePropertiesSP parent_properties_sp(
      debugger.GetValueProperties());
  if (parent_properties_sp) {
    static constexpr llvm::StringLiteral g_property_name("plugin");

    OptionValuePropertiesSP plugin_properties_sp =
        parent_properties_sp->GetSubProperty(nullptr, g_property_name);
    if (!plugin_properties_sp && can_create) {
      plugin_properties_sp =
          std::make_shared<OptionValueProperties>(g_property_name);
      plugin_properties_sp->SetExpectedPath("plugin");
      parent_properties_sp->AppendProperty(g_property_name,
                                           "Settings specify to plugins.", true,
                                           plugin_properties_sp);
    }

    if (plugin_properties_sp) {
      lldb::OptionValuePropertiesSP plugin_type_properties_sp =
          plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
      if (!plugin_type_properties_sp && can_create) {
        plugin_type_properties_sp =
            std::make_shared<OptionValueProperties>(plugin_type_name);
        plugin_type_properties_sp->SetExpectedPath(
            ("plugin." + plugin_type_name).str());
        plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
                                             true, plugin_type_properties_sp);
      }
      return plugin_type_properties_sp;
    }
  }
  return lldb::OptionValuePropertiesSP();
}

// This is deprecated way to register plugin specific settings.  e.g.
// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
// generic settings would be under "platform.SETTINGNAME".
static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
    Debugger &debugger, llvm::StringRef plugin_type_name,
    llvm::StringRef plugin_type_desc, bool can_create) {
  static constexpr llvm::StringLiteral g_property_name("plugin");
  lldb::OptionValuePropertiesSP parent_properties_sp(
      debugger.GetValueProperties());
  if (parent_properties_sp) {
    OptionValuePropertiesSP plugin_properties_sp =
        parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
    if (!plugin_properties_sp && can_create) {
      plugin_properties_sp =
          std::make_shared<OptionValueProperties>(plugin_type_name);
      plugin_properties_sp->SetExpectedPath(plugin_type_name.str());
      parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
                                           true, plugin_properties_sp);
    }

    if (plugin_properties_sp) {
      lldb::OptionValuePropertiesSP plugin_type_properties_sp =
          plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
      if (!plugin_type_properties_sp && can_create) {
        plugin_type_properties_sp =
            std::make_shared<OptionValueProperties>(g_property_name);
        plugin_type_properties_sp->SetExpectedPath(
            (plugin_type_name + ".plugin").str());
        plugin_properties_sp->AppendProperty(g_property_name,
                                             "Settings specific to plugins",
                                             true, plugin_type_properties_sp);
      }
      return plugin_type_properties_sp;
    }
  }
  return lldb::OptionValuePropertiesSP();
}

namespace {

typedef lldb::OptionValuePropertiesSP
GetDebuggerPropertyForPluginsPtr(Debugger &, llvm::StringRef, llvm::StringRef,
                                 bool can_create);
}

static lldb::OptionValuePropertiesSP
GetSettingForPlugin(Debugger &debugger, llvm::StringRef setting_name,
                    llvm::StringRef plugin_type_name,
                    GetDebuggerPropertyForPluginsPtr get_debugger_property =
                        GetDebuggerPropertyForPlugins) {
  lldb::OptionValuePropertiesSP properties_sp;
  lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
      debugger, plugin_type_name,
      "", // not creating to so we don't need the description
      false));
  if (plugin_type_properties_sp)
    properties_sp =
        plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
  return properties_sp;
}

static bool
CreateSettingForPlugin(Debugger &debugger, llvm::StringRef plugin_type_name,
                       llvm::StringRef plugin_type_desc,
                       const lldb::OptionValuePropertiesSP &properties_sp,
                       llvm::StringRef description, bool is_global_property,
                       GetDebuggerPropertyForPluginsPtr get_debugger_property =
                           GetDebuggerPropertyForPlugins) {
  if (properties_sp) {
    lldb::OptionValuePropertiesSP plugin_type_properties_sp(
        get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
                              true));
    if (plugin_type_properties_sp) {
      plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
                                                description, is_global_property,
                                                properties_sp);
      return true;
    }
  }
  return false;
}

static constexpr llvm::StringLiteral kDynamicLoaderPluginName("dynamic-loader");
static constexpr llvm::StringLiteral kPlatformPluginName("platform");
static constexpr llvm::StringLiteral kProcessPluginName("process");
static constexpr llvm::StringLiteral kTracePluginName("trace");
static constexpr llvm::StringLiteral kObjectFilePluginName("object-file");
static constexpr llvm::StringLiteral kSymbolFilePluginName("symbol-file");
static constexpr llvm::StringLiteral kSymbolLocatorPluginName("symbol-locator");
static constexpr llvm::StringLiteral kJITLoaderPluginName("jit-loader");
static constexpr llvm::StringLiteral
    kStructuredDataPluginName("structured-data");
static constexpr llvm::StringLiteral kCPlusPlusLanguagePlugin("cplusplus");

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
                                                llvm::StringRef setting_name) {
  return GetSettingForPlugin(debugger, setting_name, kDynamicLoaderPluginName);
}

bool PluginManager::CreateSettingForDynamicLoaderPlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    llvm::StringRef description, bool is_global_property) {
  return CreateSettingForPlugin(debugger, kDynamicLoaderPluginName,
                                "Settings for dynamic loader plug-ins",
                                properties_sp, description, is_global_property);
}

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
                                           llvm::StringRef setting_name) {
  return GetSettingForPlugin(debugger, setting_name, kPlatformPluginName,
                             GetDebuggerPropertyForPluginsOldStyle);
}

bool PluginManager::CreateSettingForPlatformPlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    llvm::StringRef description, bool is_global_property) {
  return CreateSettingForPlugin(debugger, kPlatformPluginName,
                                "Settings for platform plug-ins", properties_sp,
                                description, is_global_property,
                                GetDebuggerPropertyForPluginsOldStyle);
}

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
                                          llvm::StringRef setting_name) {
  return GetSettingForPlugin(debugger, setting_name, kProcessPluginName);
}

bool PluginManager::CreateSettingForProcessPlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    llvm::StringRef description, bool is_global_property) {
  return CreateSettingForPlugin(debugger, kProcessPluginName,
                                "Settings for process plug-ins", properties_sp,
                                description, is_global_property);
}

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForSymbolLocatorPlugin(Debugger &debugger,
                                                llvm::StringRef setting_name) {
  return GetSettingForPlugin(debugger, setting_name, kSymbolLocatorPluginName);
}

bool PluginManager::CreateSettingForSymbolLocatorPlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    llvm::StringRef description, bool is_global_property) {
  return CreateSettingForPlugin(debugger, kSymbolLocatorPluginName,
                                "Settings for symbol locator plug-ins",
                                properties_sp, description, is_global_property);
}

bool PluginManager::CreateSettingForTracePlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    llvm::StringRef description, bool is_global_property) {
  return CreateSettingForPlugin(debugger, kTracePluginName,
                                "Settings for trace plug-ins", properties_sp,
                                description, is_global_property);
}

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForObjectFilePlugin(Debugger &debugger,
                                             llvm::StringRef setting_name) {
  return GetSettingForPlugin(debugger, setting_name, kObjectFilePluginName);
}

bool PluginManager::CreateSettingForObjectFilePlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    llvm::StringRef description, bool is_global_property) {
  return CreateSettingForPlugin(debugger, kObjectFilePluginName,
                                "Settings for object file plug-ins",
                                properties_sp, description, is_global_property);
}

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
                                             llvm::StringRef setting_name) {
  return GetSettingForPlugin(debugger, setting_name, kSymbolFilePluginName);
}

bool PluginManager::CreateSettingForSymbolFilePlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    llvm::StringRef description, bool is_global_property) {
  return CreateSettingForPlugin(debugger, kSymbolFilePluginName,
                                "Settings for symbol file plug-ins",
                                properties_sp, description, is_global_property);
}

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
                                            llvm::StringRef setting_name) {
  return GetSettingForPlugin(debugger, setting_name, kJITLoaderPluginName);
}

bool PluginManager::CreateSettingForJITLoaderPlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    llvm::StringRef description, bool is_global_property) {
  return CreateSettingForPlugin(debugger, kJITLoaderPluginName,
                                "Settings for JIT loader plug-ins",
                                properties_sp, description, is_global_property);
}

static const char *kOperatingSystemPluginName("os");

lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin(
    Debugger &debugger, llvm::StringRef setting_name) {
  lldb::OptionValuePropertiesSP properties_sp;
  lldb::OptionValuePropertiesSP plugin_type_properties_sp(
      GetDebuggerPropertyForPlugins(
          debugger, kOperatingSystemPluginName,
          "", // not creating to so we don't need the description
          false));
  if (plugin_type_properties_sp)
    properties_sp =
        plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
  return properties_sp;
}

bool PluginManager::CreateSettingForOperatingSystemPlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    llvm::StringRef description, bool is_global_property) {
  if (properties_sp) {
    lldb::OptionValuePropertiesSP plugin_type_properties_sp(
        GetDebuggerPropertyForPlugins(debugger, kOperatingSystemPluginName,
                                      "Settings for operating system plug-ins",
                                      true));
    if (plugin_type_properties_sp) {
      plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
                                                description, is_global_property,
                                                properties_sp);
      return true;
    }
  }
  return false;
}

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
                                                 llvm::StringRef setting_name) {
  return GetSettingForPlugin(debugger, setting_name, kStructuredDataPluginName);
}

bool PluginManager::CreateSettingForStructuredDataPlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    llvm::StringRef description, bool is_global_property) {
  return CreateSettingForPlugin(debugger, kStructuredDataPluginName,
                                "Settings for structured data plug-ins",
                                properties_sp, description, is_global_property);
}

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForCPlusPlusLanguagePlugin(
    Debugger &debugger, llvm::StringRef setting_name) {
  return GetSettingForPlugin(debugger, setting_name, kCPlusPlusLanguagePlugin);
}

bool PluginManager::CreateSettingForCPlusPlusLanguagePlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    llvm::StringRef description, bool is_global_property) {
  return CreateSettingForPlugin(debugger, kCPlusPlusLanguagePlugin,
                                "Settings for CPlusPlus language plug-ins",
                                properties_sp, description, is_global_property);
}

//
// Plugin Info+Enable Implementations
//
llvm::SmallVector<RegisteredPluginInfo> PluginManager::GetABIPluginInfo() {
  return GetABIInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetABIPluginEnabled(llvm::StringRef name, bool enable) {
  return GetABIInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetArchitecturePluginInfo() {
  return GetArchitectureInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetArchitecturePluginEnabled(llvm::StringRef name,
                                                 bool enable) {
  return GetArchitectureInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetDisassemblerPluginInfo() {
  return GetDisassemblerInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetDisassemblerPluginEnabled(llvm::StringRef name,
                                                 bool enable) {
  return GetDisassemblerInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetDynamicLoaderPluginInfo() {
  return GetDynamicLoaderInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetDynamicLoaderPluginEnabled(llvm::StringRef name,
                                                  bool enable) {
  return GetDynamicLoaderInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetEmulateInstructionPluginInfo() {
  return GetEmulateInstructionInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetEmulateInstructionPluginEnabled(llvm::StringRef name,
                                                       bool enable) {
  return GetEmulateInstructionInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetInstrumentationRuntimePluginInfo() {
  return GetInstrumentationRuntimeInstances().GetPluginInfoForAllInstances();
}

llvm::StringRef PluginManager::PluginDomainKindToStr(PluginDomainKind kind) {
  switch (kind) {
  case ePluginDomainKindGlobal:
    return "global";
  case ePluginDomainKindDebugger:
    return "debugger";
  case ePluginDomainKindTarget:
    return "target";
  }
  llvm_unreachable("unhandled PluginDomainKind");
}

llvm::Error PluginManager::SetInstrumentationRuntimePluginEnabled(
    llvm::StringRef name, bool enable, Debugger &requesting_debugger,
    PluginDomainKind domain) {
  if (domain != lldb::ePluginDomainKindGlobal)
    return llvm::createStringErrorV("{} domain is not supported",
                                    PluginDomainKindToStr(domain));
  if (!GetInstrumentationRuntimeInstances().SetInstanceEnabled(name, enable))
    return llvm::createStringError("plugin could not be found");

  return llvm::Error::success();
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetJITLoaderPluginInfo() {
  return GetJITLoaderInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetJITLoaderPluginEnabled(llvm::StringRef name,
                                              bool enable) {
  return GetJITLoaderInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo> PluginManager::GetLanguagePluginInfo() {
  return GetLanguageInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetLanguagePluginEnabled(llvm::StringRef name,
                                             bool enable) {
  return GetLanguageInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetLanguageRuntimePluginInfo() {
  return GetLanguageRuntimeInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetLanguageRuntimePluginEnabled(llvm::StringRef name,
                                                    bool enable) {
  return GetLanguageRuntimeInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetMemoryHistoryPluginInfo() {
  return GetMemoryHistoryInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetMemoryHistoryPluginEnabled(llvm::StringRef name,
                                                  bool enable) {
  return GetMemoryHistoryInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetObjectContainerPluginInfo() {
  return GetObjectContainerInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetObjectContainerPluginEnabled(llvm::StringRef name,
                                                    bool enable) {
  return GetObjectContainerInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetObjectFilePluginInfo() {
  return GetObjectFileInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetObjectFilePluginEnabled(llvm::StringRef name,
                                               bool enable) {
  return GetObjectFileInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetOperatingSystemPluginInfo() {
  return GetOperatingSystemInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetOperatingSystemPluginEnabled(llvm::StringRef name,
                                                    bool enable) {
  return GetOperatingSystemInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo> PluginManager::GetPlatformPluginInfo() {
  return GetPlatformInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetPlatformPluginEnabled(llvm::StringRef name,
                                             bool enable) {
  return GetPlatformInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo> PluginManager::GetProcessPluginInfo() {
  return GetProcessInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetProcessPluginEnabled(llvm::StringRef name, bool enable) {
  return GetProcessInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo> PluginManager::GetREPLPluginInfo() {
  return GetREPLInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetREPLPluginEnabled(llvm::StringRef name, bool enable) {
  return GetREPLInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetRegisterTypeBuilderPluginInfo() {
  return GetRegisterTypeBuilderInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetRegisterTypeBuilderPluginEnabled(llvm::StringRef name,
                                                        bool enable) {
  return GetRegisterTypeBuilderInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetScriptInterpreterPluginInfo() {
  return GetScriptInterpreterInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetScriptInterpreterPluginEnabled(llvm::StringRef name,
                                                      bool enable) {
  return GetScriptInterpreterInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetScriptedInterfacePluginInfo() {
  return GetScriptedInterfaceInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetScriptedInterfacePluginEnabled(llvm::StringRef name,
                                                      bool enable) {
  return GetScriptedInterfaceInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetStructuredDataPluginInfo() {
  return GetStructuredDataPluginInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetStructuredDataPluginEnabled(llvm::StringRef name,
                                                   bool enable) {
  return GetStructuredDataPluginInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetSymbolFilePluginInfo() {
  return GetSymbolFileInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetSymbolFilePluginEnabled(llvm::StringRef name,
                                               bool enable) {
  return GetSymbolFileInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetSymbolLocatorPluginInfo() {
  return GetSymbolLocatorInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetSymbolLocatorPluginEnabled(llvm::StringRef name,
                                                  bool enable) {
  return GetSymbolLocatorInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetSymbolVendorPluginInfo() {
  return GetSymbolVendorInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetSymbolVendorPluginEnabled(llvm::StringRef name,
                                                 bool enable) {
  return GetSymbolVendorInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetSystemRuntimePluginInfo() {
  return GetSystemRuntimeInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetSystemRuntimePluginEnabled(llvm::StringRef name,
                                                  bool enable) {
  return GetSystemRuntimeInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo> PluginManager::GetTracePluginInfo() {
  return GetTracePluginInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetTracePluginEnabled(llvm::StringRef name, bool enable) {
  return GetTracePluginInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetTraceExporterPluginInfo() {
  return GetTraceExporterInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetTraceExporterPluginEnabled(llvm::StringRef name,
                                                  bool enable) {
  return GetTraceExporterInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetTypeSystemPluginInfo() {
  return GetTypeSystemInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetTypeSystemPluginEnabled(llvm::StringRef name,
                                               bool enable) {
  return GetTypeSystemInstances().SetInstanceEnabled(name, enable);
}

llvm::SmallVector<RegisteredPluginInfo>
PluginManager::GetUnwindAssemblyPluginInfo() {
  return GetUnwindAssemblyInstances().GetPluginInfoForAllInstances();
}
bool PluginManager::SetUnwindAssemblyPluginEnabled(llvm::StringRef name,
                                                   bool enable) {
  return GetUnwindAssemblyInstances().SetInstanceEnabled(name, enable);
}

void PluginManager::AutoCompletePluginName(llvm::StringRef name,
                                           CompletionRequest &request) {
  // Split the name into the namespace and the plugin name.
  // If there is no dot then the ns_name will be equal to name and
  // plugin_prefix will be empty.
  llvm::StringRef ns_name, plugin_prefix;
  std::tie(ns_name, plugin_prefix) = name.split('.');

  for (const PluginNamespace &plugin_ns : GetPluginNamespaces()) {
    // If the plugin namespace matches exactly then
    // add all the plugins in this namespace as completions if the
    // plugin names starts with the plugin_prefix. If the plugin_prefix
    // is empty then it will match all the plugins (empty string is a
    // prefix of everything).
    if (plugin_ns.name == ns_name) {
      for (const RegisteredPluginInfo &plugin : plugin_ns.get_info()) {
        llvm::SmallString<128> buf;
        if (plugin.name.starts_with(plugin_prefix))
          request.AddCompletion(
              (plugin_ns.name + "." + plugin.name).toStringRef(buf));
      }
    } else if (plugin_ns.name.starts_with(name) &&
               !plugin_ns.get_info().empty()) {
      // Otherwise check if the namespace is a prefix of the full name.
      // Use a partial completion here so that we can either operate on the full
      // namespace or tab-complete to the next level.
      request.AddCompletion(plugin_ns.name, "", CompletionMode::Partial);
    }
  }
}
