From 3b4e43568740833807d9782fb3c908c7eeee7188 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Mon, 6 Mar 2023 10:20:19 +0100 Subject: [PATCH] Move to kotlinx.serialization (#4726) * replace Moshi with kotlinx.serialization * remove (most of moshi) --- benchmark/app/build.gradle.kts | 7 +- benchmark/build-logic/build.gradle.kts | 28 ++----- benchmark/build-logic/settings.gradle.kts | 25 ++++-- benchmark/build.gradle.kts | 16 ---- benchmark/gradle/benchmarks.versions.toml | 11 +++ benchmark/microbenchmark/build.gradle.kts | 8 +- benchmark/settings.gradle.kts | 23 +++++- .../src/main/kotlin/CompilerOptions.kt | 4 +- gradle/libraries.toml | 8 +- libraries/apollo-ast/api/apollo-ast.api | 2 +- .../ast/introspection/IntrospectionSchema.kt | 2 +- .../apollo-compiler/api/apollo-compiler.api | 76 ++++++++++++------- libraries/apollo-compiler/build.gradle.kts | 6 -- .../apollo3/compiler/ApolloCompiler.kt | 5 +- .../apollo3/compiler/CodegenMetadata.kt | 22 +++--- .../apollographql/apollo3/compiler/Options.kt | 2 - .../apollo3/compiler/codegen/Resolver.kt | 12 +-- .../apollographql/apollo3/compiler/moshi.kt | 64 ---------------- .../operationoutput/OperationOutput.kt | 32 +++++--- .../internal/ApolloConvertSchemaTask.kt | 4 +- .../internal/ApolloRegisterOperationsTask.kt | 2 +- .../apollo-tooling/api/apollo-tooling.api | 4 + libraries/apollo-tooling/build.gradle.kts | 7 +- .../apollo3/tooling/RegisterOperations.kt | 21 +++-- .../apollo3/tooling/SchemaDownloader.kt | 18 ++++- .../apollo3/tooling/SchemaHelper.kt | 3 +- .../apollo3/tooling/SchemaUploader.kt | 5 +- .../apollo3/tooling/serialization.kt | 35 +++++++++ 28 files changed, 237 insertions(+), 215 deletions(-) create mode 100644 benchmark/gradle/benchmarks.versions.toml delete mode 100644 libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/moshi.kt create mode 100644 libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/serialization.kt diff --git a/benchmark/app/build.gradle.kts b/benchmark/app/build.gradle.kts index a424c86b003..8fe2caba38b 100644 --- a/benchmark/app/build.gradle.kts +++ b/benchmark/app/build.gradle.kts @@ -3,11 +3,12 @@ apply(plugin = "org.jetbrains.kotlin.android") configure { namespace = "com.apollographql.apollo3.emptyapp" - compileSdkVersion(golatac.version("android.sdkversion.compile").toInt()) + + compileSdkVersion(libs.versions.android.sdkversion.compile.get().toInt()) defaultConfig { - minSdkVersion(golatac.version("android.sdkversion.min")) - targetSdkVersion(golatac.version("android.sdkversion.target")) + minSdk = libs.versions.android.sdkversion.min.get().toInt() + targetSdk = libs.versions.android.sdkversion.target.get().toInt() val debugSigningConfig = signingConfigs.getByName("debug").apply { // This is all public. This app is only an empty shell to make Firebase happy because it requires an 'app' APK. diff --git a/benchmark/build-logic/build.gradle.kts b/benchmark/build-logic/build.gradle.kts index e8038e73c84..808eed1dd1a 100644 --- a/benchmark/build-logic/build.gradle.kts +++ b/benchmark/build-logic/build.gradle.kts @@ -1,33 +1,21 @@ plugins { `embedded-kotlin` - id("net.mbonnin.golatac") version "0.0.3" } -golatac.init(file("../../gradle/libraries.toml")) - group = "com.apollographql.apollo3.benchmark" -repositories { - mavenCentral() - google() - maven { - url = uri("../../build/localMaven") - } -} - dependencies { compileOnly(gradleApi()) - implementation(golatac.lib("kotlin.plugin")) - implementation("com.squareup.okio:okio-jvm:3.2.0") - implementation(golatac.lib("ksp")) - implementation("me.lucko:jar-relocator:1.5") - + implementation(libs.kotlin.plugin) + implementation(libs.okio) + implementation(libs.ksp) + implementation(benchmarks.jar.relocator) if (true) { - implementation(golatac.lib("apollo.plugin")) + implementation(libs.apollo.plugin) } else { implementation("com.apollographql.apollo3:apollo-gradle-plugin:3.4.0") } - implementation("androidx.benchmark:benchmark-gradle-plugin:1.1.0") - implementation("com.android.tools.build:gradle:7.4.0-alpha09") - implementation("org.ow2.asm:asm-commons:9.2") + implementation(benchmarks.benchmark.gradle.plugin) + implementation(benchmarks.agp) + implementation(benchmarks.asm) } diff --git a/benchmark/build-logic/settings.gradle.kts b/benchmark/build-logic/settings.gradle.kts index e50a948d16e..27c41662910 100644 --- a/benchmark/build-logic/settings.gradle.kts +++ b/benchmark/build-logic/settings.gradle.kts @@ -1,11 +1,20 @@ -pluginManagement { - repositories { - mavenCentral() - gradlePluginPortal { - content { - includeModule("org.gradle.kotlin.embedded-kotlin", "org.gradle.kotlin.embedded-kotlin.gradle.plugin") - includeGroup("org.gradle.kotlin") - } +apply(from = "../../gradle/repositories.gradle.kts") + +listOf(pluginManagement.repositories, dependencyResolutionManagement.repositories).forEach { + it.apply { + maven { + url = uri("../../build/localMaven") + } + } +} + +dependencyResolutionManagement { + versionCatalogs { + create("benchmarks") { + from(files("../gradle/benchmarks.versions.toml")) + } + create("libs") { + from(files("../../gradle/libraries.toml")) } } } \ No newline at end of file diff --git a/benchmark/build.gradle.kts b/benchmark/build.gradle.kts index d7fbb8f5483..5c51c285d1f 100644 --- a/benchmark/build.gradle.kts +++ b/benchmark/build.gradle.kts @@ -1,11 +1,4 @@ buildscript { - repositories { - mavenCentral() - google() - maven { - url = uri("../build/localMaven") - } - } dependencies { classpath("com.apollographql.apollo3.benchmark:build-logic") } @@ -17,12 +10,3 @@ plugins { golatac.init(file("../gradle/libraries.toml")) -allprojects { - repositories { - mavenCentral() - google() - maven { - url = rootProject.uri("../build/localMaven") - } - } -} diff --git a/benchmark/gradle/benchmarks.versions.toml b/benchmark/gradle/benchmarks.versions.toml new file mode 100644 index 00000000000..92dcea92280 --- /dev/null +++ b/benchmark/gradle/benchmarks.versions.toml @@ -0,0 +1,11 @@ +[versions] +moshix = "0.14.1" + +[libraries] +jar-relocator = "me.lucko:jar-relocator:1.5" +benchmark-gradle-plugin = "androidx.benchmark:benchmark-gradle-plugin:1.1.1" +agp = "com.android.tools.build:gradle:7.4.2" +asm = "org.ow2.asm:asm-commons:9.3" +moshix-ksp = { group = "dev.zacsweers.moshix", name = "moshi-ksp", version.ref = "moshix" } +benchmark-junit4 = "androidx.benchmark:benchmark-junit4:1.1.1" +androidx-test-core = "androidx.test:core:1.5.0" diff --git a/benchmark/microbenchmark/build.gradle.kts b/benchmark/microbenchmark/build.gradle.kts index 5a1eed158ca..2aa52cbd59b 100644 --- a/benchmark/microbenchmark/build.gradle.kts +++ b/benchmark/microbenchmark/build.gradle.kts @@ -59,11 +59,11 @@ dependencies { } } } - implementation(golatac.lib("moshi")) - ksp(golatac.lib("moshix.ksp")) + implementation(libs.moshi) + ksp(benchmarks.moshix.ksp) - androidTestImplementation("androidx.benchmark:benchmark-junit4:1.1.0") - androidTestImplementation("androidx.test:core:1.4.0") + androidTestImplementation(benchmarks.benchmark.junit4) + androidTestImplementation(benchmarks.androidx.test.core) } configure { diff --git a/benchmark/settings.gradle.kts b/benchmark/settings.gradle.kts index d88523d810d..0afacb68fe2 100644 --- a/benchmark/settings.gradle.kts +++ b/benchmark/settings.gradle.kts @@ -2,8 +2,25 @@ include(":app", ":microbenchmark") includeBuild("build-logic") -pluginManagement { - repositories { - mavenCentral() + +apply(from = "../gradle/repositories.gradle.kts") + +listOf(pluginManagement.repositories, dependencyResolutionManagement.repositories).forEach { + it.apply { + maven { + url = uri("../build/localMaven") + } + } +} + + +dependencyResolutionManagement { + versionCatalogs { + create("benchmarks") { + from(files("gradle/benchmarks.versions.toml")) + } + create("libs") { + from(files("../gradle/libraries.toml")) + } } } \ No newline at end of file diff --git a/build-logic/src/main/kotlin/CompilerOptions.kt b/build-logic/src/main/kotlin/CompilerOptions.kt index fddbe4d25c2..19469a3b444 100644 --- a/build-logic/src/main/kotlin/CompilerOptions.kt +++ b/build-logic/src/main/kotlin/CompilerOptions.kt @@ -27,7 +27,9 @@ fun Project.configureJavaAndKotlinCompilers() { apiVersion = "1.5" languageVersion = "1.5" - (this as? KotlinJvmOptions)?.jvmTarget = "1.8" + (this as? KotlinJvmOptions)?.let { + it.jvmTarget = "1.8" + } } } tasks.withType(KotlinNativeCompile::class.java).configureEach { diff --git a/gradle/libraries.toml b/gradle/libraries.toml index bd1ad93d28a..6db586db54c 100644 --- a/gradle/libraries.toml +++ b/gradle/libraries.toml @@ -23,8 +23,6 @@ kotlinx-datetime = "0.4.0" kotlinx-serialization-runtime = "1.4.1" ksp = "1.8.20-Beta-1.0.9" ktor = "2.2.2" -moshi = "1.12.0" -moshix = "0.14.1" okhttp = "4.9.3" rx-android = "2.0.1" rx-java2 = "2.2.21" @@ -116,14 +114,12 @@ kotlinx-serialization-json-okio = { group = "org.jetbrains.kotlinx", name = "kot kotlinx-binarycompatibilityvalidator = { group = "org.jetbrains.kotlinx", name = "binary-compatibility-validator", version = "0.10.1" } ksp = { group = "com.google.devtools.ksp", name = "symbol-processing-gradle-plugin", version.ref = "ksp" } ktor-client-js = { group = "io.ktor", name = "ktor-client-js", version.ref = "ktor" } -moshi = { group = "com.squareup.moshi", name = "moshi", version.ref = "moshi" } -moshix-ksp = { group = "dev.zacsweers.moshix", name = "moshi-ksp", version.ref = "moshix" } -moshix-sealed-codegen = { group = "dev.zacsweers.moshix", name = "moshi-sealed-codegen", version.ref = "moshix" } -moshix-sealed-runtime = { group = "dev.zacsweers.moshix", name = "moshi-sealed-runtime", version.ref = "moshix" } okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" } okhttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" } okhttp-mockwebserver = { group = "com.squareup.okhttp3", name = "mockwebserver", version.ref = "okhttp" } okhttp-tls = { group = "com.squareup.okhttp3", name = "okhttp-tls", version.ref = "okhttp" } +moshi = { group = "com.squareup.moshi", name = "moshi", version = "1.12.0" } +okio = "com.squareup.okio:okio-jvm:3.3.0" poet-java = { group = "com.squareup", name = "javapoet", version.ref = "javaPoet" } poet-kotlin = { group = "com.squareup", name = "kotlinpoet", version = "1.12.0" } rx-java2 = { group = "io.reactivex.rxjava2", name = "rxjava", version.ref = "rx-java2" } diff --git a/libraries/apollo-ast/api/apollo-ast.api b/libraries/apollo-ast/api/apollo-ast.api index 8751cde7a91..6888ad6970e 100644 --- a/libraries/apollo-ast/api/apollo-ast.api +++ b/libraries/apollo-ast/api/apollo-ast.api @@ -1434,7 +1434,7 @@ public final class com/apollographql/apollo3/ast/introspection/IntrospectionSche public static final fun toIntrospectionSchema (Lokio/BufferedSource;Ljava/lang/String;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema; public static synthetic fun toIntrospectionSchema$default (Lokio/BufferedSource;Ljava/lang/String;ILjava/lang/Object;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema; public static final fun toJson (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema;)Ljava/lang/String; - public static final fun toJson (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema;Ljava/io/File;)V + public static final fun writeTo (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema;Ljava/io/File;)V } public final class com/apollographql/apollo3/ast/introspection/Introspection_to_schemaKt { diff --git a/libraries/apollo-ast/src/main/kotlin/com/apollographql/apollo3/ast/introspection/IntrospectionSchema.kt b/libraries/apollo-ast/src/main/kotlin/com/apollographql/apollo3/ast/introspection/IntrospectionSchema.kt index b24d3aee7c5..af20ab5c20c 100644 --- a/libraries/apollo-ast/src/main/kotlin/com/apollographql/apollo3/ast/introspection/IntrospectionSchema.kt +++ b/libraries/apollo-ast/src/main/kotlin/com/apollographql/apollo3/ast/introspection/IntrospectionSchema.kt @@ -243,7 +243,7 @@ fun IntrospectionSchema.toJson(): String { return json.encodeToString(IntrospectionSchema.serializer(), this) } -fun IntrospectionSchema.toJson(file: File) { +fun IntrospectionSchema.writeTo(file: File) { file.outputStream().sink().buffer().use { it.writeUtf8(json.encodeToString(IntrospectionSchema.serializer(), this)) } diff --git a/libraries/apollo-compiler/api/apollo-compiler.api b/libraries/apollo-compiler/api/apollo-compiler.api index a21c6c2ca2a..92a3d2fe443 100644 --- a/libraries/apollo-compiler/api/apollo-compiler.api +++ b/libraries/apollo-compiler/api/apollo-compiler.api @@ -14,20 +14,29 @@ public abstract interface class com/apollographql/apollo3/compiler/ApolloCompile } public final class com/apollographql/apollo3/compiler/CodegenMetadata { + public static final field Companion Lcom/apollographql/apollo3/compiler/CodegenMetadata$Companion; + public synthetic fun (ILcom/apollographql/apollo3/compiler/codegen/ResolverInfo;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V public final fun copy (Lcom/apollographql/apollo3/compiler/codegen/ResolverInfo;)Lcom/apollographql/apollo3/compiler/CodegenMetadata; public static synthetic fun copy$default (Lcom/apollographql/apollo3/compiler/CodegenMetadata;Lcom/apollographql/apollo3/compiler/codegen/ResolverInfo;ILjava/lang/Object;)Lcom/apollographql/apollo3/compiler/CodegenMetadata; public fun equals (Ljava/lang/Object;)Z public fun hashCode ()I public fun toString ()Ljava/lang/String; + public static final synthetic fun write$Self (Lcom/apollographql/apollo3/compiler/CodegenMetadata;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V } -public final class com/apollographql/apollo3/compiler/CodegenMetadataJsonAdapter : com/squareup/moshi/JsonAdapter { - public fun (Lcom/squareup/moshi/Moshi;)V - public fun fromJson (Lcom/squareup/moshi/JsonReader;)Lcom/apollographql/apollo3/compiler/CodegenMetadata; - public synthetic fun fromJson (Lcom/squareup/moshi/JsonReader;)Ljava/lang/Object; - public fun toJson (Lcom/squareup/moshi/JsonWriter;Lcom/apollographql/apollo3/compiler/CodegenMetadata;)V - public synthetic fun toJson (Lcom/squareup/moshi/JsonWriter;Ljava/lang/Object;)V - public fun toString ()Ljava/lang/String; +public final class com/apollographql/apollo3/compiler/CodegenMetadata$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lcom/apollographql/apollo3/compiler/CodegenMetadata$$serializer; + public fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/compiler/CodegenMetadata; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/compiler/CodegenMetadata;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class com/apollographql/apollo3/compiler/CodegenMetadata$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; } public final class com/apollographql/apollo3/compiler/CodegenMetadataKt { @@ -140,10 +149,6 @@ public final class com/apollographql/apollo3/compiler/KotlinCodegenOptions { public final fun getSealedClassesForEnumsMatching ()Ljava/util/List; } -public final class com/apollographql/apollo3/compiler/MoshiKt { - public static final fun getMOSHI ()Lcom/squareup/moshi/Moshi; -} - public abstract interface class com/apollographql/apollo3/compiler/OperationIdGenerator { public static final field Companion Lcom/apollographql/apollo3/compiler/OperationIdGenerator$Companion; public abstract fun apply (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; @@ -302,6 +307,8 @@ public final class com/apollographql/apollo3/compiler/VersionKt { } public final class com/apollographql/apollo3/compiler/codegen/ResolverKey { + public static final field Companion Lcom/apollographql/apollo3/compiler/codegen/ResolverKey$Companion; + public synthetic fun (ILcom/apollographql/apollo3/compiler/codegen/ResolverKeyKind;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V public fun (Lcom/apollographql/apollo3/compiler/codegen/ResolverKeyKind;Ljava/lang/String;)V public final fun component1 ()Lcom/apollographql/apollo3/compiler/codegen/ResolverKeyKind; public final fun component2 ()Ljava/lang/String; @@ -312,15 +319,22 @@ public final class com/apollographql/apollo3/compiler/codegen/ResolverKey { public final fun getKind ()Lcom/apollographql/apollo3/compiler/codegen/ResolverKeyKind; public fun hashCode ()I public fun toString ()Ljava/lang/String; + public static final synthetic fun write$Self (Lcom/apollographql/apollo3/compiler/codegen/ResolverKey;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V } -public final class com/apollographql/apollo3/compiler/codegen/ResolverKeyJsonAdapter : com/squareup/moshi/JsonAdapter { - public fun (Lcom/squareup/moshi/Moshi;)V - public fun fromJson (Lcom/squareup/moshi/JsonReader;)Lcom/apollographql/apollo3/compiler/codegen/ResolverKey; - public synthetic fun fromJson (Lcom/squareup/moshi/JsonReader;)Ljava/lang/Object; - public fun toJson (Lcom/squareup/moshi/JsonWriter;Lcom/apollographql/apollo3/compiler/codegen/ResolverKey;)V - public synthetic fun toJson (Lcom/squareup/moshi/JsonWriter;Ljava/lang/Object;)V - public fun toString ()Ljava/lang/String; +public final class com/apollographql/apollo3/compiler/codegen/ResolverKey$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lcom/apollographql/apollo3/compiler/codegen/ResolverKey$$serializer; + public fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/compiler/codegen/ResolverKey; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/compiler/codegen/ResolverKey;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class com/apollographql/apollo3/compiler/codegen/ResolverKey$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; } public final class com/apollographql/apollo3/compiler/codegen/ResolverKeyKind : java/lang/Enum { @@ -400,22 +414,32 @@ public final class com/apollographql/apollo3/compiler/ir/IrSchemaBuilder { } public final class com/apollographql/apollo3/compiler/operationoutput/OperationDescriptor { + public static final field Companion Lcom/apollographql/apollo3/compiler/operationoutput/OperationDescriptor$Companion; + public synthetic fun (ILjava/lang/String;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V public fun (Ljava/lang/String;Ljava/lang/String;)V public final fun getName ()Ljava/lang/String; public final fun getSource ()Ljava/lang/String; + public static final synthetic fun write$Self (Lcom/apollographql/apollo3/compiler/operationoutput/OperationDescriptor;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V } -public final class com/apollographql/apollo3/compiler/operationoutput/OperationDescriptorJsonAdapter : com/squareup/moshi/JsonAdapter { - public fun (Lcom/squareup/moshi/Moshi;)V - public fun fromJson (Lcom/squareup/moshi/JsonReader;)Lcom/apollographql/apollo3/compiler/operationoutput/OperationDescriptor; - public synthetic fun fromJson (Lcom/squareup/moshi/JsonReader;)Ljava/lang/Object; - public fun toJson (Lcom/squareup/moshi/JsonWriter;Lcom/apollographql/apollo3/compiler/operationoutput/OperationDescriptor;)V - public synthetic fun toJson (Lcom/squareup/moshi/JsonWriter;Ljava/lang/Object;)V - public fun toString ()Ljava/lang/String; +public final class com/apollographql/apollo3/compiler/operationoutput/OperationDescriptor$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lcom/apollographql/apollo3/compiler/operationoutput/OperationDescriptor$$serializer; + public fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/compiler/operationoutput/OperationDescriptor; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/compiler/operationoutput/OperationDescriptor;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class com/apollographql/apollo3/compiler/operationoutput/OperationDescriptor$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; } public final class com/apollographql/apollo3/compiler/operationoutput/OperationOutputKt { public static final fun findOperationId (Ljava/util/Map;Ljava/lang/String;)Ljava/lang/String; - public static final fun toOperationOutput (Lokio/BufferedSource;)Ljava/util/Map; + public static final fun toOperationOutput (Ljava/io/File;)Ljava/util/Map; + public static final fun writeTo (Ljava/util/Map;Ljava/io/File;)V } diff --git a/libraries/apollo-compiler/build.gradle.kts b/libraries/apollo-compiler/build.gradle.kts index 74b6a626689..9a28f7e1b3a 100644 --- a/libraries/apollo-compiler/build.gradle.kts +++ b/libraries/apollo-compiler/build.gradle.kts @@ -3,7 +3,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("org.jetbrains.kotlin.jvm") id("apollo.library") - id("com.google.devtools.ksp") id("org.jetbrains.kotlin.plugin.serialization") } @@ -22,14 +21,9 @@ dependencies { } api(golatac.lib("poet.java")) - implementation(golatac.lib("moshi")) - implementation(golatac.lib("moshix.sealed.runtime")) implementation(golatac.lib("kotlinx.serialization.json")) implementation(golatac.lib("kotlinx.serialization.json.okio")) - ksp(golatac.lib("moshix.sealed.codegen")) - ksp(golatac.lib("moshix.ksp")) - testImplementation(golatac.lib("kotlin.compiletesting")) testImplementation(golatac.lib("google.testing.compile")) testImplementation(golatac.lib("truth")) diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/ApolloCompiler.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/ApolloCompiler.kt index 3dc6b5b497e..054d95d0f6c 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/ApolloCompiler.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/ApolloCompiler.kt @@ -30,6 +30,7 @@ import com.apollographql.apollo3.compiler.ir.IrSchemaBuilder import com.apollographql.apollo3.compiler.ir.toIrOperations import com.apollographql.apollo3.compiler.operationoutput.OperationDescriptor import com.apollographql.apollo3.compiler.operationoutput.OperationOutput +import com.apollographql.apollo3.compiler.operationoutput.writeTo import okio.buffer import okio.source import java.io.File @@ -271,7 +272,9 @@ object ApolloCompiler { """.trimMargin() } - operationOutputFile?.writeText(operationOutput.toJson(" ")) + if (operationOutputFile != null) { + operationOutput.writeTo(operationOutputFile) + } return operationOutput } diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/CodegenMetadata.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/CodegenMetadata.kt index 8ab602c1c7a..b9e34a373a8 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/CodegenMetadata.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/CodegenMetadata.kt @@ -2,14 +2,17 @@ package com.apollographql.apollo3.compiler import com.apollographql.apollo3.compiler.codegen.ResolverInfo import com.apollographql.apollo3.compiler.codegen.ResolverKeyKind -import com.squareup.moshi.JsonClass -import com.squareup.moshi.Moshi +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.okio.decodeFromBufferedSource +import kotlinx.serialization.json.okio.encodeToBufferedSink import okio.buffer import okio.sink import okio.source import java.io.File -@JsonClass(generateAdapter = true) +@Serializable data class CodegenMetadata internal constructor( /** * resolver info used by the codegen to lookup already existing ClassNames @@ -21,18 +24,17 @@ fun CodegenMetadata.schemaTypes(): Set { return resolverInfo.entries.filter { it.key.kind == ResolverKeyKind.SchemaType }.map { it.key.id }.toSet() } -private val adapter = Moshi.Builder() - .build() - .adapter(CodegenMetadata::class.java) - +@OptIn(ExperimentalSerializationApi::class) fun CodegenMetadata.writeTo(file: File) { file.sink().buffer().use { - adapter.toJson(it, this) + Json.encodeToBufferedSink(CodegenMetadata.serializer(), this, it) } + } +@OptIn(ExperimentalSerializationApi::class) fun File.toCodegenMetadata(): CodegenMetadata { return source().buffer().use { - adapter.fromJson(it)!! + Json.decodeFromBufferedSource(CodegenMetadata.serializer(), it) } -} \ No newline at end of file +} diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/Options.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/Options.kt index b01982816fe..6814cbd9989 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/Options.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/Options.kt @@ -7,8 +7,6 @@ import com.apollographql.apollo3.compiler.hooks.ApolloCompilerKotlinHooks import com.apollographql.apollo3.compiler.ir.IrOperations import com.apollographql.apollo3.compiler.ir.IrSchema import com.apollographql.apollo3.compiler.operationoutput.OperationOutput -import com.squareup.moshi.JsonClass -import dev.zacsweers.moshix.sealed.annotations.TypeLabel import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import java.io.File diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/Resolver.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/Resolver.kt index 7c70263a445..b0d25c05c84 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/Resolver.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/Resolver.kt @@ -1,31 +1,31 @@ package com.apollographql.apollo3.compiler.codegen -import com.squareup.moshi.JsonClass +import kotlinx.serialization.Serializable /** * Additional resolver data generated alongside the models and adapters. * This data maps a GraphQL identifier (such as a typename or model path) to its target class. * This allows children modules to reference classes generated in parents (and know when to skip generating them). */ -@JsonClass(generateAdapter = true) +@Serializable internal class ResolverInfo( val magic: String, val version: String, val entries: List ) -@JsonClass(generateAdapter = true) +@Serializable internal class ResolverClassName(val packageName: String, val simpleNames: List) { constructor(packageName: String, vararg simpleNames: String): this(packageName, simpleNames.toList()) } -@JsonClass(generateAdapter = true) +@Serializable internal class ResolverMemberName(val className: ResolverClassName, val name: String) /** * Must be a data class because it is used as a key in resolvers */ -@JsonClass(generateAdapter = true) +@Serializable data class ResolverKey(val kind: ResolverKeyKind, val id: String) enum class ResolverKeyKind { @@ -47,7 +47,7 @@ enum class ResolverKeyKind { Pagination } -@JsonClass(generateAdapter = true) +@Serializable internal class ResolverEntry( val key: ResolverKey, val className: ResolverClassName diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/moshi.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/moshi.kt deleted file mode 100644 index 1948b5778d0..00000000000 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/moshi.kt +++ /dev/null @@ -1,64 +0,0 @@ -package com.apollographql.apollo3.compiler - -import com.squareup.moshi.JsonAdapter -import com.squareup.moshi.JsonReader -import com.squareup.moshi.Moshi -import com.squareup.moshi.Types -import okio.buffer -import okio.sink -import okio.source -import java.io.File -import java.io.InputStream - -val MOSHI: Moshi by lazy { - Moshi.Builder().build() -} - -inline fun getJsonAdapter() = MOSHI.adapter(T::class.java) - -inline fun getJsonListAdapter(): JsonAdapter> { - val type = Types.newParameterizedType(List::class.java, T::class.java) - return MOSHI.adapter(type) -} - -inline fun String.fromJson(): T { - return getJsonAdapter().fromJson(this)!! -} - -inline fun JsonReader.fromJson(): T { - return getJsonAdapter().fromJson(this)!! -} - -inline fun InputStream.fromJson(): T { - use { - return getJsonAdapter().fromJson(it.source().buffer())!! - } -} - -inline fun File.fromJson(): T { - return inputStream().fromJson() -} - -inline fun String.fromJsonList(): List { - return getJsonListAdapter().fromJson(this)!! -} - -inline fun InputStream.fromJsonList(): List { - use { - return getJsonListAdapter().fromJson(it.source().buffer())!! - } -} - -inline fun File.fromJsonList(): List { - return inputStream().fromJsonList() -} - -inline fun T.toJson(indent: String = ""): String { - return getJsonAdapter().indent(indent).toJson(this) -} - -inline fun T.toJson(file: File, indent: String = "") { - file.outputStream().sink().buffer().use { - return getJsonAdapter().indent(indent).toJson(it, this) - } -} diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/operationoutput/OperationOutput.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/operationoutput/OperationOutput.kt index 0da4b847bc8..48df1c88a87 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/operationoutput/OperationOutput.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/operationoutput/OperationOutput.kt @@ -1,10 +1,14 @@ package com.apollographql.apollo3.compiler.operationoutput -import com.apollographql.apollo3.compiler.MOSHI -import com.squareup.moshi.JsonAdapter -import com.squareup.moshi.JsonClass -import com.squareup.moshi.Types -import okio.BufferedSource +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.okio.decodeFromBufferedSource +import kotlinx.serialization.json.okio.encodeToBufferedSink +import okio.buffer +import okio.sink +import okio.source +import java.io.File /** * [OperationOutput] is a map where the operationId is the key and [OperationDescriptor] the value @@ -16,7 +20,7 @@ typealias OperationOutput = Map /** * This structure is also generated by other tools (iOS, cli, ...), try to keep the field names if possible. */ -@JsonClass(generateAdapter = true) +@Serializable class OperationDescriptor( val name: String, val source: String @@ -30,11 +34,17 @@ fun OperationOutput.findOperationId(name: String): String { return id } -fun BufferedSource.toOperationOutput(): OperationOutput { - return operationOutputAdapter().fromJson(this)!! +@OptIn(ExperimentalSerializationApi::class) +fun OperationOutput.writeTo(file: File) { + file.sink().buffer().use { + Json.encodeToBufferedSink>(this, it) + } + } -private fun operationOutputAdapter(): JsonAdapter { - val type = Types.newParameterizedType(Map::class.java, String::class.java, OperationDescriptor::class.java) - return MOSHI.adapter(type) +@OptIn(ExperimentalSerializationApi::class) +fun File.toOperationOutput(): OperationOutput { + return source().buffer().use { + Json.decodeFromBufferedSource>(it) + } } diff --git a/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/ApolloConvertSchemaTask.kt b/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/ApolloConvertSchemaTask.kt index fc0c8e1a281..8c914680ffd 100644 --- a/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/ApolloConvertSchemaTask.kt +++ b/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/ApolloConvertSchemaTask.kt @@ -2,7 +2,7 @@ package com.apollographql.apollo3.gradle.internal import com.apollographql.apollo3.ast.introspection.toGQLDocument import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema -import com.apollographql.apollo3.ast.introspection.toJson +import com.apollographql.apollo3.ast.introspection.writeTo import com.apollographql.apollo3.ast.introspection.toSchema import com.apollographql.apollo3.ast.toUtf8 import org.gradle.api.DefaultTask @@ -47,7 +47,7 @@ abstract class ApolloConvertSchemaTask : DefaultTask() { if (from.isIntrospection()) { from.toIntrospectionSchema().toGQLDocument().toUtf8(to) } else { - from.toSchema().toIntrospectionSchema().toJson(to) + from.toSchema().toIntrospectionSchema().writeTo(to) } } diff --git a/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/ApolloRegisterOperationsTask.kt b/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/ApolloRegisterOperationsTask.kt index a5ed5254add..972465b7c3a 100644 --- a/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/ApolloRegisterOperationsTask.kt +++ b/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/ApolloRegisterOperationsTask.kt @@ -30,7 +30,7 @@ abstract class ApolloRegisterOperationsTask: DefaultTask() { key = key.get() ?: error("key is required to register operations"), graphID = graph.get() ?: error("graphID is required to register operations"), graphVariant = graphVariant.get() ?: error("graphVariant is required to register operations"), - operationOutput = operationOutput.get().asFile.source().buffer().toOperationOutput() + operationOutput = operationOutput.get().asFile.toOperationOutput() ) } } \ No newline at end of file diff --git a/libraries/apollo-tooling/api/apollo-tooling.api b/libraries/apollo-tooling/api/apollo-tooling.api index e69de29bb2d..bacf821b822 100644 --- a/libraries/apollo-tooling/api/apollo-tooling.api +++ b/libraries/apollo-tooling/api/apollo-tooling.api @@ -0,0 +1,4 @@ +public final class com/apollographql/apollo3/tooling/SerializationKt { + public static final fun toJsonElement (Ljava/lang/Object;)Lkotlinx/serialization/json/JsonElement; +} + diff --git a/libraries/apollo-tooling/build.gradle.kts b/libraries/apollo-tooling/build.gradle.kts index ebe733f4c88..e222dd0c57d 100644 --- a/libraries/apollo-tooling/build.gradle.kts +++ b/libraries/apollo-tooling/build.gradle.kts @@ -4,14 +4,13 @@ plugins { } dependencies { + api(project(":apollo-compiler")) + implementation(project(":apollo-annotations")) implementation(project(":apollo-ast")) - api(project(":apollo-compiler")) - implementation(golatac.lib("moshi")) - implementation(golatac.lib("moshix.sealed.runtime")) implementation(golatac.lib("okhttp")) + implementation(golatac.lib("kotlinx.serialization.json")) - implementation(golatac.lib("moshi")) testImplementation(golatac.lib("junit")) testImplementation(golatac.lib("truth")) } diff --git a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/RegisterOperations.kt b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/RegisterOperations.kt index 57008a71321..3b499a84579 100644 --- a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/RegisterOperations.kt +++ b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/RegisterOperations.kt @@ -26,9 +26,9 @@ import com.apollographql.apollo3.ast.toUtf8 import com.apollographql.apollo3.ast.transform import com.apollographql.apollo3.compiler.APOLLO_VERSION import com.apollographql.apollo3.compiler.OperationIdGenerator -import com.apollographql.apollo3.compiler.fromJson import com.apollographql.apollo3.compiler.operationoutput.OperationOutput import com.apollographql.apollo3.tooling.SchemaDownloader.cast +import kotlinx.serialization.json.Json import okio.Buffer @@ -58,10 +58,6 @@ private fun GQLDirective.score() = name private fun GQLArgument.score() = name -private fun isEmpty(s: String?): Boolean { - return s == null || s.trim { it <= ' ' }.length == 0 -} - private fun List.join( writer: SDLWriter, separator: String = " ", @@ -209,6 +205,7 @@ object RegisterOperations { is GQLIntValue -> { TransformResult.Replace(it.copy(value = 0)) } + is GQLFloatValue -> { /** * Because in JS (0.0).toString == "0" (vs "0.0" on the JVM), we replace the FloatValue by an IntValue @@ -222,16 +219,18 @@ object RegisterOperations { ) ) } + is GQLStringValue -> { TransformResult.Replace(it.copy(value = "")) } + else -> TransformResult.Continue } } /** * Algorithm taken from https://github.com/apollographql/apollo-tooling/blob/6d69f226c2e2c54b4fc0de6394d813bddfb54694/packages/apollo-graphql/src/transforms.ts#L102 - * It's not 100% exact but it's important that it matches what apollo-tooling is doing for safelisting + * It's not 100% exact, but it's important that it matches what apollo-tooling is doing for safelisting * * Especially: * - it doesn't sort inline fragment @@ -239,12 +238,10 @@ object RegisterOperations { */ val sortedDocument = hiddenLiterals!!.sort() - val minimized = printDocument(sortedDocument) + return printDocument(sortedDocument) .replace(Regex("\\s+"), " ") .replace(Regex("([^_a-zA-Z0-9]) ")) { it.groupValues[1] } .replace(Regex(" ([^_a-zA-Z0-9])")) { it.groupValues[1] } - - return minimized } fun String.safelistingHash(): String { @@ -282,7 +279,8 @@ object RegisterOperations { val responseString = response.body.use { it?.string() } val errors = responseString - ?.fromJson>() + ?.let { Json.parseToJsonElement(it) } + ?.toAny().cast>() ?.get("data").cast>() ?.get("service").cast>() ?.get("registerOperationsWithResponse").cast>() @@ -296,7 +294,8 @@ object RegisterOperations { } val success = responseString - ?.fromJson>() + ?.let { Json.parseToJsonElement(it) } + ?.toAny().cast>() ?.get("data").cast>() ?.get("service").cast>() ?.get("registerOperationsWithResponse").cast>() diff --git a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaDownloader.kt b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaDownloader.kt index 0d6fa493fb3..4fccbcf7521 100644 --- a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaDownloader.kt +++ b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaDownloader.kt @@ -5,11 +5,20 @@ import com.apollographql.apollo3.ast.GQLDocument import com.apollographql.apollo3.ast.introspection.IntrospectionSchema import com.apollographql.apollo3.ast.introspection.toGQLDocument import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema +import com.apollographql.apollo3.ast.introspection.writeTo import com.apollographql.apollo3.ast.parseAsGQLDocument import com.apollographql.apollo3.ast.toUtf8 import com.apollographql.apollo3.ast.validateAsSchema -import com.apollographql.apollo3.compiler.fromJson -import com.apollographql.apollo3.compiler.toJson +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonNull +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.booleanOrNull +import kotlinx.serialization.json.doubleOrNull +import kotlinx.serialization.json.intOrNull +import kotlinx.serialization.json.longOrNull import okio.Buffer import java.io.File @@ -101,7 +110,7 @@ object SchemaDownloader { if (schema.extension.lowercase() == "json") { if (introspectionSchema == null) { introspectionSchema = gqlSchema!!.validateAsSchema().valueAssertNoErrors().toIntrospectionSchema() - schema.writeText(introspectionSchema.toJson(indent = " ")) + introspectionSchema.writeTo(schema) } else { schema.writeText(introspectionSchemaJson!!) } @@ -159,7 +168,8 @@ object SchemaDownloader { val responseString = response.body.use { it?.string() } val document = responseString - ?.fromJson>() + ?.let { Json.parseToJsonElement(it) } + ?.toAny().cast>() ?.get("data").cast>() ?.get("service").cast>() ?.get("variant").cast>() diff --git a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaHelper.kt b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaHelper.kt index 1497454507e..6627c6176c6 100644 --- a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaHelper.kt +++ b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaHelper.kt @@ -1,6 +1,5 @@ package com.apollographql.apollo3.tooling -import com.apollographql.apollo3.compiler.toJson import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.OkHttpClient import okhttp3.Request @@ -40,7 +39,7 @@ internal object SchemaHelper { } internal fun executeQuery(map: Map, url: String, headers: Map, insecure: Boolean): Response { - val body = map.toJson().toByteArray().toRequestBody("application/json".toMediaTypeOrNull()) + val body = map.toJsonElement().toString().toRequestBody("application/json".toMediaTypeOrNull()) val request = Request.Builder() .post(body) .apply { diff --git a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaUploader.kt b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaUploader.kt index 069d1abd65c..fbebfec4363 100644 --- a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaUploader.kt +++ b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaUploader.kt @@ -1,8 +1,8 @@ package com.apollographql.apollo3.tooling import com.apollographql.apollo3.annotations.ApolloExperimental -import com.apollographql.apollo3.compiler.fromJson import com.apollographql.apollo3.tooling.SchemaDownloader.cast +import kotlinx.serialization.json.Json @ApolloExperimental object SchemaUploader { @@ -42,7 +42,8 @@ object SchemaUploader { val responseString = response.body.use { it?.string() } val uploadSchema = responseString - ?.fromJson>() + ?.let { Json.parseToJsonElement(it) } + ?.toAny().cast>() ?.get("data").cast>() ?.get("service").cast>() ?.get("uploadSchema").cast>() diff --git a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/serialization.kt b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/serialization.kt new file mode 100644 index 00000000000..37d3153c56e --- /dev/null +++ b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/serialization.kt @@ -0,0 +1,35 @@ +package com.apollographql.apollo3.tooling + +import com.apollographql.apollo3.tooling.SchemaDownloader.cast +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonNull +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.booleanOrNull +import kotlinx.serialization.json.doubleOrNull +import kotlinx.serialization.json.intOrNull +import kotlinx.serialization.json.longOrNull + +internal fun JsonElement.toAny(): Any? = when (this) { + is JsonObject -> this.mapValues { it.value.toAny() } + is JsonArray -> this.map { it.toAny() } + is JsonPrimitive -> { + when { + isString -> this.content + this is JsonNull -> null + else -> booleanOrNull ?: intOrNull ?: longOrNull ?: doubleOrNull ?: error("cannot decode $this") + } + } + else -> error("cannot convert $this to Any") +} + +fun Any?.toJsonElement(): JsonElement = when (this) { + is Map<*, *> -> JsonObject(this.cast>()!!.mapValues { it.value.toJsonElement() }) + is List<*> -> JsonArray(map { it.toJsonElement() }) + is Boolean -> JsonPrimitive(this) + is Number -> JsonPrimitive(this) + is String -> JsonPrimitive(this) + null -> JsonNull + else -> error("cannot convert $this to JsonElement") +} \ No newline at end of file