Skip to content

Commit 8262081

Browse files
committed
Merge remote-tracking branch 'origin/master' into dev
2 parents 9f8d050 + d489d96 commit 8262081

20 files changed

+203
-164
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ Kotlin serialization consists of a compiler plugin, that generates visitor code
3131

3232
<!--- END -->
3333

34+
* **Additional links**
35+
* [Kotlin Serialization Guide](docs/serialization-guide.md)
36+
* [Full API reference](https://kotlin.github.io/kotlinx.serialization/)
37+
3438
## Introduction and references
3539

3640
Here is a small example.

core/commonMain/src/kotlinx/serialization/descriptors/SerialDescriptor.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ public interface SerialDescriptor {
220220
* @Serializable
221221
* class Outer(@AnotherSerialAnnotation val nested: Nested)
222222
*
223-
* outerDescriptor.getElementAnnotations(0) // Returns [@SomeSerialAnnotation]
224-
* outerDescriptor.getElementDescriptor(0).annotations // Returns [@AnotherSerialAnnotation]
223+
* outerDescriptor.getElementAnnotations(0) // Returns [@AnotherSerialAnnotation]
224+
* outerDescriptor.getElementDescriptor(0).annotations // Returns [@SomeSerialAnnotation]
225225
* ```
226226
* Only annotations marked with [SerialInfo] are added to the resulting list.
227227
*

docs/polymorphism.md

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ class OwnedProject(override val name: String, val owner: String) : Project()
144144

145145
fun main() {
146146
val data: Project = OwnedProject("kotlinx.coroutines", "kotlin")
147-
println(Json.encodeToString(data))
147+
println(Json.encodeToString(data)) // Serializing data of compile-time type Project
148148
}
149149
```
150150

@@ -159,6 +159,45 @@ A `type` key is added to the resulting JSON object as a _discriminator_.
159159

160160
<!--- TEST -->
161161

162+
Pay attention to the small, but very important detail in the above example that is related to [Static types](#static-types):
163+
the `val data` property has a compile-time type of `Project`, even though its run-time type is `OwnedProject`.
164+
When serializing polymorphic class hierarchies you must ensure that the compile-time type of the serialized object
165+
is a polymorphic one, not a concrete one.
166+
167+
Let us see what happens if the example is slightly changed, so that the compile-time of the object that is being
168+
serialized is `OwnedProject` (the same as its run-time type).
169+
170+
```kotlin
171+
@Serializable
172+
sealed class Project {
173+
abstract val name: String
174+
}
175+
176+
@Serializable
177+
class OwnedProject(override val name: String, val owner: String) : Project()
178+
179+
fun main() {
180+
val data = OwnedProject("kotlinx.coroutines", "kotlin") // data: OwnedProject here
181+
println(Json.encodeToString(data)) // Serializing data of compile-time type OwnedProject
182+
}
183+
```
184+
185+
> You can get the full code [here](../guide/example/example-poly-05.kt).
186+
187+
The type of `OwnedProject` is concrete and is not polymorphic, thus the `type`
188+
discriminator property is not emitted into the resulting JSON.
189+
190+
```text
191+
{"name":"kotlinx.coroutines","owner":"kotlin"}
192+
```
193+
194+
<!--- TEST -->
195+
196+
In general, Kotlin serialization is designed to work correctly only when the compile-time type used during serialization
197+
is the same one as the compile-time type used during deserialization. You can always specify the type explicitly
198+
when calling serialization functions. The previous example can be corrected to use `Project` type for serialization
199+
by calling `Json.encodeToString<Project>(data)`.
200+
162201
### Custom subclass serial name
163202

164203
A value of the `type` key is a fully qualified class name by default. We can put [SerialName] annotation onto
@@ -180,7 +219,7 @@ fun main() {
180219
}
181220
```
182221

183-
> You can get the full code [here](../guide/example/example-poly-05.kt).
222+
> You can get the full code [here](../guide/example/example-poly-06.kt).
184223
185224
This way we can have a stable _serial name_ that is not affected by the class's name in the source code.
186225

@@ -215,7 +254,7 @@ fun main() {
215254
}
216255
```
217256

218-
> You can get the full code [here](../guide/example/example-poly-06.kt).
257+
> You can get the full code [here](../guide/example/example-poly-07.kt).
219258
220259
The properties of the superclass are serialized before the properties of the subclass.
221260

@@ -250,12 +289,12 @@ fun main() {
250289
}
251290
```
252291

253-
> You can get the full code [here](../guide/example/example-poly-07.kt).
292+
> You can get the full code [here](../guide/example/example-poly-08.kt).
254293
255294
An object serializes as an empty class, also using its fully-qualified class name as type by default:
256295

257296
```text
258-
[{"type":"example.examplePoly07.EmptyResponse"},{"type":"example.examplePoly07.TextResponse","text":"OK"}]
297+
[{"type":"example.examplePoly08.EmptyResponse"},{"type":"example.examplePoly08.TextResponse","text":"OK"}]
259298
```
260299

261300
<!--- TEST -->
@@ -308,7 +347,7 @@ fun main() {
308347
}
309348
```
310349

311-
> You can get the full code [here](../guide/example/example-poly-08.kt).
350+
> You can get the full code [here](../guide/example/example-poly-09.kt).
312351
313352
This additional configuration makes our code work just as it worked with a sealed class in
314353
the [Sealed classes](#sealed-classes) section, but here subclasses can be spread arbitrarily throughout the code.
@@ -361,7 +400,7 @@ fun main() {
361400
}
362401
```
363402

364-
> You can get the full code [here](../guide/example/example-poly-09.kt).
403+
> You can get the full code [here](../guide/example/example-poly-10.kt).
365404
366405
```text
367406
{"type":"owned","name":"kotlinx.coroutines","owner":"kotlin"}
@@ -404,7 +443,7 @@ fun main() {
404443
}
405444
```
406445

407-
> You can get the full code [here](../guide/example/example-poly-10.kt).
446+
> You can get the full code [here](../guide/example/example-poly-11.kt).
408447
409448
As long as we've registered the actual subtype of the interface that is being serialized in
410449
the [SerializersModule] of our `format`, we get it working at runtime.
@@ -449,7 +488,7 @@ fun main() {
449488
}
450489
```
451490

452-
> You can get the full code [here](../guide/example/example-poly-11.kt).
491+
> You can get the full code [here](../guide/example/example-poly-12.kt).
453492
454493
We get the exception.
455494

@@ -497,7 +536,7 @@ fun main() {
497536
}
498537
```
499538

500-
> You can get the full code [here](../guide/example/example-poly-12.kt).
539+
> You can get the full code [here](../guide/example/example-poly-13.kt).
501540
502541
However, the `Any` is a class and it is not serializable:
503542

@@ -539,7 +578,7 @@ fun main() {
539578
}
540579
```
541580

542-
> You can get the full code [here](../guide/example/example-poly-13.kt).
581+
> You can get the full code [here](../guide/example/example-poly-14.kt).
543582
544583
With the explicit serializer it works as before.
545584

@@ -592,7 +631,7 @@ fun main() {
592631
}
593632
```
594633

595-
> You can get the full code [here](../guide/example/example-poly-14.kt).
634+
> You can get the full code [here](../guide/example/example-poly-15.kt).
596635
597636
<!--- TEST
598637
{"project":{"type":"owned","name":"kotlinx.coroutines","owner":"kotlin"}}
@@ -645,7 +684,7 @@ fun main() {
645684
}
646685
-->
647686

648-
> You can get the full code [here](../guide/example/example-poly-15.kt).
687+
> You can get the full code [here](../guide/example/example-poly-16.kt).
649688
650689
<!--- TEST
651690
{"project":{"type":"owned","name":"kotlinx.coroutines","owner":"kotlin"},"any":{"type":"owned","name":"kotlinx.coroutines","owner":"kotlin"}}
@@ -736,7 +775,7 @@ fun main() {
736775

737776
```
738777

739-
> You can get the full code [here](../guide/example/example-poly-16.kt).
778+
> You can get the full code [here](../guide/example/example-poly-17.kt).
740779
741780
The JSON that is being produced is deeply polymorphic.
742781

@@ -784,7 +823,7 @@ fun main() {
784823
}
785824
```
786825

787-
> You can get the full code [here](../guide/example/example-poly-17.kt).
826+
> You can get the full code [here](../guide/example/example-poly-18.kt).
788827
789828
We get the following exception.
790829

@@ -846,7 +885,7 @@ fun main() {
846885
}
847886
```
848887

849-
> You can get the full code [here](../guide/example/example-poly-18.kt).
888+
> You can get the full code [here](../guide/example/example-poly-19.kt).
850889
851890
Notice, how `BasicProject` had also captured the specified type key in its `type` property.
852891

formats/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,11 @@ Basic serial operations have been implemented, but some features such as compoun
119119
* Platform: JVM, Android
120120

121121
Allow serialization and deserialization of objects to and from [CBOR](https://cbor.io/). This codec can be used to read and write from Java InputStream and OutputStream.
122+
123+
### Amazon Ion (binary only)
124+
125+
* GitHub repo: [dimitark/kotlinx-serialization-ion](https://github.com/dimitark/kotlinx-serialization-ion)
126+
* Artifact ID: `com.github.dimitark:kotlinx-serialization-ion`
127+
* Platform: JVM
128+
129+
Allow serialization and deserialization of objects to and from [Amazon Ion](https://amzn.github.io/ion-docs/). It stores the data in a flat binary format. Upon destialization, it retains the references between the objects.

guide/example/example-poly-04.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ class OwnedProject(override val name: String, val owner: String) : Project()
1414

1515
fun main() {
1616
val data: Project = OwnedProject("kotlinx.coroutines", "kotlin")
17-
println(Json.encodeToString(data))
17+
println(Json.encodeToString(data)) // Serializing data of compile-time type Project
1818
}

guide/example/example-poly-05.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ sealed class Project {
99
abstract val name: String
1010
}
1111

12-
@Serializable
13-
@SerialName("owned")
12+
@Serializable
1413
class OwnedProject(override val name: String, val owner: String) : Project()
1514

1615
fun main() {
17-
val data: Project = OwnedProject("kotlinx.coroutines", "kotlin")
18-
println(Json.encodeToString(data))
16+
val data = OwnedProject("kotlinx.coroutines", "kotlin") // data: OwnedProject here
17+
println(Json.encodeToString(data)) // Serializing data of compile-time type OwnedProject
1918
}

guide/example/example-poly-06.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@ import kotlinx.serialization.json.*
66

77
@Serializable
88
sealed class Project {
9-
abstract val name: String
10-
var status = "open"
9+
abstract val name: String
1110
}
1211

13-
@Serializable
12+
@Serializable
1413
@SerialName("owned")
1514
class OwnedProject(override val name: String, val owner: String) : Project()
1615

1716
fun main() {
18-
val json = Json { encodeDefaults = true } // "status" will be skipped otherwise
1917
val data: Project = OwnedProject("kotlinx.coroutines", "kotlin")
20-
println(json.encodeToString(data))
18+
println(Json.encodeToString(data))
2119
}

guide/example/example-poly-07.kt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ import kotlinx.serialization.*
55
import kotlinx.serialization.json.*
66

77
@Serializable
8-
sealed class Response
9-
10-
@Serializable
11-
object EmptyResponse : Response()
12-
8+
sealed class Project {
9+
abstract val name: String
10+
var status = "open"
11+
}
12+
1313
@Serializable
14-
class TextResponse(val text: String) : Response()
14+
@SerialName("owned")
15+
class OwnedProject(override val name: String, val owner: String) : Project()
1516

1617
fun main() {
17-
val list = listOf(EmptyResponse, TextResponse("OK"))
18-
println(Json.encodeToString(list))
18+
val json = Json { encodeDefaults = true } // "status" will be skipped otherwise
19+
val data: Project = OwnedProject("kotlinx.coroutines", "kotlin")
20+
println(json.encodeToString(data))
1921
}

guide/example/example-poly-08.kt

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,16 @@ package example.examplePoly08
44
import kotlinx.serialization.*
55
import kotlinx.serialization.json.*
66

7-
import kotlinx.serialization.modules.*
8-
9-
val module = SerializersModule {
10-
polymorphic(Project::class) {
11-
subclass(OwnedProject::class)
12-
}
13-
}
14-
15-
val format = Json { serializersModule = module }
16-
177
@Serializable
18-
abstract class Project {
19-
abstract val name: String
20-
}
21-
8+
sealed class Response
9+
2210
@Serializable
23-
@SerialName("owned")
24-
class OwnedProject(override val name: String, val owner: String) : Project()
11+
object EmptyResponse : Response()
12+
13+
@Serializable
14+
class TextResponse(val text: String) : Response()
2515

2616
fun main() {
27-
val data: Project = OwnedProject("kotlinx.coroutines", "kotlin")
28-
println(format.encodeToString(data))
29-
}
17+
val list = listOf(EmptyResponse, TextResponse("OK"))
18+
println(Json.encodeToString(list))
19+
}

guide/example/example-poly-09.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ val module = SerializersModule {
1414

1515
val format = Json { serializersModule = module }
1616

17-
interface Project {
18-
val name: String
17+
@Serializable
18+
abstract class Project {
19+
abstract val name: String
1920
}
20-
21+
2122
@Serializable
2223
@SerialName("owned")
23-
class OwnedProject(override val name: String, val owner: String) : Project
24+
class OwnedProject(override val name: String, val owner: String) : Project()
2425

2526
fun main() {
2627
val data: Project = OwnedProject("kotlinx.coroutines", "kotlin")

0 commit comments

Comments
 (0)