1 /*
2 * Copyright 2017-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3 */
4
5 @file:OptIn(ExperimentalSerializationApi::class)
6
7 package sample
8
9 import kotlinx.serialization.*
10 import kotlinx.serialization.modules.SerializersModule
11 import kotlinx.serialization.modules.polymorphic
12 import kotlinx.serialization.modules.subclass
13 import kotlinx.serialization.protobuf.ProtoNumber
14
15 @Serializable
16 data class IntData(val intV: Int)
17
18 @Serializable
19 data class Box<T>(val boxed: T)
20
21 @Serializable
22 data class HasBox<T>(val desc: String, val boxes: List<Box<T>>)
23
24 @Serializable
25 data class Data(
26 val s: String,
27 val box: Box<Int> = Box(42),
28 val boxes: HasBox<String> = HasBox("boxes", listOf(Box("foo"), Box("bar"))),
29 val m: Map<Int, String> = emptyMap()
30 )
31
32 // this has implicit @Polymorphic
33 interface IMessage {
34 val body: String
35 }
36
37 // and this class too has implicit @Polymorphic
38 @Serializable
39 abstract class Message() : IMessage {
40 abstract override val body: String
41 }
42
43 @Polymorphic
44 @Serializable
45 @SerialName("SimpleMessage") // to cut out package prefix
46 open class SimpleMessage() : Message() {
47 override var body: String = "Simple"
48 }
49
50 @Serializable
51 @SerialName("DoubleSimpleMessage")
52 class DoubleSimpleMessage(val body2: String) : SimpleMessage()
53
54 @Serializable
55 @SerialName("MessageWithId")
56 open class MessageWithId(val id: Int, override val body: String) : Message()
57
58 @Serializable
59 class Holder(
60 val iMessage: IMessage,
61 val iMessageList: List<IMessage>,
62 val message: Message,
63 val msgSet: Set<Message>,
64 val simple: SimpleMessage,
65 // all above should be polymorphic
66 val withId: MessageWithId // but this not
67 )
68
69 @Serializable
70 class GenericMessage<T : IMessage, V: Any>(
71 @Polymorphic val value: T,
72 @Polymorphic val value2: V
73 )
74
75 @Serializable
76 abstract class AbstractSerializable {
77 public abstract val rootState: String // no backing field
78
79 val publicState: String = "A"
80 }
81
82 @Serializable
83 open class SerializableBase: AbstractSerializable() {
84
85
86 private val privateState: String = "B" // still should be serialized
87
88 @Transient
89 private val privateTransientState = "C" // not serialized: explicitly transient
90
91 val notAState: String // not serialized: no backing field
92 get() = "D"
93
94 override val rootState: String
95 get() = "E" // still not serializable
96
equalsnull97 override fun equals(other: Any?): Boolean {
98 if (this === other) return true
99 if (other !is SerializableBase) return false
100
101 if (privateState != other.privateState) return false
102 if (privateTransientState != other.privateTransientState) return false
103
104 return true
105 }
106 }
107
108 @Serializable
109 class Derived(val derivedState: Int): SerializableBase() {
110 override val rootState: String = "foo" // serializable!
111
equalsnull112 override fun equals(other: Any?): Boolean {
113 if (this === other) return true
114 if (other !is Derived) return false
115 if (!super.equals(other)) return false
116
117 if (derivedState != other.derivedState) return false
118 if (rootState != other.rootState) return false
119
120 return true
121 }
122 }
123
124 @Serializable
125 open class Base1(open var state1: String) {
toStringnull126 override fun toString(): String {
127 return "Base1(state1='$state1')"
128 }
129 }
130
131 @Serializable
132 class Derived2(@SerialName("state2") override var state1: String): Base1(state1) {
toStringnull133 override fun toString(): String {
134 return "Derived2(state1='$state1')"
135 }
136 }
137
138 @Serializable
139 open class PolyBase(@ProtoNumber(1) val id: Int) {
hashCodenull140 override fun hashCode(): Int {
141 return id
142 }
143
toStringnull144 override fun toString(): String {
145 return "PolyBase(id=$id)"
146 }
147
equalsnull148 override fun equals(other: Any?): Boolean {
149 if (this === other) return true
150 if (other == null || this::class != other::class) return false
151
152 other as PolyBase
153
154 if (id != other.id) return false
155
156 return true
157 }
158
159 }
160
161 @Serializable
162 data class PolyDerived(@ProtoNumber(2) val s: String) : PolyBase(1)
163
<lambda>null164 val BaseAndDerivedModule = SerializersModule {
165 polymorphic(PolyBase::class, PolyBase.serializer()) {
166 subclass(PolyDerived.serializer())
167 }
168 }
169
170 @Serializable
171 data class MyPolyData(val data: Map<String, @Polymorphic Any>)
172
173 @Serializable
174 data class MyPolyDataWithPolyBase(
175 val data: Map<String, @Polymorphic Any>,
176 @Polymorphic val polyBase: PolyBase
177 )
178
179 enum class Attitude { POSITIVE, NEUTRAL, NEGATIVE }
180
181 @Serializable
182 data class Tree(val name: String, val left: Tree? = null, val right: Tree? = null)
183
184 @Serializable
185 data class Zoo(
186 val unit: Unit,
187 val boolean: Boolean,
188 val byte: Byte,
189 val short: Short,
190 val int: Int,
191 val long: Long,
192 val float: Float,
193 val double: Double,
194 val char: Char,
195 val string: String,
196 val enum: Attitude,
197 val intData: IntData,
198 val unitN: Unit?,
199 val booleanN: Boolean?,
200 val byteN: Byte?,
201 val shortN: Short?,
202 val intN: Int?,
203 val longN: Long?,
204 val floatN: Float?,
205 val doubleN: Double?,
206 val charN: Char?,
207 val stringN: String?,
208 val enumN: Attitude?,
209 val intDataN: IntData?,
210 val listInt: List<Int>,
211 val listIntN: List<Int?>,
212 val listNInt: Set<Int>?,
213 val listNIntN: MutableSet<Int?>?,
214 val listListEnumN: List<List<Attitude?>>,
215 val listIntData: List<IntData>,
216 val listIntDataN: MutableList<IntData?>,
217 val tree: Tree,
218 val mapStringInt: Map<String,Int>,
219 val mapIntStringN: Map<Int,String?>,
220 val arrays: ZooWithArrays
221 )
222
223 @Serializable
224 data class ZooWithArrays(
225 val arrByte: Array<Byte>,
226 val arrInt: Array<Int>,
227 val arrIntN: Array<Int?>,
228 val arrIntData: Array<IntData>
229
230 ) {
equalsnull231 override fun equals(other: Any?) = other is ZooWithArrays &&
232 arrByte.contentEquals(other.arrByte) &&
233 arrInt.contentEquals(other.arrInt) &&
234 arrIntN.contentEquals(other.arrIntN) &&
235 arrIntData.contentEquals(other.arrIntData)
236 }
237
238 val zoo = Zoo(
239 Unit, true, 10, 20, 30, 40, 50f, 60.0, 'A', "Str0", Attitude.POSITIVE, IntData(70),
240 null, null, 11, 21, 31, 41, 51f, 61.0, 'B', "Str1", Attitude.NEUTRAL, null,
241 listOf(1, 2, 3),
242 listOf(4, 5, null),
243 setOf(6, 7, 8),
244 mutableSetOf(null, 9, 10),
245 listOf(listOf(Attitude.NEGATIVE, null)),
246 listOf(IntData(1), IntData(2), IntData(3)),
247 mutableListOf(IntData(1), null, IntData(3)),
248 Tree("root", Tree("left"), Tree("right", Tree("right.left"), Tree("right.right"))),
249 mapOf("one" to 1, "two" to 2, "three" to 3),
250 mapOf(0 to null, 1 to "first", 2 to "second"),
251 ZooWithArrays(
252 arrayOf(1, 2, 3),
253 arrayOf(100, 200, 300),
254 arrayOf(null, -1, -2),
255 arrayOf(IntData(1), IntData(2))
256 )
257 )
258