[kpm] kgp-idea: Implement IdeaKpmSerializationContext

This context shall be used to register extension points like
IdeaKpmSerializationLogger or IdeaKpmExtrasSerializationExtension

^KT-52568 In Progress
This commit is contained in:
sebastian.sellmair
2022-06-13 13:55:16 +02:00
committed by Space
parent 132743cb7a
commit 7db9a4b0b1
5 changed files with 149 additions and 0 deletions
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.kpm.idea.serialize
import org.jetbrains.kotlin.tooling.core.Extras
interface IdeaKpmExtrasSerializationExtension {
fun <T : Any> serializer(key: Extras.Key<T>): IdeaKpmExtrasSerializer<T>?
object Empty : IdeaKpmExtrasSerializationExtension {
override fun <T : Any> serializer(key: Extras.Key<T>): IdeaKpmExtrasSerializer<T>? = null
}
}
interface IdeaKpmExtrasSerializationExtensionBuilder {
fun <T : Any> register(key: Extras.Key<T>, serializer: IdeaKpmExtrasSerializer<T>)
}
fun IdeaKpmExtrasSerializationExtension(
builder: IdeaKpmExtrasSerializationExtensionBuilder.() -> Unit
): IdeaKpmExtrasSerializationExtension {
return IdeaKpmExtrasSerializationExtensionImpl(
IdeaKpmExtrasSerializationExtensionBuilderImpl().apply(builder).serializers
)
}
private class IdeaKpmExtrasSerializationExtensionBuilderImpl : IdeaKpmExtrasSerializationExtensionBuilder {
val serializers = mutableMapOf<Extras.Key<*>, IdeaKpmExtrasSerializer<*>>()
override fun <T : Any> register(key: Extras.Key<T>, serializer: IdeaKpmExtrasSerializer<T>) {
serializers[key] = serializer
}
}
private class IdeaKpmExtrasSerializationExtensionImpl(
private val map: Map<Extras.Key<*>, IdeaKpmExtrasSerializer<*>>
) : IdeaKpmExtrasSerializationExtension {
override fun <T : Any> serializer(key: Extras.Key<T>): IdeaKpmExtrasSerializer<T>? {
@Suppress("unchecked_cast")
return map[key] as? IdeaKpmExtrasSerializer<T>
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.kpm.idea.serialize
import kotlin.reflect.KClass
interface IdeaKpmExtrasSerializer<T : Any> {
fun serialize(context: IdeaKpmSerializationContext, value: T): ByteArray?
fun deserialize(context: IdeaKpmSerializationContext, data: ByteArray): T?
companion object {
/**
* Returns a [IdeaKpmExtrasSerializer] based upon [java.io.Serializable]
*/
fun <T : Any> javaIoSerializable(clazz: KClass<T>): IdeaKpmExtrasSerializer<T> {
return IdeaKpmJavaIoSerializableExtrasSerializer(clazz)
}
inline fun <reified T : Any> javaIoSerializable(): IdeaKpmExtrasSerializer<T> {
return javaIoSerializable(T::class)
}
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.kpm.idea.serialize
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import kotlin.reflect.KClass
internal class IdeaKpmJavaIoSerializableExtrasSerializer<T : Any>(
private val clazz: KClass<T>
) : IdeaKpmExtrasSerializer<T> {
override fun serialize(context: IdeaKpmSerializationContext, value: T): ByteArray? {
return try {
ByteArrayOutputStream().use { byteArrayOutputStream ->
ObjectOutputStream(byteArrayOutputStream).use { oos -> oos.writeObject(value) }
byteArrayOutputStream.toByteArray()
}
} catch (t: Throwable) {
context.logger.error("${ErrorMessages.SERIALIZATION_FAILURE} $value", t)
null
}
}
override fun deserialize(context: IdeaKpmSerializationContext, data: ByteArray): T? {
return try {
ObjectInputStream(ByteArrayInputStream(data)).use { stream -> clazz.java.cast(stream.readObject()) }
} catch (t: Throwable) {
context.logger.error("${ErrorMessages.DESERIALIZATION_FAILURE} ${clazz.java}", t)
null
}
}
object ErrorMessages {
const val SERIALIZATION_FAILURE = "Failed to serialize"
const val DESERIALIZATION_FAILURE = "Failed to deserialize"
}
}
@@ -0,0 +1,11 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.kpm.idea.serialize
interface IdeaKpmSerializationContext {
val extrasSerializationExtension: IdeaKpmExtrasSerializationExtension
val logger: IdeaKpmSerializationLogger
}
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.kpm.idea.serialize
interface IdeaKpmSerializationLogger {
enum class Severity {
WARNING,
ERROR,
}
fun report(severity: Severity, message: String, cause: Throwable? = null)
fun warn(message: String, cause: Throwable? = null) = report(Severity.WARNING, message, cause)
fun error(message: String, cause: Throwable? = null) = report(Severity.ERROR, message, cause)
object None : IdeaKpmSerializationLogger {
override fun report(severity: Severity, message: String, cause: Throwable?) = Unit
}
}