summaryrefslogtreecommitdiff
path: root/core/commonMain/src/kotlinx/serialization/internal/Enums.kt
diff options
context:
space:
mode:
Diffstat (limited to 'core/commonMain/src/kotlinx/serialization/internal/Enums.kt')
-rw-r--r--core/commonMain/src/kotlinx/serialization/internal/Enums.kt73
1 files changed, 66 insertions, 7 deletions
diff --git a/core/commonMain/src/kotlinx/serialization/internal/Enums.kt b/core/commonMain/src/kotlinx/serialization/internal/Enums.kt
index 1e620154..90800d7b 100644
--- a/core/commonMain/src/kotlinx/serialization/internal/Enums.kt
+++ b/core/commonMain/src/kotlinx/serialization/internal/Enums.kt
@@ -49,20 +49,79 @@ internal class EnumDescriptor(
}
}
-// Used for enums that are not explicitly serializable by the plugin
+@OptIn(ExperimentalSerializationApi::class)
+@InternalSerializationApi
+internal fun <T : Enum<T>> createSimpleEnumSerializer(serialName: String, values: Array<T>): KSerializer<T> {
+ return EnumSerializer(serialName, values)
+}
+
+/**
+ * The function has a bug (#2121) and should not be used by new (1.8.20+) plugins. It is preserved for backward compatibility with previously compiled enum classes.
+ */
+@OptIn(ExperimentalSerializationApi::class)
+@InternalSerializationApi
+internal fun <T : Enum<T>> createMarkedEnumSerializer(
+ serialName: String,
+ values: Array<T>,
+ names: Array<String?>,
+ annotations: Array<Array<Annotation>?>
+): KSerializer<T> {
+ val descriptor = EnumDescriptor(serialName, values.size)
+ values.forEachIndexed { i, v ->
+ val elementName = names.getOrNull(i) ?: v.name
+ descriptor.addElement(elementName)
+ annotations.getOrNull(i)?.forEach {
+ descriptor.pushAnnotation(it)
+ }
+ }
+
+ return EnumSerializer(serialName, values, descriptor)
+}
+
+@OptIn(ExperimentalSerializationApi::class)
+@InternalSerializationApi
+internal fun <T : Enum<T>> createAnnotatedEnumSerializer(
+ serialName: String,
+ values: Array<T>,
+ names: Array<String?>,
+ entryAnnotations: Array<Array<Annotation>?>,
+ classAnnotations: Array<Annotation>?
+): KSerializer<T> {
+ val descriptor = EnumDescriptor(serialName, values.size)
+ classAnnotations?.forEach {
+ descriptor.pushClassAnnotation(it)
+ }
+ values.forEachIndexed { i, v ->
+ val elementName = names.getOrNull(i) ?: v.name
+ descriptor.addElement(elementName)
+ entryAnnotations.getOrNull(i)?.forEach {
+ descriptor.pushAnnotation(it)
+ }
+ }
+
+ return EnumSerializer(serialName, values, descriptor)
+}
+
@PublishedApi
@OptIn(ExperimentalSerializationApi::class)
internal class EnumSerializer<T : Enum<T>>(
serialName: String,
private val values: Array<T>
) : KSerializer<T> {
+ private var overriddenDescriptor: SerialDescriptor? = null
- override val descriptor: SerialDescriptor = buildSerialDescriptor(serialName, SerialKind.ENUM) {
- values.forEach {
- val fqn = "$serialName.${it.name}"
- val enumMemberDescriptor = buildSerialDescriptor(fqn, StructureKind.OBJECT)
- element(it.name, enumMemberDescriptor)
- }
+ internal constructor(serialName: String, values: Array<T>, descriptor: SerialDescriptor) : this(serialName, values) {
+ overriddenDescriptor = descriptor
+ }
+
+ override val descriptor: SerialDescriptor by lazy {
+ overriddenDescriptor ?: createUnmarkedDescriptor(serialName)
+ }
+
+ private fun createUnmarkedDescriptor(serialName: String): SerialDescriptor {
+ val d = EnumDescriptor(serialName, values.size)
+ values.forEach { d.addElement(it.name) }
+ return d
}
override fun serialize(encoder: Encoder, value: T) {