All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.InternalServiceLoader.kt Maven / Gradle / Ivy

/*
 * Copyright (c) 2024 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license.
 */

@file:Suppress("PackageDirectoryMismatch")

package dev.whyoleg.sweetspi.internal

import kotlin.reflect.*

@RequiresOptIn("Internal API for KSP processor, should not be used outside", RequiresOptIn.Level.ERROR)
public annotation class InternalSweetSpiApi

// there should be one such initializer generated by KSP per module/platform/sourceSet where KSP plugin is applied
@InternalSweetSpiApi
public interface InternalServiceModule {
    public val services: Set>
    public val requiredServices: Set>
    public fun providers(cls: KClass<*>): List<*>
}

@InternalSweetSpiApi
internal expect val internalServiceLoader: Lazy

internal expect open class SynchronizedObject()

internal expect inline fun  synchronized(lock: SynchronizedObject, block: () -> T): T

@InternalSweetSpiApi
internal class InternalServiceLoader(
    private val modules: List,
) : SynchronizedObject() {
    private val registeredServices: Set> = modules.flatMapTo(mutableSetOf(), InternalServiceModule::services)
    private val providers = mutableMapOf, List<*>>()

    init {
        // this could happen mostly if there is something wrong with KSP or runtime code
        modules.forEach { module ->
            module.requiredServices.forEach { required ->
                if (required !in registeredServices) {
                    println("Service `${required.simpleName}` wasn't registered, required by: $module")
                }
            }
        }
    }

    fun  load(cls: KClass): List {
        require(cls in registeredServices) { "Service `${cls.simpleName}` wasn't registered" }

        @Suppress("UNCHECKED_CAST")
        return synchronized(this) {
            providers.getOrPut(cls) { modules.flatMap { it.providers(cls) } } as List
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy