1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
/*
* Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
@file:Suppress("DEPRECATION_ERROR")
package kotlinx.serialization.internal
import kotlinx.serialization.*
/*
* Descriptor used for explicitly serializable enums by the plugin.
* Designed to be consistent with `EnumSerializer.descriptor` and weird plugin usage.
*/
@InternalSerializationApi
@Deprecated(level = DeprecationLevel.HIDDEN, message = "For plugin-generated code")
public class EnumDescriptor(
name: String,
elementsCount: Int
) : SerialClassDescImpl(name, elementsCount = elementsCount) {
override val kind: SerialKind = UnionKind.ENUM_KIND
private val elementDescriptors by lazy {
Array(elementsCount) { SerialDescriptor(name + "." + getElementName(it), StructureKind.OBJECT) }
}
override fun getElementDescriptor(index: Int): SerialDescriptor = elementDescriptors.getChecked(index)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null) return false
if (other !is SerialDescriptor) return false
if (other.kind !== UnionKind.ENUM_KIND) return false
if (serialName != other.serialName) return false
if (elementNames() != other.elementNames()) return false
return true
}
override fun toString(): String {
return elementNames().joinToString(", ", "$serialName(", ")")
}
override fun hashCode(): Int {
var result = serialName.hashCode()
result = 31 * result + elementNames().hashCode()
return result
}
}
// Used for enums that are not explicitly serializable
@InternalSerializationApi
@Deprecated(level = DeprecationLevel.ERROR, message = "For plugin-generated code, " +
"should not be used directly. For the custom serializers please report your use-case to project issues, so proper public API could be introduced instead")
public class EnumSerializer<T : Enum<T>>(
serialName: String,
private val values: Array<T>
) : KSerializer<T> {
override val descriptor: SerialDescriptor = SerialDescriptor(serialName, UnionKind.ENUM_KIND) {
values.forEach {
val fqn = "$serialName.${it.name}"
val enumMemberDescriptor = SerialDescriptor(fqn, StructureKind.OBJECT)
element(it.name, enumMemberDescriptor)
}
}
override fun serialize(encoder: Encoder, value: T) {
val index = values.indexOf(value)
check(index != -1) {
"$value is not a valid enum ${descriptor.serialName}, must be one of ${values.contentToString()}"
}
encoder.encodeEnum(descriptor, index)
}
override fun deserialize(decoder: Decoder): T {
val index = decoder.decodeEnum(descriptor)
check(index in values.indices) {
"$index is not among valid $${descriptor.serialName} enum values, values size is ${values.size}"
}
return values[index]
}
}
|