[Gradle] kgp-idea-proto: Add public API for extras serialisation

KT-55926
This commit is contained in:
Sebastian Sellmair
2023-01-13 13:30:11 +01:00
committed by Space Team
parent 54db04e0f4
commit d0bb804e85
5 changed files with 59 additions and 0 deletions
@@ -1,3 +1,8 @@
public final class org/jetbrains/kotlin/gradle/idea/proto/ExtrasKt {
public static final fun Extras (Lorg/jetbrains/kotlin/gradle/idea/serialize/IdeaKotlinSerializationContext;[B)Lorg/jetbrains/kotlin/tooling/core/MutableExtras;
public static final fun toByteArray (Lorg/jetbrains/kotlin/tooling/core/Extras;Lorg/jetbrains/kotlin/gradle/idea/serialize/IdeaKotlinSerializationContext;)[B
}
public final class org/jetbrains/kotlin/gradle/idea/proto/kpm/KpmIdeaProto {
public static final fun IdeaKpmProject (Lorg/jetbrains/kotlin/gradle/idea/serialize/IdeaKotlinSerializationContext;Ljava/io/InputStream;)Lorg/jetbrains/kotlin/gradle/idea/kpm/IdeaKpmProject;
public static final fun IdeaKpmProject (Lorg/jetbrains/kotlin/gradle/idea/serialize/IdeaKotlinSerializationContext;Ljava/nio/ByteBuffer;)Lorg/jetbrains/kotlin/gradle/idea/kpm/IdeaKpmProject;
@@ -8,12 +8,28 @@
package org.jetbrains.kotlin.gradle.idea.proto
import com.google.protobuf.ByteString
import com.google.protobuf.InvalidProtocolBufferException
import org.jetbrains.kotlin.gradle.idea.proto.generated.IdeaExtrasProto
import org.jetbrains.kotlin.gradle.idea.proto.generated.ideaExtrasProto
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinExtrasSerializer
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinSerializationContext
import org.jetbrains.kotlin.tooling.core.*
fun Extras.toByteArray(context: IdeaKotlinSerializationContext): ByteArray {
return context.IdeaExtrasProto(this).toByteArray()
}
fun IdeaKotlinSerializationContext.Extras(data: ByteArray): MutableExtras? {
return try {
val proto = IdeaExtrasProto.parseFrom(data)
Extras(proto)
} catch (e: InvalidProtocolBufferException) {
logger.error("Failed to deserialize Extras", e)
null
}
}
@Suppress("unchecked_cast")
internal fun IdeaKotlinSerializationContext.IdeaExtrasProto(extras: Extras): IdeaExtrasProto {
val context = this
@@ -0,0 +1,24 @@
/*
* Copyright 2010-2023 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.idea.proto
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.TestIdeaKotlinInstances
import org.jetbrains.kotlin.tooling.core.MutableExtras
import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
import org.jetbrains.kotlin.tooling.core.toMutableExtras
import kotlin.test.Test
import kotlin.test.fail
class ExtrasSerializationTest : AbstractSerializationTest<MutableExtras>() {
override fun serialize(value: MutableExtras): ByteArray = value.toByteArray(this)
override fun deserialize(data: ByteArray): MutableExtras = Extras(data) ?: fail()
@Test
fun `sample - extrasWithIntAndStrings`() = testSerialization(TestIdeaKotlinInstances.extrasWithIntAndStrings.toMutableExtras())
@Test
fun `sample - emptyExtras`() = testSerialization(mutableExtrasOf())
}
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.gradle.targets.metadata.isSingleKotlinTargetSourceSe
import org.jetbrains.kotlin.gradle.targets.metadata.isSinglePlatformTypeSourceSet
import org.jetbrains.kotlin.gradle.utils.getOrPut
import org.jetbrains.kotlin.tooling.core.Extras
import org.jetbrains.kotlin.tooling.core.HasMutableExtras
interface IdeMultiplatformImport {
@@ -37,6 +38,12 @@ interface IdeMultiplatformImport {
fun resolveDependenciesSerialized(sourceSetName: String): List<ByteArray>
/**
* @param owner: Should implement [HasMutableExtras]. Passing [Any] is fine to make it easier to cross
* ClassLoader boundaries. Passing some non [HasMutableExtras] will just return null
*/
fun resolveExtrasSerialized(owner: Any): ByteArray?
fun serialize(dependencies: Iterable<IdeaKotlinDependency>): List<ByteArray>
fun <T : Any> serialize(key: Extras.Key<T>, value: T): ByteArray?
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.plugin.ide
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.idea.proto.tcs.toByteArray
import org.jetbrains.kotlin.gradle.idea.proto.toByteArray
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinExtrasSerializationExtension
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinSerializationContext
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver.Companion.re
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.*
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.Companion.logger
import org.jetbrains.kotlin.tooling.core.Extras
import org.jetbrains.kotlin.tooling.core.HasMutableExtras
import org.jetbrains.kotlin.utils.addToStdlib.measureTimeMillisWithResult
import kotlin.system.measureTimeMillis
@@ -37,6 +39,11 @@ internal class IdeMultiplatformImportImpl(
return serialize(resolveDependencies(sourceSetName))
}
override fun resolveExtrasSerialized(owner: Any): ByteArray? {
if (owner !is HasMutableExtras) return null
return owner.extras.toByteArray(createSerializationContext())
}
override fun serialize(dependencies: Iterable<IdeaKotlinDependency>): List<ByteArray> {
val context = createSerializationContext()
return dependencies.map { dependency -> dependency.toByteArray(context) }