• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 package kotlinx.serialization
6 
7 import kotlinx.serialization.descriptors.*
8 import kotlinx.serialization.encoding.*
9 import kotlin.reflect.*
10 
11 /**
12  * The main entry point to the serialization process.
13  * Applying [Serializable] to the Kotlin class instructs the serialization plugin to automatically generate implementation of [KSerializer]
14  * for the current class, that can be used to serialize and deserialize the class.
15  * The generated serializer can be accessed with `T.serializer()` extension function on the class companion,
16  * both are generated by the plugin as well.
17  *
18  * ```
19  * @Serializable
20  * class MyData(val myData: AnotherData, val intProperty: Int, ...)
21  *
22  * // Produces JSON string using the generated serializer
23  * val jsonString = Json.encodeToJson(MyData.serializer(), instance)
24  * ```
25  *
26  * Additionally, the user-defined serializer can be specified using [with] parameter:
27  * ```
28  * @Serializable(with = MyAnotherDataCustomSerializer::class)
29  * class MyAnotherData(...)
30  *
31  * MyAnotherData.serializer() // <- returns MyAnotherDataCustomSerializer
32  * ```
33  *
34  * To continue generating the implementation of [KSerializer] using the plugin, specify the [KeepGeneratedSerializer] annotation.
35  * In this case, the serializer will be available via `generatedSerializer()` function, and will also be used in the heirs.
36  *
37  * For annotated properties, specifying [with] parameter is mandatory and can be used to override
38  * serializer on the use-site without affecting the rest of the usages:
39  * ```
40  * @Serializable // By default is serialized as 3 byte components
41  * class RgbPixel(val red: Short, val green: Short, val blue: Short)
42  *
43  * @Serializable
44  * class RgbExample(
45  *     @Serializable(with = RgbAsHexString::class) p1: RgbPixel, // Serialize as HEX string, e.g. #FFFF00
46  *     @Serializable(with = RgbAsSingleInt::class) p2: RgbPixel, // Serialize as single integer, e.g. 16711680
47  *     p3: RgbPixel // Serialize as 3 short components, e.g. { "red": 255, "green": 255, "blue": 0 }
48  * )
49  * ```
50  * In this example, each pixel will be serialized using different data representation.
51  *
52  * For classes with generic type parameters, `serializer()` function requires one additional argument per each generic type parameter:
53  * ```
54  * @Serializable
55  * class Box<T>(value: T)
56  *
57  * Box.serializer() // Doesn't compile
58  * Box.serializer(Int.serializer()) // Returns serializer for Box<Int>
59  * Box.serializer(Box.serializer(Int.serializer())) // Returns serializer for Box<Box<Int>>
60  * ```
61  *
62  * ### Implementation details
63  *
64  * In order to generate `serializer` function that is not a method on the particular instance, the class should have a companion object, either named or unnamed.
65  * Companion object is generated by the plugin if it is not declared, effectively exposing both companion and `serializer()` method to class ABI.
66  * If companion object already exists, only `serializer` method will be generated.
67  *
68  * @see UseSerializers
69  * @see Serializer
70  * @see KeepGeneratedSerializer
71  */
72 @MustBeDocumented
73 @Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS, AnnotationTarget.TYPE)
74 //@Retention(AnnotationRetention.RUNTIME) // Runtime is the default retention, also see KT-41082
75 public annotation class Serializable(
76     val with: KClass<out KSerializer<*>> = KSerializer::class // Default value indicates that auto-generated serializer is used
77 )
78 
79 /**
80  * The meta-annotation for adding [Serializable] behaviour to user-defined annotations.
81  *
82  * Applying [MetaSerializable] to the annotation class `A` instructs the serialization plugin to treat annotation A
83  * as [Serializable]. In addition, all annotations marked with [MetaSerializable] are saved in the generated [SerialDescriptor]
84  * as if they are annotated with [SerialInfo].
85  *
86  * ```
87  * @MetaSerializable
88  * @Target(AnnotationTarget.CLASS)
89  * annotation class MySerializable(val data: String)
90  *
91  * @MySerializable("some_data")
92  * class MyData(val myData: AnotherData, val intProperty: Int, ...)
93  *
94  * val serializer = MyData.serializer()
95  * serializer.descriptor.annotations.filterIsInstance<MySerializable>().first().data // <- returns "some_data"
96  * ```
97  *
98  * @see Serializable
99  * @see SerialInfo
100  * @see UseSerializers
101  * @see Serializer
102  */
103 @MustBeDocumented
104 @Target(AnnotationTarget.ANNOTATION_CLASS)
105 //@Retention(AnnotationRetention.RUNTIME) // Runtime is the default retention, also see KT-41082
106 @ExperimentalSerializationApi
107 public annotation class MetaSerializable
108 
109 /**
110  * Instructs the serialization plugin to turn this class into serializer for specified class [forClass].
111  * However, it would not be used automatically. To apply it on particular class or property,
112  * use [Serializable] or [UseSerializers], or [Contextual] with runtime registration.
113  *
114  * `@Serializer(forClass)` is experimental and unstable feature that can be changed in future releases.
115  * Changes may include additional constraints on classes and objects marked with this annotation,
116  * behavioural changes and even serialized shape of the class.
117  */
118 @MustBeDocumented
119 @Target(AnnotationTarget.CLASS)
120 @Retention(AnnotationRetention.BINARY)
121 @ExperimentalSerializationApi
122 public annotation class Serializer(
123     val forClass: KClass<*> //  target class to create serializer for
124 )
125 
126 /**
127  * Overrides the name of a class or a property in the corresponding [SerialDescriptor].
128  * Names and serial names are used by text-based serial formats in order to encode the name of the class or
129  * the name of the property, e.g. by `Json`.
130  *
131  * By default, [SerialDescriptor.serialName] and [SerialDescriptor.getElementName]
132  * are associated with fully qualified name of the target class and the name of the property respectively.
133  * Applying this annotation changes the visible name to the given [value]:
134  *
135  * ```
136  * package foo
137  *
138  * @Serializable // RegularName.serializer().descriptor.serialName is "foo.RegularName"
139  * class RegularName(val myInt: Int)
140  *
141  * @Serializable
142  * @SerialName("CustomName") // Omit package from name that is used for diagnostic and polymorphism
143  * class CustomName(@SerialName("int") val myInt: Int)
144  *
145  * // Prints "{"myInt":42}"
146  * println(Json.encodeToString(RegularName(42)))
147  * // Prints "{"int":42}"
148  * println(Json.encodeToString(CustomName(42)))
149  * ```
150  *
151  * If a name of class or property is overridden with this annotation, original source code name is not available for the library.
152  * Tools like `JsonNamingStrategy` and `ProtoBufSchemaGenerator` would see and transform [value] from [SerialName] annotation.
153  */
154 @MustBeDocumented
155 @Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
156 // @Retention(AnnotationRetention.RUNTIME) still runtime, but KT-41082
157 public annotation class SerialName(val value: String)
158 
159 /**
160  * Indicates that property must be present during deserialization process, despite having a default value.
161  */
162 @MustBeDocumented
163 @Target(AnnotationTarget.PROPERTY)
164 // @Retention(AnnotationRetention.RUNTIME) still runtime, but KT-41082
165 public annotation class Required
166 
167 /**
168  * Marks this property invisible for the whole serialization process, including [serial descriptors][SerialDescriptor].
169  * Transient properties must have default values.
170  */
171 @MustBeDocumented
172 @Target(AnnotationTarget.PROPERTY)
173 // @Retention(AnnotationRetention.RUNTIME) still runtime, but KT-41082
174 public annotation class Transient
175 
176 /**
177  * Controls whether the target property is serialized when its value is equal to a default value,
178  * regardless of the format settings.
179  * Does not affect decoding and deserialization process.
180  *
181  * Example of usage:
182  * ```
183  * @Serializable
184  * data class Foo(
185  *     @EncodeDefault(ALWAYS) val a: Int = 42,
186  *     @EncodeDefault(NEVER) val b: Int = 43,
187  *     val c: Int = 44
188  * )
189  *
190  * Json { encodeDefaults = false }.encodeToString((Foo()) // {"a": 42}
191  * Json { encodeDefaults = true }.encodeToString((Foo())  // {"a": 42, "c":44}
192  * ```
193  *
194  * @see EncodeDefault.Mode.ALWAYS
195  * @see EncodeDefault.Mode.NEVER
196  */
197 @MustBeDocumented
198 @Target(AnnotationTarget.PROPERTY)
199 @ExperimentalSerializationApi
200 public annotation class EncodeDefault(val mode: Mode = Mode.ALWAYS) {
201     /**
202      * Strategy for the [EncodeDefault] annotation.
203      */
204     @ExperimentalSerializationApi
205     public enum class Mode {
206         /**
207          * Configures serializer to always encode the property, even if its value is equal to its default.
208          * For annotated properties, format settings are not taken into account and
209          * [CompositeEncoder.shouldEncodeElementDefault] is not invoked.
210          */
211         ALWAYS,
212 
213         /**
214          * Configures serializer not to encode the property if its value is equal to its default.
215          * For annotated properties, format settings are not taken into account and
216          * [CompositeEncoder.shouldEncodeElementDefault] is not invoked.
217          */
218         NEVER
219     }
220 }
221 
222 /**
223  * Meta-annotation that commands the compiler plugin to handle the annotation as serialization-specific.
224  * Serialization-specific annotations are preserved in the [SerialDescriptor] and can be retrieved
225  * during serialization process with [SerialDescriptor.getElementAnnotations] for properties annotations
226  * and [SerialDescriptor.annotations] for class annotations.
227  *
228  * It is recommended to explicitly specify target for serial info annotations, whether it is [AnnotationTarget.PROPERTY], [AnnotationTarget.CLASS], or both.
229  * Keep in mind that Kotlin compiler prioritizes [function parameter target][AnnotationTarget.VALUE_PARAMETER] over [property target][AnnotationTarget.PROPERTY],
230  * so serial info annotations used on constructor-parameters-as-properties without explicit declaration-site or use-site target are not preserved.
231  */
232 @MustBeDocumented
233 @Target(AnnotationTarget.ANNOTATION_CLASS)
234 @Retention(AnnotationRetention.BINARY)
235 @ExperimentalSerializationApi
236 public annotation class SerialInfo
237 
238 /**
239  * Meta-annotation that commands the compiler plugin to handle the annotation as serialization-specific.
240  * Serialization-specific annotations are preserved in the [SerialDescriptor] and can be retrieved
241  * during serialization process with [SerialDescriptor.getElementAnnotations].
242  *
243  * In contrary to regular [SerialInfo], this one makes annotations inheritable:
244  * If class X marked as [Serializable] has any of its supertypes annotated with annotation A that has `@InheritableSerialInfo` on it,
245  * A appears in X's [SerialDescriptor] even if X itself is not annotated.
246  * It is possible to use A multiple times on different supertypes. Resulting X's [SerialDescriptor.annotations] would still contain
247  * only one instance of A.
248  * Note that if A has any arguments, their values should be the same across all hierarchy. Otherwise, a compilation error
249  * would be reported by the plugin.
250  *
251  * Example:
252  * ```
253  * @InheritableSerialInfo
254  * annotation class A(val value: Int)
255  *
256  * @A(1) // Annotation can also be inherited from interfaces
257  * interface I
258  *
259  * @Serializable
260  * @A(1) // Argument value is the same as in I, no compiler error
261  * abstract class Base: I
262  *
263  * @Serializable
264  * class Derived: Base()
265  *
266  * // This function returns 1.
267  * fun foo(): Int = Derived.serializer().descriptor.annotations.filterIsInstance<A>().single().value
268  * ```
269  */
270 @MustBeDocumented
271 @Target(AnnotationTarget.ANNOTATION_CLASS)
272 @Retention(AnnotationRetention.BINARY)
273 @ExperimentalSerializationApi
274 public annotation class InheritableSerialInfo
275 
276 /**
277  * Instructs the plugin to use [ContextualSerializer] on a given property or type.
278  * Context serializer is usually used when serializer for type can only be found in runtime.
279  * It is also possible to apply [ContextualSerializer] to every property of the given type,
280  * using file-level [UseContextualSerialization] annotation.
281  *
282  * @see ContextualSerializer
283  * @see UseContextualSerialization
284  */
285 @Target(AnnotationTarget.PROPERTY, AnnotationTarget.TYPE)
286 @Retention(AnnotationRetention.BINARY)
287 public annotation class Contextual
288 
289 /**
290  * Instructs the plugin to use [ContextualSerializer] for every type in the current file that is listed in the [forClasses].
291  *
292  * @see Contextual
293  * @see ContextualSerializer
294  */
295 @Target(AnnotationTarget.FILE)
296 @Retention(AnnotationRetention.BINARY)
297 public annotation class UseContextualSerialization(vararg val forClasses: KClass<*>)
298 
299 /**
300  *  Adds [serializerClasses] to serializers resolving process inside the plugin.
301  *  Each of [serializerClasses] must implement [KSerializer].
302  *
303  *  Inside the file with this annotation, for each given property
304  *  of type `T` in some serializable class, this list would be inspected for the presence of `KSerializer<T>`.
305  *  If such serializer is present, it would be used instead of default.
306  *
307  *  Main use-case for this annotation is not to write @Serializable(with=SomeSerializer::class)
308  *  on each property with custom serializer.
309  *
310  *  Serializers from this list have higher priority than default, but lesser priority than
311  *  serializers defined on the property itself, such as [Serializable] (with=...) or [Contextual].
312  */
313 @Target(AnnotationTarget.FILE)
314 @Retention(AnnotationRetention.BINARY)
315 public annotation class UseSerializers(vararg val serializerClasses: KClass<out KSerializer<*>>)
316 
317 /**
318  * Instructs the serialization plugin to use [PolymorphicSerializer] on an annotated property or type usage.
319  * When used on class, replaces its serializer with [PolymorphicSerializer] everywhere.
320  *
321  * This annotation is applied automatically to interfaces and serializable abstract classes
322  * and can be applied to open classes in addition to [Serializable] for the sake of simplicity.
323  *
324  * Does not affect sealed classes, because they are gonna be serialized with subclasses automatically
325  * with special compiler plugin support which would be added later.
326  */
327 @Target(AnnotationTarget.PROPERTY, AnnotationTarget.TYPE, AnnotationTarget.CLASS)
328 //@Retention(AnnotationRetention.RUNTIME) // Runtime is the default retention, also see KT-41082
329 public annotation class Polymorphic
330 
331 /**
332  * Instructs the serialization plugin to keep automatically generated implementation of [KSerializer]
333  * for the current class if a custom serializer is specified at the same time `@Serializable(with=SomeSerializer::class)`.
334  *
335  * Automatically generated serializer is available via `generatedSerializer()` function in companion object of serializable class.
336  *
337  * Keeping generated serializers allow to use plugin generated serializer in inheritors even if custom serializer is specified.
338  *
339  * Used only with annotation [Serializable] with the specified argument [Serializable.with], e.g. `@Serializable(with=SomeSerializer::class)`.
340  *
341  * Annotation is not allowed on classes involved in polymorphic serialization:
342  * interfaces, sealed classes, abstract classes, classes marked by [Polymorphic].
343  *
344  * A compiler version `2.0.20` or higher is required.
345  */
346 @ExperimentalSerializationApi
347 @Target(AnnotationTarget.CLASS)
348 @Retention(AnnotationRetention.RUNTIME)
349 public annotation class KeepGeneratedSerializer
350 
351 /**
352  * Marks declarations that are still **experimental** in kotlinx.serialization, which means that the design of the
353  * corresponding declarations has open issues which may (or may not) lead to their changes in the future.
354  * Roughly speaking, there is a chance that those declarations will be deprecated in the near future or
355  * the semantics of their behavior may change in some way that may break some code.
356  *
357  * By default, the following categories of API are experimental:
358  *
359  * * Writing 3rd-party serialization formats
360  * * Writing non-trivial custom serializers
361  * * Implementing [SerialDescriptor] interfaces
362  * * Not-yet-stable serialization formats that require additional polishing
363  */
364 @MustBeDocumented
365 @Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS)
366 @RequiresOptIn(level = RequiresOptIn.Level.WARNING)
367 public annotation class ExperimentalSerializationApi
368 
369 /**
370  * Public API marked with this annotation is effectively **internal**, which means
371  * it should not be used outside of `kotlinx.serialization`.
372  * Signature, semantics, source and binary compatibilities are not guaranteed for this API
373  * and will be changed without any warnings or migration aids.
374  * If you cannot avoid using internal API to solve your problem, please report your use-case to serialization's issue tracker.
375  */
376 @MustBeDocumented
377 @Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS)
378 @RequiresOptIn(level = RequiresOptIn.Level.ERROR)
379 public annotation class InternalSerializationApi
380