-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
143 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
src/main/kotlin/com/github/avrokotlin/avro4k/internal/decoder/AbstractPolymorphicDecoder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.github.avrokotlin.avro4k.internal.decoder | ||
|
||
import com.github.avrokotlin.avro4k.Avro | ||
import com.github.avrokotlin.avro4k.internal.IllegalIndexedAccessError | ||
import com.github.avrokotlin.avro4k.internal.isNamedSchema | ||
import kotlinx.serialization.DeserializationStrategy | ||
import kotlinx.serialization.SerializationException | ||
import kotlinx.serialization.descriptors.SerialDescriptor | ||
import kotlinx.serialization.encoding.AbstractDecoder | ||
import kotlinx.serialization.encoding.Decoder | ||
import kotlinx.serialization.modules.SerializersModule | ||
import org.apache.avro.Schema | ||
|
||
internal abstract class AbstractPolymorphicDecoder( | ||
protected val avro: Avro, | ||
private val descriptor: SerialDescriptor, | ||
private val schema: Schema, | ||
) : AbstractDecoder() { | ||
final override val serializersModule: SerializersModule | ||
get() = avro.serializersModule | ||
|
||
private lateinit var chosenSchema: Schema | ||
|
||
final override fun decodeString(): String { | ||
return tryFindSerialName()?.also { chosenSchema = it.second }?.first | ||
?: throw SerializationException("Unknown schema name '${schema.fullName}' for polymorphic type ${descriptor.serialName}. Full schema: $schema") | ||
} | ||
|
||
private fun tryFindSerialName(): Pair<String, Schema>? { | ||
val namesAndAliasesToSerialName: Map<String, String> = avro.polymorphicResolver.getFullNamesAndAliasesToSerialName(descriptor) | ||
return tryFindSerialName(namesAndAliasesToSerialName, schema) | ||
} | ||
|
||
protected abstract fun tryFindSerialNameForUnion( | ||
namesAndAliasesToSerialName: Map<String, String>, | ||
schema: Schema, | ||
): Pair<String, Schema>? | ||
|
||
protected fun tryFindSerialName( | ||
namesAndAliasesToSerialName: Map<String, String>, | ||
schema: Schema, | ||
): Pair<String, Schema>? { | ||
if (schema.isUnion) { | ||
return tryFindSerialNameForUnion(namesAndAliasesToSerialName, schema) | ||
} | ||
return ( | ||
namesAndAliasesToSerialName[schema.fullName] | ||
?: schema.takeIf { it.isNamedSchema() }?.aliases?.firstNotNullOfOrNull { namesAndAliasesToSerialName[it] } | ||
) | ||
?.let { it to schema } | ||
} | ||
|
||
final override fun <T> decodeSerializableValue(deserializer: DeserializationStrategy<T>): T { | ||
return newDecoder(chosenSchema) | ||
.decodeSerializableValue(deserializer) | ||
} | ||
|
||
abstract fun newDecoder(chosenSchema: Schema): Decoder | ||
|
||
final override fun decodeSequentially() = true | ||
|
||
final override fun decodeElementIndex(descriptor: SerialDescriptor): Int { | ||
throw IllegalIndexedAccessError() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 14 additions & 31 deletions
45
...kotlin/com/github/avrokotlin/avro4k/internal/decoder/generic/PolymorphicGenericDecoder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,25 @@ | ||
package com.github.avrokotlin.avro4k.internal.decoder.generic | ||
|
||
import com.github.avrokotlin.avro4k.Avro | ||
import com.github.avrokotlin.avro4k.internal.IllegalIndexedAccessError | ||
import kotlinx.serialization.DeserializationStrategy | ||
import kotlinx.serialization.SerializationException | ||
import com.github.avrokotlin.avro4k.internal.decoder.AbstractPolymorphicDecoder | ||
import kotlinx.serialization.descriptors.SerialDescriptor | ||
import kotlinx.serialization.encoding.AbstractDecoder | ||
import kotlinx.serialization.modules.SerializersModule | ||
import kotlinx.serialization.encoding.Decoder | ||
import org.apache.avro.Schema | ||
import org.apache.avro.generic.IndexedRecord | ||
|
||
internal class PolymorphicGenericDecoder( | ||
private val avro: Avro, | ||
private val descriptor: SerialDescriptor, | ||
private val value: IndexedRecord, | ||
) : AbstractDecoder() { | ||
override val serializersModule: SerializersModule | ||
get() = avro.serializersModule | ||
|
||
override fun decodeString(): String { | ||
return tryFindSerialName(value.schema) | ||
?: throw SerializationException("Unknown schema name ${value.schema.fullName} for polymorphic type ${descriptor.serialName}") | ||
} | ||
|
||
private fun tryFindSerialName(schema: Schema): String? { | ||
val namesAndAliasesToSerialName = avro.polymorphicResolver.getFullNamesAndAliasesToSerialName(descriptor) | ||
return namesAndAliasesToSerialName[schema.fullName] | ||
?: schema.aliases.firstNotNullOfOrNull { namesAndAliasesToSerialName[it] } | ||
avro: Avro, | ||
descriptor: SerialDescriptor, | ||
schema: Schema, | ||
private val value: Any?, | ||
) : AbstractPolymorphicDecoder(avro, descriptor, schema) { | ||
override fun tryFindSerialNameForUnion( | ||
namesAndAliasesToSerialName: Map<String, String>, | ||
schema: Schema, | ||
): Pair<String, Schema>? { | ||
return schema.types.firstNotNullOfOrNull { tryFindSerialName(namesAndAliasesToSerialName, it) } | ||
} | ||
|
||
override fun <T> decodeSerializableValue(deserializer: DeserializationStrategy<T>): T { | ||
return AvroValueGenericDecoder(avro, value, value.schema) | ||
.decodeSerializableValue(deserializer) | ||
} | ||
|
||
override fun decodeSequentially() = true | ||
|
||
override fun decodeElementIndex(descriptor: SerialDescriptor): Int { | ||
throw IllegalIndexedAccessError() | ||
override fun newDecoder(chosenSchema: Schema): Decoder { | ||
return AvroValueGenericDecoder(avro, value, chosenSchema) | ||
} | ||
} |
Oops, something went wrong.