Skip to content

Commit 3518b1d

Browse files
committed
Define and plug Polymorphic annotation PolymorphicAdapterFactory class
1 parent 78ba5fb commit 3518b1d

File tree

5 files changed

+90
-0
lines changed

5 files changed

+90
-0
lines changed

gradle-plugin/plugin/src/main/java/com/yelp/codegen/KotlinGenerator.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ open class KotlinGenerator : SharedCodegen() {
125125
"CollectionFormats.kt",
126126
"EnumToValueConverterFactory.kt",
127127
"GeneratedCodeConverters.kt",
128+
"OptimisticHashCode.kt",
129+
"PolymorphicAdapterFactory.kt",
128130
"TypesAdapters.kt",
129131
"WrapperConverterFactory.kt",
130132
"XNullable.kt",
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package {{packageName}}.tools
2+
3+
@Suppress("NOTHING_TO_INLINE")
4+
internal inline fun <T> T.optimisticHashCode(): Int = this?.hashCode() ?: 0
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package {{packageName}}.tools
2+
3+
import com.squareup.moshi.JsonAdapter
4+
import com.squareup.moshi.Moshi
5+
import com.squareup.moshi.Types
6+
import com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory
7+
import java.lang.reflect.Type
8+
import kotlin.reflect.KClass
9+
10+
@Target(AnnotationTarget.CLASS)
11+
@Retention(AnnotationRetention.RUNTIME)
12+
internal annotation class Polymorphic(
13+
val discriminatorField: String,
14+
val discriminatedValues: Array<String>,
15+
val discriminatedClasses: Array<KClass<*>>
16+
)
17+
18+
internal class PolymorphicAdapterFactory : JsonAdapter.Factory {
19+
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi): JsonAdapter<*>? {
20+
val rawType = Types.getRawType(type)
21+
return rawType.getAnnotation(Polymorphic::class.java)?.let { annotation ->
22+
@Suppress("UNCHECKED_CAST")
23+
val polymorphicJsonAdapterFactory: PolymorphicJsonAdapterFactory<Any> = PolymorphicJsonAdapterFactory.of(
24+
rawType, annotation.discriminatorField
25+
) as? PolymorphicJsonAdapterFactory<Any> ?: return@let null
26+
27+
return annotation.discriminatedClasses.zip(annotation.discriminatedValues).fold(
28+
initial = polymorphicJsonAdapterFactory.withFallbackJsonAdapter(
29+
moshi.nextAdapter<Any>(
30+
this@PolymorphicAdapterFactory,
31+
type,
32+
annotations
33+
)
34+
)
35+
) { jsonAdapterFactory, (klass, label) ->
36+
jsonAdapterFactory.withSubtype(klass.java, label)
37+
}.create(type, annotations, moshi)
38+
}
39+
}
40+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.yelp.codegen.generatecodesamples.tools
2+
3+
@Suppress("NOTHING_TO_INLINE")
4+
internal inline fun <T> T.optimisticHashCode(): Int = this?.hashCode() ?: 0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.yelp.codegen.generatecodesamples.tools
2+
3+
import com.squareup.moshi.JsonAdapter
4+
import com.squareup.moshi.Moshi
5+
import com.squareup.moshi.Types
6+
import com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory
7+
import java.lang.reflect.Type
8+
import kotlin.reflect.KClass
9+
10+
@Target(AnnotationTarget.CLASS)
11+
@Retention(AnnotationRetention.RUNTIME)
12+
internal annotation class Polymorphic(
13+
val discriminatorField: String,
14+
val discriminatedValues: Array<String>,
15+
val discriminatedClasses: Array<KClass<*>>
16+
)
17+
18+
internal class PolymorphicAdapterFactory : JsonAdapter.Factory {
19+
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi): JsonAdapter<*>? {
20+
val rawType = Types.getRawType(type)
21+
return rawType.getAnnotation(Polymorphic::class.java)?.let { annotation ->
22+
@Suppress("UNCHECKED_CAST")
23+
val polymorphicJsonAdapterFactory: PolymorphicJsonAdapterFactory<Any> = PolymorphicJsonAdapterFactory.of(
24+
rawType, annotation.discriminatorField
25+
) as? PolymorphicJsonAdapterFactory<Any> ?: return@let null
26+
27+
return annotation.discriminatedClasses.zip(annotation.discriminatedValues).fold(
28+
initial = polymorphicJsonAdapterFactory.withFallbackJsonAdapter(
29+
moshi.nextAdapter<Any>(
30+
this@PolymorphicAdapterFactory,
31+
type,
32+
annotations
33+
)
34+
)
35+
) { jsonAdapterFactory, (klass, label) ->
36+
jsonAdapterFactory.withSubtype(klass.java, label)
37+
}.create(type, annotations, moshi)
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)