73 lines
2.3 KiB
C++
73 lines
2.3 KiB
C++
module;
|
|
|
|
export module lsp.provider.base.registry;
|
|
import spdlog;
|
|
|
|
import std;
|
|
|
|
import lsp.core.dispacther;
|
|
import lsp.provider.base.interface;
|
|
|
|
export namespace lsp::provider
|
|
{
|
|
template<typename T>
|
|
concept AutoRegisterableProvider = HasMethod<T> && HasProviderName<T> &&
|
|
requires {
|
|
{ T::kAutoRegister } -> std::convertible_to<bool>;
|
|
} &&
|
|
(std::derived_from<T, core::IRequestProvider> ||
|
|
std::derived_from<T, core::INotificationProvider>);
|
|
|
|
template<AutoRegisterableProvider... Providers>
|
|
consteval bool HasDuplicateMethods()
|
|
{
|
|
std::array<std::string_view, sizeof...(Providers)> methods = { Providers::kMethod... };
|
|
for (std::size_t i = 0; i < methods.size(); ++i)
|
|
{
|
|
for (std::size_t j = i + 1; j < methods.size(); ++j)
|
|
{
|
|
if (methods[i] == methods[j])
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
template<AutoRegisterableProvider... Providers>
|
|
class ProviderRegistry
|
|
{
|
|
public:
|
|
static constexpr std::size_t kProviderCount = sizeof...(Providers);
|
|
using ProviderList = std::tuple<Providers...>;
|
|
|
|
static void RegisterAll(core::RequestDispatcher& dispatcher)
|
|
{
|
|
(RegisterProvider<Providers>(dispatcher), ...);
|
|
}
|
|
|
|
private:
|
|
static_assert(!HasDuplicateMethods<Providers...>(),
|
|
"Duplicate method names detected in providers.");
|
|
|
|
template<typename Provider>
|
|
static void RegisterProvider(core::RequestDispatcher& dispatcher)
|
|
{
|
|
auto provider = std::make_shared<Provider>();
|
|
|
|
if constexpr (std::derived_from<Provider, core::IRequestProvider>)
|
|
{
|
|
dispatcher.RegisterRequestProvider(provider);
|
|
}
|
|
else if constexpr (std::derived_from<Provider, core::INotificationProvider>)
|
|
{
|
|
dispatcher.RegisterNotificationProvider(provider);
|
|
}
|
|
|
|
spdlog::debug("Registered provider [{}] for [{}]",
|
|
Provider::kProviderName, Provider::kMethod);
|
|
}
|
|
};
|
|
}
|