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