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

org.jetbrains.kotlinx.dataframe.plugin.impl.Interpreter.kt Maven / Gradle / Ivy

The newest version!
package org.jetbrains.kotlinx.dataframe.plugin.impl

import org.jetbrains.kotlinx.dataframe.plugin.extensions.KotlinTypeFacade
import kotlin.properties.PropertyDelegateProvider
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KType
import kotlin.reflect.typeOf

interface Interpreter {
    val expectedArguments: List

    data class ExpectedArgument(
        val name: String,
        val klass: KType,
        val lens: Lens,
        val defaultValue: DefaultValue<*>
    )

    sealed interface Lens

    data object Value : Lens

    data object ReturnType : Lens

    data object Dsl : Lens

    data object Schema : Lens

    data object  Id : Lens

    // required to compute whether resulting schema should be inheritor of previous class or a new class
    fun startingSchema(arguments: Map>, kotlinTypeFacade: KotlinTypeFacade): PluginDataFrameSchema?

    fun interpret(arguments: Map>, kotlinTypeFacade: KotlinTypeFacade): InterpretationResult

    sealed interface InterpretationResult

    class Success(val value: T) : InterpretationResult {
        override fun equals(other: Any?): Boolean {
            if (this === other) return true
            if (javaClass != other?.javaClass) return false

            other as Success<*>

            return value == other.value
        }

        override fun hashCode(): Int {
            return value?.hashCode() ?: 0
        }
    }

    class Error(val message: String?) : InterpretationResult
}

sealed interface DefaultValue

class Present(val value: T) : DefaultValue
data object Absent : DefaultValue

open class Arguments(private val arguments: Map>, kotlinTypeFacade: KotlinTypeFacade): KotlinTypeFacade by kotlinTypeFacade {
    operator fun get(s: String): Any? = (arguments[s] ?: error("")).value
    operator fun contains(key: String): Boolean {
        return arguments.contains(key)
    }
}

abstract class AbstractInterpreter : Interpreter {
    @PublishedApi
    internal val _expectedArguments: MutableList = mutableListOf()

    override val expectedArguments: List = _expectedArguments

    protected open val Arguments.startingSchema: PluginDataFrameSchema? get() = null

    final override fun startingSchema(arguments: Map>, kotlinTypeFacade: KotlinTypeFacade): PluginDataFrameSchema? {
        return Arguments(arguments, kotlinTypeFacade).startingSchema
    }

    inline fun  argConvert(
        defaultValue: DefaultValue = Absent,
        name: ArgumentName? = null,
        lens: Interpreter.Lens = Interpreter.Value,
        crossinline converter: (CompileTimeValue) -> Value
    ): PropertyDelegateProvider> = PropertyDelegateProvider { thisRef: Any?, property ->
        val name = name?.value ?: property.name
        _expectedArguments.add(Interpreter.ExpectedArgument(name, typeOf(), lens, defaultValue))
        ReadOnlyProperty { args, _ ->
            if (name !in args && defaultValue is Present) {
                defaultValue.value
            } else {
                converter(args[name] as CompileTimeValue)
            }
        }
    }

    fun  arg(
        name: ArgumentName? = null,
        expectedType: KType? = null,
        defaultValue: DefaultValue = Absent,
        lens: Interpreter.Lens = Interpreter.Value
    ): PropertyDelegateProvider> = PropertyDelegateProvider { thisRef: Any?, property ->
        val name = name?.value ?: property.name
        _expectedArguments.add(
            Interpreter.ExpectedArgument(
                name,
                expectedType ?: property.returnType,
                lens,
                defaultValue
            )
        )
        ReadOnlyProperty { args, _ ->
            if (name !in args && defaultValue is Present) {
                defaultValue.value
            } else {
                @Suppress("UNCHECKED_CAST")
                args[name] as Value
            }
        }
    }

    class ArgumentName private constructor(val value: String) {
        companion object {
            fun of(name: String): ArgumentName = ArgumentName(name)
        }
    }

    fun name(name: String): ArgumentName = ArgumentName.of(name)

    final override fun interpret(arguments: Map>, kotlinTypeFacade: KotlinTypeFacade): Interpreter.InterpretationResult {
        return try {
            Arguments(arguments, kotlinTypeFacade).interpret().let { Interpreter.Success(it) }
        } catch (e: Exception) {
            Interpreter.Error(e.message + e.stackTrace.contentToString())
        }
    }

    abstract fun Arguments.interpret(): T
}

interface SchemaModificationInterpreter : Interpreter {

    override fun interpret(arguments: Map>, kotlinTypeFacade: KotlinTypeFacade): Interpreter.InterpretationResult
}

abstract class AbstractSchemaModificationInterpreter :
    AbstractInterpreter(),
    SchemaModificationInterpreter




© 2015 - 2024 Weber Informatics LLC | Privacy Policy