/* * Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ package kotlinx.serialization.internal import kotlinx.serialization.* import kotlinx.serialization.builtins.* import kotlin.reflect.* import kotlin.time.* import kotlin.uuid.* internal actual fun Array.getChecked(index: Int): T { if (index !in indices) throw IndexOutOfBoundsException("Index $index out of bounds $indices") return get(index) } internal actual fun BooleanArray.getChecked(index: Int): Boolean { if (index !in indices) throw IndexOutOfBoundsException("Index $index out of bounds $indices") return get(index) } internal actual fun KClass.compiledSerializerImpl(): KSerializer? = this.constructSerializerForGivenTypeArgs() ?: ( if (this === Nothing::class) NothingSerializer // .js throws an exception for Nothing else this.js.asDynamic().Companion?.serializer() ) as? KSerializer internal actual fun KClass.isInterface(): Boolean = isInterface internal actual fun createCache(factory: (KClass<*>) -> KSerializer?): SerializerCache { return object: SerializerCache { override fun get(key: KClass): KSerializer? { return factory(key) } } } internal actual fun createParametrizedCache(factory: (KClass, List) -> KSerializer?): ParametrizedSerializerCache { return object: ParametrizedSerializerCache { override fun get(key: KClass, types: List): Result?> { return kotlin.runCatching { factory(key, types) } } } } internal actual fun ArrayList.toNativeArrayImpl(eClass: KClass): Array = toTypedArray() internal actual fun KClass<*>.platformSpecificSerializerNotRegistered(): Nothing { throw SerializationException( notRegisteredMessage() + "To get enum serializer on Kotlin/JS, it should be annotated with @Serializable annotation." ) } @Suppress("UNCHECKED_CAST", "DEPRECATION_ERROR") @OptIn(ExperimentalAssociatedObjects::class) internal actual fun KClass.constructSerializerForGivenTypeArgs(vararg args: KSerializer): KSerializer? = try { val assocObject = findAssociatedObject() when { assocObject is KSerializer<*> -> assocObject as KSerializer assocObject is SerializerFactory -> assocObject.serializer(*args) as KSerializer else -> null } } catch (e: dynamic) { null } internal actual fun isReferenceArray(rootClass: KClass): Boolean = rootClass == Array::class /** * WARNING: may be broken in arbitrary time in the future without notice * * Should be eventually replaced with compiler intrinsics */ private val KClass<*>.isInterface: Boolean get(): Boolean { // .js throws an exception for Nothing if (this === Nothing::class) return false return js.asDynamic().`$metadata$`?.kind == "interface" } @OptIn(ExperimentalUnsignedTypes::class, ExperimentalUuidApi::class, ExperimentalSerializationApi::class) internal actual fun initBuiltins(): Map, KSerializer<*>> = mapOf( String::class to String.serializer(), Char::class to Char.serializer(), CharArray::class to CharArraySerializer(), Double::class to Double.serializer(), DoubleArray::class to DoubleArraySerializer(), Float::class to Float.serializer(), FloatArray::class to FloatArraySerializer(), Long::class to Long.serializer(), LongArray::class to LongArraySerializer(), ULong::class to ULong.serializer(), ULongArray::class to ULongArraySerializer(), Int::class to Int.serializer(), IntArray::class to IntArraySerializer(), UInt::class to UInt.serializer(), UIntArray::class to UIntArraySerializer(), Short::class to Short.serializer(), ShortArray::class to ShortArraySerializer(), UShort::class to UShort.serializer(), UShortArray::class to UShortArraySerializer(), Byte::class to Byte.serializer(), ByteArray::class to ByteArraySerializer(), UByte::class to UByte.serializer(), UByteArray::class to UByteArraySerializer(), Boolean::class to Boolean.serializer(), BooleanArray::class to BooleanArraySerializer(), Unit::class to Unit.serializer(), Nothing::class to NothingSerializer(), Duration::class to Duration.serializer(), Uuid::class to Uuid.serializer() )