diff --git a/CHANGELOG.md b/CHANGELOG.md index 2aa20eb63c..8a3c98cce7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This release will bump the Realm file format 24. Opening a file with an older fo * Support for RealmLists and RealmDictionaries in `RealmAny`. (Issue [#1434](https://github.com/realm/realm-kotlin/issues/1434)) * Optimized `RealmList.indexOf()` and `RealmList.contains()` using Core implementation of operations instead of iterating elements and comparing them in Kotlin. (Issue [#1625](https://github.com/realm/realm-kotlin/pull/1666) [RKOTLIN-995](https://jira.mongodb.org/browse/RKOTLIN-995)). * Add support for filtering logs by category. (Issue [#1691](https://github.com/realm/realm-kotlin/issues/1691) [JIRA](https://jira.mongodb.org/browse/RKOTLIN-1038)) +* [Sync] Add Mongo Client API to access Atlas App Service collections. It can be accessed through `User.mongoClient`. (Issue [#972](https://github.com/realm/realm-kotlin/issues/972)/[RKOTLIN-612](https://jira.mongodb.org/browse/RKOTLIN-612)) ### Fixed * Inserting the same typed link to the same key in a dictionary more than once would incorrectly create multiple backlinks to the object. This did not appear to cause any crashes later, but would have affecting explicit backlink count queries (eg: `...@links.@count`) and possibly notifications (Core Issue [realm/realm-core#7676](https://github.com/realm/realm-core/issues/7676) since v1.16.0). @@ -177,9 +178,9 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi * None. ### Enhancements -* [Sync] Added option to use managed WebSockets via OkHttp instead of Realm's built-in WebSocket client for Sync traffic (Only Android and JVM targets for now). Managed WebSockets offer improved support for proxies and firewalls that require authentication. This feature is currently opt-in and can be enabled by using `AppConfiguration.usePlatformNetworking()`. Managed WebSockets will become the default in a future version. (PR [#1528](https://github.com/realm/realm-kotlin/pull/1528)). -* `AutoClientResetFailed` exception now reports as the throwable cause any user exceptions that might occur during a client reset. (Issue [#1580](https://github.com/realm/realm-kotlin/issues/1580)) * The Unpacking of JVM native library will use the current library version instead of a calculated hash for the path. (Issue [#1617](https://github.com/realm/realm-kotlin/issues/1617)). +* [Sync] Added option to use managed WebSockets via OkHttp instead of Realm's built-in WebSocket client for Sync traffic (Only Android and JVM targets for now). Managed WebSockets offer improved support for proxies and firewalls that require authentication. This feature is currently opt-in and can be enabled by using `AppConfiguration.usePlatformNetworking()`. Managed WebSockets will become the default in a future version. (PR [#1528](https://github.com/realm/realm-kotlin/pull/1528)). +* [Sync] `AutoClientResetFailed` exception now reports as the throwable cause any user exceptions that might occur during a client reset. (Issue [#1580](https://github.com/realm/realm-kotlin/issues/1580)) ### Fixed * Cache notification callback JNI references at startup to ensure that symbols can be resolved in core callbacks. (Issue [#1577](https://github.com/realm/realm-kotlin/issues/1577)) diff --git a/buildSrc/src/main/kotlin/Config.kt b/buildSrc/src/main/kotlin/Config.kt index 4ef9f452bf..40bef56fb8 100644 --- a/buildSrc/src/main/kotlin/Config.kt +++ b/buildSrc/src/main/kotlin/Config.kt @@ -121,7 +121,7 @@ object Versions { const val jmh = "1.34" // https://github.com/openjdk/jmh const val jmhPlugin = "0.6.6" // https://github.com/melix/jmh-gradle-plugin const val junit = "4.13.2" // https://mvnrepository.com/artifact/junit/junit - const val kbson = "0.3.0" // https://github.com/mongodb/kbson + const val kbson = "0.4.0" // https://github.com/mongodb/kbson // When updating the Kotlin version, also remember to update /examples/min-android-sample/build.gradle.kts const val kotlin = "1.9.0" // https://github.com/JetBrains/kotlin and https://kotlinlang.org/docs/releases.html#release-details const val kotlinJvmTarget = "1.8" // Which JVM bytecode version is kotlin compiled to. diff --git a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index 0af5ca820b..a9d9863cf9 100644 --- a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -772,6 +772,7 @@ expect object RealmInterop { app: RealmAppPointer, user: RealmUserPointer, name: String, + serviceName: String? = null, serializedEjsonArgs: String, // as ejson callback: AppCallback ) diff --git a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index b0a25ca725..45055933be 100644 --- a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -1710,14 +1710,16 @@ actual object RealmInterop { ) } + @Suppress("LongParameterList") actual fun realm_app_call_function( app: RealmAppPointer, user: RealmUserPointer, name: String, + serviceName: String?, serializedEjsonArgs: String, callback: AppCallback ) { - realmc.realm_app_call_function(app.cptr(), user.cptr(), name, serializedEjsonArgs, null, callback) + realmc.realm_app_call_function(app.cptr(), user.cptr(), name, serializedEjsonArgs, serviceName, callback) } actual fun realm_app_call_reset_password_function( diff --git a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index d360bf7981..9409b13044 100644 --- a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -3262,6 +3262,7 @@ actual object RealmInterop { app: RealmAppPointer, user: RealmUserPointer, name: String, + serviceName: String?, serializedEjsonArgs: String, callback: AppCallback ) { @@ -3270,7 +3271,7 @@ actual object RealmInterop { user.cptr(), name, serializedEjsonArgs, - null, + serviceName, staticCFunction { userData: CPointer?, data: CPointer>?, error: CPointer? -> handleAppCallback(userData, error) { data.safeKString() diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmInstantImpl.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmInstantImpl.kt index 8f0c714fac..cdc7d7fabe 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmInstantImpl.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmInstantImpl.kt @@ -36,13 +36,15 @@ public fun RealmInstant.toDuration(): Duration { return epochSeconds.seconds + nanosecondsOfSecond.nanoseconds } -internal fun Duration.toRealmInstant(): RealmInstant { +public fun Duration.toRealmInstant(): RealmInstant { val seconds: Long = this.inWholeSeconds - val nanos: Duration = (this - seconds.seconds) - return RealmInstant.from(seconds, nanos.inWholeNanoseconds.toInt()) + // We cannot do duration arithmetic as some operations on INFINITE and NEG_INFINITE will overflow + val nanos: Int = (this.inWholeNanoseconds - (seconds * RealmInstant.SEC_AS_NANOSECOND)).toInt() + return RealmInstant.from(seconds, nanos) } internal fun RealmInstant.restrictToMillisPrecision() = toDuration().inWholeMilliseconds.milliseconds.toRealmInstant() -internal fun RealmInstant.asBsonDateTime() = BsonDateTime(toDuration().inWholeMilliseconds) +public inline fun RealmInstant.asBsonDateTime(): BsonDateTime = BsonDateTime(toDuration().inWholeMilliseconds) +public inline fun BsonDateTime.asRealmInstant(): RealmInstant = value.milliseconds.toRealmInstant() diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmObjectCompanion.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmObjectCompanion.kt index 7f345fdcac..f176abbd90 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmObjectCompanion.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmObjectCompanion.kt @@ -30,7 +30,7 @@ import kotlin.reflect.KProperty1 public interface RealmObjectCompanion { public val `io_realm_kotlin_class`: KClass public val `io_realm_kotlin_className`: String - public val `io_realm_kotlin_fields`: Map> + public val `io_realm_kotlin_fields`: Map, KProperty1>> public val `io_realm_kotlin_primaryKey`: KMutableProperty1<*, *>? public val `io_realm_kotlin_classKind`: RealmClassKind public fun `io_realm_kotlin_schema`(): RealmClassImpl diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmObjectUtil.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmObjectUtil.kt index 06c796f828..ea4b858a9b 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmObjectUtil.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmObjectUtil.kt @@ -107,6 +107,7 @@ internal fun RealmObjectReference.toRealmObject(): T = * Returns the [RealmObjectCompanion] associated with a given [BaseRealmObject]'s [KClass]. */ internal inline fun KClass<*>.realmObjectCompanionOrNull(): RealmObjectCompanion? { + @Suppress("invisible_reference", "invisible_member") return realmObjectCompanionOrNull(this) } @@ -114,6 +115,7 @@ internal inline fun KClass<*>.realmObjectCompanionOrNull(): RealmObjectCompanion * Returns the [RealmObjectCompanion] associated with a given [BaseRealmObject]'s [KClass]. */ internal inline fun KClass.realmObjectCompanionOrThrow(): RealmObjectCompanion { + @Suppress("invisible_reference", "invisible_member") return realmObjectCompanionOrThrow(this) } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmUUIDImpl.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmUUIDImpl.kt index 6d366fde35..17c630915b 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmUUIDImpl.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmUUIDImpl.kt @@ -21,6 +21,8 @@ import io.realm.kotlin.internal.util.HEX_PATTERN import io.realm.kotlin.internal.util.parseHex import io.realm.kotlin.internal.util.toHexString import io.realm.kotlin.types.RealmUUID +import org.mongodb.kbson.BsonBinary +import org.mongodb.kbson.BsonBinarySubType import kotlin.experimental.and import kotlin.experimental.or @@ -101,3 +103,6 @@ public class RealmUUIDImpl : RealmUUID { } } } + +public inline fun RealmUUID.asBsonBinary(): BsonBinary = BsonBinary(BsonBinarySubType.UUID_STANDARD, bytes) +public inline fun BsonBinary.asRealmUUID(): RealmUUID = RealmUUID.from(data) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt index 969b2e7ba0..610a56e443 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt @@ -25,9 +25,12 @@ import kotlin.reflect.KClass * associated [RealmObjectCompanion], in which case the `clazz` wasn't a user defined class * implementing [BaseRealmObject] augmented by our compiler plugin. */ +@PublishedApi internal expect fun realmObjectCompanionOrNull(clazz: KClass): RealmObjectCompanion? /** * Returns the [RealmObjectCompanion] associated with a given [BaseRealmObject]'s [KClass]. */ + +@PublishedApi internal expect fun realmObjectCompanionOrThrow(clazz: KClass): RealmObjectCompanion diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/schema/CachedClassKeyMap.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/schema/CachedClassKeyMap.kt index 7da918259f..4f781f60a5 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/schema/CachedClassKeyMap.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/schema/CachedClassKeyMap.kt @@ -147,7 +147,7 @@ public class CachedClassMetadata( properties = interopProperties.map { propertyInfo: PropertyInfo -> CachedPropertyMetadata( propertyInfo, - companion?.io_realm_kotlin_fields?.get(propertyInfo.name) + companion?.io_realm_kotlin_fields?.get(propertyInfo.name)?.second ) } } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/schema/RealmPropertyTypeImpl.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/schema/RealmPropertyTypeImpl.kt new file mode 100644 index 0000000000..62e8ca704a --- /dev/null +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/schema/RealmPropertyTypeImpl.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2024 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.internal.schema + +import io.realm.kotlin.internal.interop.CollectionType +import io.realm.kotlin.schema.ListPropertyType +import io.realm.kotlin.schema.MapPropertyType +import io.realm.kotlin.schema.RealmPropertyType +import io.realm.kotlin.schema.SetPropertyType +import io.realm.kotlin.schema.ValuePropertyType + +public val RealmPropertyType.collectionType: CollectionType + get() { + return when (this) { + is ListPropertyType -> CollectionType.RLM_COLLECTION_TYPE_LIST + is MapPropertyType -> CollectionType.RLM_COLLECTION_TYPE_DICTIONARY + is SetPropertyType -> CollectionType.RLM_COLLECTION_TYPE_SET + is ValuePropertyType -> CollectionType.RLM_COLLECTION_TYPE_NONE + } + } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/util/Validation.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/util/Validation.kt index 7172efdc20..7b37f1c900 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/util/Validation.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/util/Validation.kt @@ -38,7 +38,7 @@ public object Validation { * to that type, otherwise an IllegalArgumentException is thrown with the provided error message. */ @OptIn(ExperimentalContracts::class) - public inline fun isType(arg: Any?, errorMessage: String) { + public inline fun isType(arg: Any?, errorMessage: String = "Object '$arg' is not of type ${T::class.qualifiedName}") { contract { returns() implies (arg is T) } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/serializers/RealmKSerializers.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/serializers/RealmKSerializers.kt index 94a796edc4..23fb32227a 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/serializers/RealmKSerializers.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/serializers/RealmKSerializers.kt @@ -19,8 +19,8 @@ import io.realm.kotlin.ext.asRealmObject import io.realm.kotlin.ext.toRealmDictionary import io.realm.kotlin.ext.toRealmList import io.realm.kotlin.ext.toRealmSet -import io.realm.kotlin.internal.toDuration -import io.realm.kotlin.internal.toRealmInstant +import io.realm.kotlin.internal.asBsonDateTime +import io.realm.kotlin.internal.asRealmInstant import io.realm.kotlin.types.MutableRealmInt import io.realm.kotlin.types.RealmAny import io.realm.kotlin.types.RealmAny.Type @@ -46,7 +46,6 @@ import org.mongodb.kbson.BsonBinarySubType import org.mongodb.kbson.BsonDateTime import org.mongodb.kbson.BsonObjectId import org.mongodb.kbson.Decimal128 -import kotlin.time.Duration.Companion.milliseconds /** * KSerializer implementation for [RealmList]. Serialization is done as a generic list structure, @@ -250,12 +249,12 @@ public object RealmInstantKSerializer : KSerializer { override val descriptor: SerialDescriptor = serializer.descriptor override fun deserialize(decoder: Decoder): RealmInstant = - decoder.decodeSerializableValue(serializer).value.milliseconds.toRealmInstant() + decoder.decodeSerializableValue(serializer).asRealmInstant() override fun serialize(encoder: Encoder, value: RealmInstant) { encoder.encodeSerializableValue( serializer = serializer, - value = BsonDateTime(value.toDuration().inWholeMilliseconds) + value = value.asBsonDateTime() ) } } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/types/RealmInstant.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/types/RealmInstant.kt index 280bbe9e7f..17c66526dc 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/types/RealmInstant.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/types/RealmInstant.kt @@ -37,7 +37,7 @@ import io.realm.kotlin.internal.platform.currentTime public interface RealmInstant : Comparable { public companion object { - private const val SEC_AS_NANOSECOND: Int = 1_000_000_000 + internal const val SEC_AS_NANOSECOND: Int = 1_000_000_000 /** * Minimum timestamp that can be stored in Realm. diff --git a/packages/library-base/src/jvm/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt b/packages/library-base/src/jvm/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt index 0bf754fa9d..97f948eafb 100644 --- a/packages/library-base/src/jvm/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt +++ b/packages/library-base/src/jvm/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt @@ -23,11 +23,13 @@ import kotlin.reflect.full.companionObjectInstance // TODO OPTIMIZE Can we eliminate the reflective approach? Maybe by embedding the information // through the compiler plugin or something similar to the Native findAssociatedObject +@PublishedApi internal actual fun realmObjectCompanionOrNull(clazz: KClass): RealmObjectCompanion? = if (clazz.companionObjectInstance is RealmObjectCompanion) { clazz.companionObjectInstance as RealmObjectCompanion } else null +@PublishedApi internal actual fun realmObjectCompanionOrThrow(clazz: KClass): RealmObjectCompanion = realmObjectCompanionOrNull(clazz) ?: error("Couldn't find companion object of class '${clazz.simpleName}'.\nA common cause for this is when the `io.realm.kotlin` is not applied to the Gradle module that contains the '${clazz.simpleName}' class.") diff --git a/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt b/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt index 455cb38dac..2d2d81f811 100644 --- a/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt +++ b/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt @@ -22,6 +22,7 @@ import kotlin.reflect.ExperimentalAssociatedObjects import kotlin.reflect.KClass import kotlin.reflect.findAssociatedObject +@PublishedApi internal actual fun realmObjectCompanionOrNull(clazz: KClass): RealmObjectCompanion? = @OptIn(ExperimentalAssociatedObjects::class) when (val associatedObject = clazz.findAssociatedObject()) { @@ -29,6 +30,7 @@ internal actual fun realmObjectCompanionOrNull(clazz: KClass): Real else -> null } +@PublishedApi internal actual fun realmObjectCompanionOrThrow(clazz: KClass): RealmObjectCompanion = realmObjectCompanionOrNull(clazz) ?: error("Couldn't find companion object of class '${clazz.simpleName}'.\nA common cause for this is when the `io.realm.kotlin` is not applied to the Gradle module that contains the '${clazz.simpleName}' class.") diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/User.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/User.kt index 17d696a345..e7ce1120f8 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/User.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/User.kt @@ -20,7 +20,10 @@ import io.realm.kotlin.mongodb.auth.ApiKeyAuth import io.realm.kotlin.mongodb.exceptions.AppException import io.realm.kotlin.mongodb.ext.customDataAsBsonDocument import io.realm.kotlin.mongodb.ext.profileAsBsonDocument +import io.realm.kotlin.mongodb.mongo.MongoClient import io.realm.kotlin.mongodb.sync.SyncConfiguration +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import org.mongodb.kbson.serialization.EJson /** * A **user** holds the user's metadata and tokens for accessing App Services and Device Sync @@ -186,6 +189,25 @@ public interface User { */ public suspend fun linkCredentials(credentials: Credentials): User + /** + * Get a [MongoClient] for accessing documents from App Service's _Data Source_. + * + * Serialization to and from EJSON is performed with [KBSON](https://github.com/mongodb/kbson) + * that supports the [Kotlin Serialization framework](https://github.com/Kotlin/kotlinx.serialization) + * and handles serialization to and from classes marked with [Serializable]. Serialization of + * realm objects and links have some caveats and requires special configuration. For full + * details see [MongoClient]. + * + * @param serviceName the name of the data service. + * @param eJson the EJson serializer that the [MongoClient] should use to convert objects and + * primary keys with. Will default to the app's [EJson] instance configured with + * [AppConfiguration.Builder.ejson]. For details on configuration of serialization see + * [MongoClient]. + * throws IllegalStateException if trying to obtain a [MongoClient] from a logged out [User]. + */ + @ExperimentalKBsonSerializerApi + public fun mongoClient(serviceName: String, eJson: EJson? = null): MongoClient + /** * Two Users are considered equal if they have the same user identity and are associated * with the same app. diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/exceptions/ServiceExceptions.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/exceptions/ServiceExceptions.kt index 1b8b10feaf..6d2a4db3c9 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/exceptions/ServiceExceptions.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/exceptions/ServiceExceptions.kt @@ -20,8 +20,8 @@ import io.realm.kotlin.internal.interop.CodeDescription /** * This exception is considered the top-level or "catch-all" for problems related to HTTP requests - * made towards App Services. This covers both HTTP transport problems, problems passing JSON - * or the server considering the request invalid, for whatever reason. + * made towards App Services. This covers both HTTP transport problems, or the server considering + * the request invalid, for whatever reason. * * Generally, reacting to this exception will be hard, except to log the error for further * analysis. But in many cases a more specific subtype will be thrown, which will be easier to @@ -31,7 +31,7 @@ import io.realm.kotlin.internal.interop.CodeDescription * @see BadRequestException * @see AuthException */ -public open class ServiceException internal constructor( +public open class ServiceException @PublishedApi internal constructor( message: String, internal val errorCode: CodeDescription? = null ) : AppException(message) diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/ext/MongoClientExt.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/ext/MongoClientExt.kt new file mode 100644 index 0000000000..e64b01c6b1 --- /dev/null +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/ext/MongoClientExt.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2024 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.mongodb.ext + +import io.realm.kotlin.mongodb.internal.MongoClientCollection +import io.realm.kotlin.mongodb.internal.MongoClientImpl +import io.realm.kotlin.mongodb.mongo.MongoClient +import io.realm.kotlin.mongodb.mongo.MongoCollection +import io.realm.kotlin.types.BaseRealmObject +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import org.mongodb.kbson.serialization.EJson + +/** + * Get a [MongoCollection] that exposes methods to retrieve and update data from the remote + * collection of objects of schema type [T]. + * + * Serialization to and from EJSON is performed with [KBSON](https://github.com/mongodb/kbson) + * and requires to opt-in to the experimental [ExperimentalKBsonSerializerApi]-feature. + * + * @param eJson the EJson serializer that the [MongoCollection] should use to convert objects and + * primary keys with. Will default to the databases [EJson] instance. + * @param T the schema type indicating which for which remote entities of the collection will be + * serialized from and to. + * @return a [MongoCollection] that will accept and return entities from the remote collection + * as [T] values. + */ +@ExperimentalKBsonSerializerApi +public inline fun MongoClient.collection(eJson: EJson? = null): MongoCollection { + @Suppress("invisible_reference", "invisible_member") + return MongoClientCollection(this as MongoClientImpl, io.realm.kotlin.internal.platform.realmObjectCompanionOrThrow(T::class).io_realm_kotlin_className, eJson ?: this.eJson) +} diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/ext/MongoCollectionExt.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/ext/MongoCollectionExt.kt new file mode 100644 index 0000000000..60cba26cf2 --- /dev/null +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/ext/MongoCollectionExt.kt @@ -0,0 +1,290 @@ +/* + * Copyright 2024 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.mongodb.ext + +import io.realm.kotlin.internal.util.Validation +import io.realm.kotlin.mongodb.exceptions.ServiceException +import io.realm.kotlin.mongodb.internal.MongoCollectionImpl +import io.realm.kotlin.mongodb.internal.decodeFromBsonValue +import io.realm.kotlin.mongodb.internal.decodeFromBsonValueList +import io.realm.kotlin.mongodb.internal.encodeToBsonValue +import io.realm.kotlin.mongodb.internal.toAny +import io.realm.kotlin.mongodb.mongo.MongoCollection +import org.mongodb.kbson.BsonDocument +import org.mongodb.kbson.BsonValue +import kotlin.jvm.JvmName + +/** + * Returns the number of documents in the collection. + * + * @param filter a filter to select specific documents. If `null` then no filtering will be done. + * @param limit an upper bound of the number of documents to consider. If `null` then no limit is + * applied. + * @throws ServiceException if the underlying App Service HTTP requests fails. + */ +public suspend fun MongoCollection<*>.count(filter: BsonDocument? = null, limit: Long? = null): Long { + Validation.isType>(this) + return count(filter, limit) +} + +/** + * Retrieve a single object from the remote collection. + * + * @param filter a filter to select specific documents. If `null` then no filtering will be done. + * @param projection a BsonDocument that describes which fields that are returned from the server. + * If `null` then all fields will be returned. + * @param sort a document describing one or more fields used to sort documents before selecting the + * single document to return. If `null` then no sorting will be applied. + * @return the result of the remote `findOne` invocation deserialized into a [T]-instance. + * @throws ServiceException if the underlying App Service HTTP requests fails. + * @throws SerializationException if App Service response could not be deserialized to [T]. + */ +public suspend inline fun MongoCollection.findOne(filter: BsonDocument? = null, projection: BsonDocument? = null, sort: BsonDocument? = null): T? { + Validation.isType>(this) + val bsonValue: BsonValue = findOne(filter, projection, sort) + val decodeFromBsonValue: T? = decodeFromBsonValue(bsonValue) + return decodeFromBsonValue +} + +/** + * Retrieve multiple object from the remote collection. + * + * @param filter a filter to select specific documents. If `null` then no filtering will be done. + * @param projection a BsonDocument that describes which fields that are returned from the server. + * If `null` then all fields will be returned. + * @param sort a document describing one or more fields used to sort documents before selecting the + * single document to return. If `null` then no sorting will be applied. + * @param limit an upper bound of the number of documents to consider. If `null` then no limit is + * applied. + * @return the result of the remote `find` invocation deserialized into a list of [T]-instances. + * @throws ServiceException if the underlying App Service HTTP requests fails. + * @throws SerializationException if App Service response could not be deserialized to `List`. + */ +public suspend inline fun MongoCollection.find(filter: BsonDocument? = null, projection: BsonDocument? = null, sort: BsonDocument? = null, limit: Long? = null): List { + Validation.isType>(this) + return find(filter, projection, sort, limit).asArray().map { decodeFromBsonValue(it) } +} + +/** + * Execute an aggregate pipeline on the remote collection. + * + * @param pipeline a list of aggregation pipeline stages. + * @return the result of the remote `aggregate` invocation deserialized into a list of [T]-instances. + * @throws ServiceException if the underlying App Service HTTP requests fails. + * @throws SerializationException if App Service response could not be deserialized to `List`. + */ +public suspend inline fun MongoCollection<*>.aggregate(pipeline: List): List { + Validation.isType>(this) + return decodeFromBsonValueList(aggregate(pipeline)) +} + +/** + * Insert a single object into the remote collection. + * + * @param document the object to serialize and insert into the remote collection. + * @return the `_id` value of the document insert in the collection deserialized to the most appropriate type. + * @throws ServiceException if the underlying App Service HTTP requests fails. + * @throws SerializationException if [document] could not be serialized into a EJson document or if + * the App Service response could not be parsed into a reasonable type. + */ +public suspend inline fun MongoCollection.insertOne(document: T): Any { + Validation.isType>(this) + return insertOne(encodeToBsonValue(document).asDocument()).toAny() ?: throw ServiceException("No primary key for inserted document") +} + +/** + * Insert a list of object into the remote collection. + * + * @param documents the objects to serialize and insert into the remote collection. + * @param T the type of object that should be serializer and inserted to the collection. + * @param R the type that the returned `_id` values should be deserialized into. + * @return the `_id` values of the documents inserted in the collection deserialized to a [R]-instance. + * @throws ServiceException if the underlying App Service HTTP requests fails. + * @throws SerializationException if [documents] could not be serialized into a EJson document or if + * the App Service response could not be deserialized to `List`. + */ +@JvmName("insertManyTyped") +public suspend inline fun MongoCollection<*>.insertMany(documents: Collection): List { + Validation.isType>(this) + val bsonValues: List = insertMany(documents.map { encodeToBsonValue(it).asDocument() }) + return bsonValues.map { it.toAny() ?: throw ServiceException("Response should not contain null values: $bsonValues") } +} + +/** + * Delete a single object from the remote collection. + * + * @param filter a filter to specify the documents to delete. + * @return a boolean indicating if a document was deleted or not. + * @throws ServiceException if the underlying App Service HTTP requests fails. + */ +public suspend fun MongoCollection<*>.deleteOne(filter: BsonDocument): Boolean { + Validation.isType>(this) + return deleteOne(filter) +} + +/** + * Delete multiple objects from the remote collection. + * + * @param filter a filter to specify the documents to delete. + * @return the number of documents that have been deleted. + * @throws ServiceException if the underlying App Service HTTP requests fails. + */ +public suspend fun MongoCollection<*>.deleteMany(filter: BsonDocument): Long { + Validation.isType>(this) + return deleteMany(filter) +} + +/** + * Wrapper of results of an [updateOne] call. + * + * @param updated boolean indicating that a document was updated. + * @param upsertedId primary key of the new document if created. + */ +public data class UpdateOneResult(val updated: Boolean, val upsertedId: Any?) + +/** + * Update or insert a single object in the remote collection. + * + * @param filter a filter to select the document to update. + * @param update a BsonDocument specifying the updates that should be applied to the document. + * @param upsert a boolean indicating if a new document should be inserted if the [filter] does not + * match any existing documents in the collection. + * @return the result of the `updateOne` operation. + * @throws ServiceException if the underlying App Service HTTP requests fails. + * @throws SerializationException if App Service response could not be deserialized to + * [UpdateOneResult]. + */ +public suspend inline fun MongoCollection<*>.updateOne( + filter: BsonDocument, + update: BsonDocument, + upsert: Boolean = false +): UpdateOneResult { + Validation.isType>(this) + return updateOne(filter, update, upsert).let { (updated, upsertedId) -> + UpdateOneResult(updated, upsertedId?.let { it.toAny() }) + } +} + +/** + * Wrapper of results of an [updateMany] call. + * + * @param modifiedCount number of documents that was updated by the operation. + * @param upsertedId primary key of the new document if created. + */ +public data class UpdateManyResult(val modifiedCount: Long, val upsertedId: Any?) + +/** + * Update multiple objects or insert a single new object in the remote collection. + * + * @param filter a filter to select the documents to update. + * @param update a BsonDocument specifying the updates that should be applied to the documents. + * @param upsert a boolean indicating if a new document should be inserted if the [filter] does not + * match any existing documents in the collection. + * @return the result of the `updateMany` operation. + * @throws ServiceException if the underlying App Service HTTP requests fails. + * @throws SerializationException if App Service response could not be deserialized to + * [UpdateManyResult]. + */ +public suspend inline fun MongoCollection<*>.updateMany( + filter: BsonDocument, + update: BsonDocument, + upsert: Boolean = false +): UpdateManyResult { + Validation.isType>(this) + return updateMany(filter, update, upsert).let { (updatedCount, upsertedId) -> + UpdateManyResult(updatedCount, upsertedId?.toAny()) + } +} + +/** + * Find and update or insert a single new object in the remote collection. + * + * @param filter a filter to select the documents to update. + * @param update a BsonDocument specifying the updates that should be applied to the documents. + * @param projection a BsonDocument that describes which fields that are returned from the server. + * If `null` then all fields will be returned. + * @param sort a document describing one or more fields used to sort documents before selecting the + * single document to return. If `null` then no sorting will be applied. + * @param upsert a boolean indicating if a new document should be inserted if the [filter] does not + * match any existing documents in the collection. + * @param returnNewDoc a boolean indicating whether to return the document before or after the update. + * @return the result of the remote `findOneAndUpdate` invocation deserialized into a [T]-instance. + * @throws ServiceException if the underlying App Service HTTP requests fails. + * @throws SerializationException if App Service response could not be deserialized to [T]. + */ +@Suppress("LongParameterList") +public suspend inline fun MongoCollection.findOneAndUpdate( + filter: BsonDocument, + update: BsonDocument, + projection: BsonDocument? = null, + sort: BsonDocument? = null, + upsert: Boolean = false, + returnNewDoc: Boolean = false, +): T? { + Validation.isType>(this) + return decodeFromBsonValue(findOneAndUpdate(filter, update, projection, sort, upsert, returnNewDoc)) +} + +/** + * Find and replace or insert a single new object in the remote collection. + * + * @param filter a filter to select the documents to update. + * @param document a BsonDocument specifying the updates that should be applied to the documents. + * @param projection a BsonDocument that describes which fields that are returned from the server. + * If `null` then all fields will be returned. + * @param sort a document describing one or more fields used to sort documents before selecting the + * single document to return. If `null` then no sorting will be applied. + * @param upsert a boolean indicating if a new document should be inserted if the [filter] does not + * match any existing documents in the collection. + * @param returnNewDoc a boolean indicating whether to return the document before or after the update. + * @return the result of the remote `findOneAndReplace` invocation deserialized into a [T]-instance. + * @throws ServiceException if the underlying App Service HTTP requests fails. + * @throws SerializationException if App Service response could not be deserialized to [T]. + */ +@Suppress("LongParameterList") +public suspend inline fun MongoCollection.findOneAndReplace( + filter: BsonDocument, + document: BsonDocument, + projection: BsonDocument? = null, + sort: BsonDocument? = null, + upsert: Boolean = false, + returnNewDoc: Boolean = false, +): T? { + Validation.isType>(this) + return decodeFromBsonValue(findOneAndReplace(filter, document, projection, sort, upsert, returnNewDoc)) +} + +/** + * Find and delete a single object in the remote collection. + * + * @param filter a filter to select the documents to update. + * @param projection a BsonDocument that describes which fields that are returned from the server. + * If `null` then all fields will be returned. + * @param sort a document describing one or more fields used to sort documents before selecting the + * single document to return. If `null` then no sorting will be applied. + * @return the result of the remote `findOneAndDelete` invocation deserialized into a [T]-instance. + * @throws ServiceException if the underlying App Service HTTP requests fails. + * @throws SerializationException if App Service response could not be deserialized to [T]. + */ +public suspend inline fun MongoCollection.findOneAndDelete( + filter: BsonDocument, + projection: BsonDocument? = null, + sort: BsonDocument? = null, +): T? { + Validation.isType>(this) + return decodeFromBsonValue(findOneAndDelete(filter, projection, sort)) +} diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/ext/UserExt.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/ext/UserExt.kt index 5f3a1527a9..72384cff01 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/ext/UserExt.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/ext/UserExt.kt @@ -62,56 +62,13 @@ public inline fun User.customDataAsBsonDocument(): BsonDocument? = */ @ExperimentalRealmSerializerApi @OptIn(ExperimentalKBsonSerializerApi::class) -public fun User.profile(serializer: KSerializer): T = +public inline fun User.profile(serializer: KSerializer = (this as UserImpl).app.configuration.ejson.serializersModule.serializerOrRealmBuiltInSerializer()): T = (this as UserImpl).app.configuration.ejson.let { ejson: EJson -> profileInternal { ejsonEncodedProfile -> ejson.decodeFromString(serializer, ejsonEncodedProfile) } } -/** - * Returns the profile for this user as a [T]. - * - * **Note** This method supports full document serialization. The user profile will be deserialized with - * the built-in serializer for [T] and decoded with [AppConfiguration.ejson]. - * - * @param T the type to decoded the user profile. - * @return The profile for this user. - */ -@ExperimentalRealmSerializerApi -@OptIn(ExperimentalKBsonSerializerApi::class) -public inline fun User.profile(): T = - profile( - (this as UserImpl).app - .configuration - .ejson - .serializersModule - .serializerOrRealmBuiltInSerializer() - ) - -/** - * Returns the custom user data associated with the user in the Realm App as [T]. - * - * The data is only refreshed when the user's access token is refreshed or when explicitly - * calling [User.refreshCustomData]. - * - * **Note** This method supports full document serialization. Custom data will be deserialized with - * the built-in serializer for [T] and decoded with [AppConfiguration.ejson]. - * - * @param T the type to decoded the user custom data. - * @return The custom user data associated with the user. - */ -@ExperimentalRealmSerializerApi -@OptIn(ExperimentalKBsonSerializerApi::class) -public inline fun User.customData(): T? = - customData( - (this as UserImpl).app - .configuration - .ejson - .serializersModule - .serializerOrRealmBuiltInSerializer() - ) - /** * Returns the custom user data associated with the user in the Realm App as [T]. * @@ -127,7 +84,7 @@ public inline fun User.customData(): T? = */ @ExperimentalRealmSerializerApi @OptIn(ExperimentalKBsonSerializerApi::class) -public fun User.customData(serializer: KSerializer): T? = +public inline fun User.customData(serializer: KSerializer = (this as UserImpl).app.configuration.ejson.serializersModule.serializerOrRealmBuiltInSerializer()): T? = (this as UserImpl).app.configuration.ejson.let { ejson: EJson -> customDataInternal { ejsonEncodedCustomData -> ejson.decodeFromString( diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/FunctionsImpl.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/FunctionsImpl.kt index 1a1cad2331..2862672300 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/FunctionsImpl.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/FunctionsImpl.kt @@ -19,21 +19,25 @@ import io.realm.kotlin.internal.interop.RealmInterop import io.realm.kotlin.internal.util.use import io.realm.kotlin.mongodb.Functions import kotlinx.coroutines.channels.Channel +import org.mongodb.kbson.BsonValue +import org.mongodb.kbson.serialization.Bson @PublishedApi internal class FunctionsImpl( override val app: AppImpl, - override val user: UserImpl + override val user: UserImpl, + val serviceName: String? = null, ) : Functions { @PublishedApi internal suspend fun callInternal( - name: String, + functionName: String, serializedEjsonArgs: String ): String = Channel>(1).use { channel -> RealmInterop.realm_app_call_function( app = app.nativePointer, user = user.nativePointer, - name = name, + name = functionName, + serviceName = serviceName, serializedEjsonArgs = serializedEjsonArgs, callback = channelResultCallback(channel) { ejsonEncodedObject: String -> // First we decode from ejson -> BsonValue @@ -44,4 +48,7 @@ internal class FunctionsImpl( return channel.receive().getOrThrow() } + + internal suspend fun callInternal(functionName: String, bsonValue: BsonValue): BsonValue = + Bson(callInternal(functionName, Bson.toJson(bsonValue))) } diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/MongoClientImpl.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/MongoClientImpl.kt new file mode 100644 index 0000000000..aecc890765 --- /dev/null +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/MongoClientImpl.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2023 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.mongodb.internal + +import io.realm.kotlin.mongodb.mongo.MongoClient +import io.realm.kotlin.mongodb.mongo.MongoDatabase +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import org.mongodb.kbson.serialization.EJson + +@PublishedApi +@OptIn(ExperimentalKBsonSerializerApi::class) +internal class MongoClientImpl( + internal val user: UserImpl, + override val serviceName: String, + val eJson: EJson, +) : MongoClient { + + val functions = FunctionsImpl(user.app, user, serviceName) + + override fun database(databaseName: String, eJson: EJson?): MongoDatabase = + MongoDatabaseImpl(this, databaseName, eJson ?: this.eJson) +} diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/MongoCollectionImpl.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/MongoCollectionImpl.kt new file mode 100644 index 0000000000..a8af3b37a5 --- /dev/null +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/MongoCollectionImpl.kt @@ -0,0 +1,268 @@ +/* + * Copyright 2023 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.mongodb.internal + +import io.realm.kotlin.mongodb.exceptions.ServiceException +import io.realm.kotlin.mongodb.mongo.MongoCollection +import org.mongodb.kbson.BsonArray +import org.mongodb.kbson.BsonBoolean +import org.mongodb.kbson.BsonDocument +import org.mongodb.kbson.BsonInt64 +import org.mongodb.kbson.BsonNull +import org.mongodb.kbson.BsonString +import org.mongodb.kbson.BsonType +import org.mongodb.kbson.BsonValue +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import org.mongodb.kbson.serialization.EJson +import org.mongodb.kbson.serialization.decodeFromBsonValue +import org.mongodb.kbson.serialization.encodeToBsonValue + +@PublishedApi +@OptIn(ExperimentalKBsonSerializerApi::class) +internal class MongoDatabaseCollection(@PublishedApi internal val database: MongoDatabaseImpl, override val name: String, eJson: EJson) : MongoCollectionImpl(database.client.functions, eJson) { + override val defaults: Map = mapOf( + "database" to BsonString(database.name), + "collection" to BsonString(name), + ) + override fun withDocumentClass(eJson: EJson?): MongoCollection { + return MongoDatabaseCollection(this.database, this.name, eJson ?: this.eJson) + } +} + +@PublishedApi +@OptIn(ExperimentalKBsonSerializerApi::class) +internal class MongoClientCollection(@PublishedApi internal val clientImpl: MongoClientImpl, override val name: String, eJson: EJson) : MongoCollectionImpl(clientImpl.functions, eJson) { + override val defaults: Map = mapOf( + "schema_name" to BsonString(name), + ) + override fun withDocumentClass(eJson: EJson?): MongoCollection { + return MongoClientCollection(clientImpl, name, eJson ?: this.eJson) + } +} + +@PublishedApi +@OptIn(ExperimentalKBsonSerializerApi::class) +internal abstract class MongoCollectionImpl constructor( + val functions: FunctionsImpl, + val eJson: EJson, +) : MongoCollection { + + // Default entries for the argument document submitted for the function call. + abstract val defaults: Map + + private suspend fun call(name: String, arguments: MutableMap.() -> Unit): BsonValue { + val doc = defaults.toMutableMap() + arguments(doc) + val argument = BsonDocument(doc) + return functions.callInternal(name, BsonArray(listOf(argument))) + } + + @PublishedApi + internal suspend fun count(filter: BsonDocument? = null, limit: Long? = null): Long { + return decodeFromBsonValue( + call("count") { + filter?.let { put("query", it) } + limit?.let { put("limit", BsonInt64(it)) } + } + ) + } + + @PublishedApi + internal suspend fun findOne(filter: BsonDocument? = null, projection: BsonDocument? = null, sort: BsonDocument? = null): BsonValue { + val call: BsonValue = call("findOne") { + filter?.let { put("query", it) } + projection?.let { put("project", it) } + sort?.let { put("sort", it) } + } + return call + } + + @PublishedApi + internal suspend fun find(filter: BsonDocument? = null, projection: BsonDocument? = null, sort: BsonDocument? = null, limit: Long? = null): BsonValue = + call("find") { + filter?.let { put("query", it) } + projection?.let { put("project", it) } + sort?.let { put("sort", it) } + limit?.let { put("limit", BsonInt64(it)) } + } + + @PublishedApi + internal suspend fun aggregate(pipeline: List): List = + call("aggregate") { put("pipeline", BsonArray(pipeline)) }.asArray().toList() + + @PublishedApi + internal suspend fun insertOne(document: BsonDocument): BsonValue = + call("insertOne") { put("document", document) }.asDocument()["insertedId"]!! + + @PublishedApi + internal suspend fun insertMany(documents: List): List = + call("insertMany") { + put("documents", BsonArray(documents)) + }.asDocument()["insertedIds"]!!.asArray().toList() + + @PublishedApi + internal suspend fun deleteOne(filter: BsonDocument): Boolean { + val deletedCountBson = call("deleteOne") { + put("query", filter) + }.asDocument()["deletedCount"]!! + val deletedCount = decodeFromBsonValue(deletedCountBson) + return when (deletedCount) { + 0L -> false + 1L -> true + else -> throw ServiceException("Unexpected response from deleteOne: deletedCount=$deletedCount") + } + } + + @PublishedApi + internal suspend fun deleteMany(filter: BsonDocument): Long { + val deletedCountBson = call("deleteMany") { + put("query", filter) + }.asDocument()["deletedCount"]!! + return decodeFromBsonValue(deletedCountBson) + } + + @PublishedApi + internal suspend fun updateOne(filter: BsonDocument, update: BsonDocument, upsert: Boolean = false): Pair { + val response: BsonValue = call("updateOne") { + put("query", filter) + put("update", update) + put("upsert", BsonBoolean(upsert)) + } + return response.asDocument().run { + val modifiedCount: Long? = get("modifiedCount")?.let { decodeFromBsonValue(it) } + val modified = when (modifiedCount) { + 0L -> false + 1L -> true + else -> throw ServiceException("Unexpected response from updateOne: modifiedCount=$modifiedCount") + } + modified to (get("upsertedId")) + } + } + + @PublishedApi + internal suspend fun updateMany(filter: BsonDocument, update: BsonDocument, upsert: Boolean = false): Pair { + val response = call("updateMany") { + put("query", filter) + put("update", update) + put("upsert", BsonBoolean(upsert)) + } + return response.asDocument().run { + decodeFromBsonValue(get("modifiedCount")!!) to (get("upsertedId")) + } + } + + @Suppress("LongParameterList") + @PublishedApi + internal suspend fun findOneAndUpdate( + filter: BsonDocument, + update: BsonDocument, + projection: BsonDocument? = null, + sort: BsonDocument? = null, + upsert: Boolean = false, + returnNewDoc: Boolean = false, + ): BsonValue = call("findOneAndUpdate") { + put("filter", filter) + put("update", update) + projection?.let { put("projection", projection) } + sort?.let { put("sort", sort) } + put("upsert", BsonBoolean(upsert)) + put("returnNewDocument", BsonBoolean(returnNewDoc)) + } + + @Suppress("LongParameterList") + @PublishedApi + internal suspend fun findOneAndReplace( + filter: BsonDocument, + update: BsonDocument, + projection: BsonDocument? = null, + sort: BsonDocument? = null, + upsert: Boolean = false, + returnNewDoc: Boolean = false, + ): BsonValue = call("findOneAndReplace") { + put("filter", filter) + put("update", update) + projection?.let { put("projection", projection) } + sort?.let { put("sort", sort) } + put("upsert", BsonBoolean(upsert)) + put("returnNewDocument", BsonBoolean(returnNewDoc)) + } + + @PublishedApi + internal suspend fun findOneAndDelete( + filter: BsonDocument, + projection: BsonDocument? = null, + sort: BsonDocument? = null, + ): BsonValue = call("findOneAndDelete") { + put("filter", filter) + projection?.let { put("projection", projection) } + sort?.let { put("sort", sort) } + } +} + +@OptIn(ExperimentalKBsonSerializerApi::class) +@PublishedApi +internal inline fun MongoCollectionImpl<*>.encodeToBsonValue(value: R): BsonValue { + return eJson.encodeToBsonValue(value) +} + +@OptIn(ExperimentalKBsonSerializerApi::class) +@PublishedApi +internal inline fun MongoCollectionImpl<*>.decodeFromBsonValue(bsonValue: BsonValue): R = + when { + bsonValue == BsonNull -> null as R + R::class == BsonValue::class -> bsonValue as R + else -> eJson.decodeFromBsonValue(bsonValue) + } + +@OptIn(ExperimentalKBsonSerializerApi::class) +@PublishedApi +internal inline fun MongoCollectionImpl<*>.decodeFromBsonValueList(bsonValues: List): List { + return if (R::class == BsonValue::class) { + bsonValues as List + } else { + bsonValues.map { eJson.decodeFromBsonValue(it) } + } +} + +@Suppress("ComplexMethod") +@PublishedApi +internal fun BsonValue.toAny(): Any? { + return when (this.bsonType) { + BsonType.NULL -> null + BsonType.INT32 -> asInt32().value + BsonType.INT64 -> asInt64().value + BsonType.OBJECT_ID -> this.asObjectId() + BsonType.STRING -> this.asString().value + BsonType.DOUBLE -> this.asDouble().value + BsonType.BINARY -> this.asBinary().data + BsonType.BOOLEAN -> this.asBoolean().value + BsonType.DATE_TIME -> this.asDateTime() + BsonType.ARRAY -> this.asArray().values.map { it.toAny() } + BsonType.DOCUMENT -> this.asDocument().mapValues { (k, v) -> v.toAny() } + BsonType.TIMESTAMP -> asTimestamp() + BsonType.DECIMAL128 -> asDecimal128() + BsonType.DB_POINTER, + BsonType.JAVASCRIPT, + BsonType.SYMBOL, + BsonType.JAVASCRIPT_WITH_SCOPE, + BsonType.REGULAR_EXPRESSION, + BsonType.MIN_KEY, + BsonType.MAX_KEY, + BsonType.END_OF_DOCUMENT, + BsonType.UNDEFINED -> this + } +} diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/MongoDBSerializer.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/MongoDBSerializer.kt new file mode 100644 index 0000000000..10f6a67074 --- /dev/null +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/MongoDBSerializer.kt @@ -0,0 +1,425 @@ +/* + * Copyright 2024 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.mongodb.internal + +import io.realm.kotlin.ext.toRealmDictionary +import io.realm.kotlin.ext.toRealmList +import io.realm.kotlin.ext.toRealmSet +import io.realm.kotlin.internal.RealmObjectCompanion +import io.realm.kotlin.internal.asBsonBinary +import io.realm.kotlin.internal.asBsonDateTime +import io.realm.kotlin.internal.asRealmInstant +import io.realm.kotlin.internal.asRealmUUID +import io.realm.kotlin.internal.interop.CollectionType +import io.realm.kotlin.internal.schema.collectionType +import io.realm.kotlin.internal.util.Validation.sdkError +import io.realm.kotlin.schema.RealmProperty +import io.realm.kotlin.schema.RealmPropertyType +import io.realm.kotlin.schema.RealmStorageType +import io.realm.kotlin.types.BaseRealmObject +import io.realm.kotlin.types.MutableRealmInt +import io.realm.kotlin.types.RealmAny +import io.realm.kotlin.types.RealmInstant +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.RealmUUID +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerializationException +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import org.mongodb.kbson.BsonArray +import org.mongodb.kbson.BsonBinary +import org.mongodb.kbson.BsonBoolean +import org.mongodb.kbson.BsonDocument +import org.mongodb.kbson.BsonDouble +import org.mongodb.kbson.BsonInt32 +import org.mongodb.kbson.BsonInt64 +import org.mongodb.kbson.BsonNull +import org.mongodb.kbson.BsonString +import org.mongodb.kbson.BsonType +import org.mongodb.kbson.BsonValue +import org.mongodb.kbson.Decimal128 +import org.mongodb.kbson.ObjectId +import kotlin.reflect.KClass +import kotlin.reflect.KMutableProperty1 +import kotlin.reflect.KProperty1 + +/** + * Serializer that will encode and decode realm objects to and from EJSON sent and received + * from the MongoClient APIs according to the schema definition of the realm objects. + * + * Serialization of links will only include primary key of the target and deserialization of + * responses from MongoClient will create target link instances where only the primary key is set + * (and all the other properties of the object will have default values). + * + * The target types of links in mixed fields cannot be derived from the schema definition of the + * realm objects. To be able to deserialize and create the correct instance, the serializer needs to + * know of all potential target types. + */ +public class MongoDBSerializer internal constructor( + clazz: KClass, + internal val schema: Map = emptyMap() +) : KSerializer { + override val descriptor: SerialDescriptor = BsonDocument.serializer().descriptor + @Suppress("invisible_reference", "invisible_member") + private val companion = io.realm.kotlin.internal.platform.realmObjectCompanionOrThrow(clazz) + + override fun deserialize(decoder: Decoder): BaseRealmObject { + return bsonToObject(companion, decoder.decodeSerializableValue(BsonDocument.serializer())) + } + + private fun bsonToObject(companion: RealmObjectCompanion, bsonDocument: BsonDocument): BaseRealmObject { + val instance = companion.io_realm_kotlin_newInstance() as BaseRealmObject + val fields: Map, KProperty1>> = + companion.io_realm_kotlin_fields + val schema = companion.io_realm_kotlin_schema() + bsonDocument.keys.forEach { key -> + val (kClass, accessor) = fields[key] + ?: throw SerializationException("Unknown field '$key' for type ${companion.io_realm_kotlin_className}") + val type = schema[key]?.type + ?: throw SerializationException("Unknown field '$key' for type ${companion.io_realm_kotlin_className}") + val value = bsonValueToStorageType(type.collectionType, type.storageType, kClass, bsonDocument[key]) + (accessor as KMutableProperty1).set(instance, value) + } + return instance + } + + override fun serialize(encoder: Encoder, value: BaseRealmObject) { + encoder.encodeSerializableValue(BsonDocument.serializer(), objectToBson(companion, value)) + } + + private fun objectToBson( + companion: RealmObjectCompanion, + realmObject: BaseRealmObject, + ): BsonDocument { + val fields: Map, KProperty1>> = + companion.io_realm_kotlin_fields + val schema = companion.io_realm_kotlin_schema() + val document = BsonDocument() + fields.forEach { (fieldName, fieldDetails) -> + val (_, accessor) = fieldDetails + val type: RealmPropertyType = + schema[fieldName]?.type ?: sdkError("Schema does not contain property $fieldName") + storageTypeToBsonValue(type.collectionType, type.storageType, accessor.get(realmObject)).let { + document[fieldName] = it + } + } + return document + } + + @Suppress("LongMethod", "ComplexMethod") + private fun storageTypeToBsonValue( + collectionType: CollectionType, + elementType: RealmStorageType, + value: Any?, + ): BsonValue { + if (value == null) return BsonNull + return when (collectionType) { + CollectionType.RLM_COLLECTION_TYPE_NONE -> { + when (elementType) { + RealmStorageType.BOOL -> BsonBoolean(value as Boolean) + RealmStorageType.INT -> when (value) { + is Byte -> BsonInt32(value.toInt()) + is Char -> BsonInt32(value.code) + is Short -> BsonInt32(value.toInt()) + is Int -> BsonInt32(value) + is Long -> BsonInt64(value) + is MutableRealmInt -> BsonInt64(value.toLong()) + else -> sdkError("Unexpected value of type ${value::class.simpleName} for field with storage type $elementType") + } + RealmStorageType.STRING -> BsonString(value as String) + RealmStorageType.BINARY -> BsonBinary(value as ByteArray) + RealmStorageType.OBJECT -> { + @Suppress("UNCHECKED_CAST") + val targetCompanion = + @Suppress("invisible_reference", "invisible_member") + io.realm.kotlin.internal.platform.realmObjectCompanionOrThrow(value::class as KClass) + @Suppress("UNCHECKED_CAST") + val primaryKeyProperty: KMutableProperty1? = + targetCompanion.io_realm_kotlin_primaryKey as KMutableProperty1? + when (primaryKeyProperty) { + // Embedded objects does not have a primary key, so serialize to full documents + null -> objectToBson(targetCompanion, value as BaseRealmObject) + else -> { + val targetStorageType = + targetCompanion.io_realm_kotlin_schema().primaryKey!!.type.storageType + val primaryKey = primaryKeyProperty.get(value as BaseRealmObject) + storageTypeToBsonValue(CollectionType.RLM_COLLECTION_TYPE_NONE, targetStorageType, primaryKey) + } + } + } + + RealmStorageType.FLOAT -> BsonDouble((value as Float).toDouble()) + RealmStorageType.DOUBLE -> BsonDouble(value as Double) + RealmStorageType.DECIMAL128 -> value as Decimal128 + RealmStorageType.TIMESTAMP -> (value as RealmInstant).asBsonDateTime() + RealmStorageType.OBJECT_ID -> value as ObjectId + RealmStorageType.UUID -> (value as RealmUUID).asBsonBinary() + RealmStorageType.ANY -> { realmAnyToBsonValue(value as RealmAny) } + } + } + CollectionType.RLM_COLLECTION_TYPE_LIST -> { + BsonArray( + (value as List<*>).map { + storageTypeToBsonValue( + CollectionType.RLM_COLLECTION_TYPE_NONE, + elementType, + it + ) + } + ) + } + CollectionType.RLM_COLLECTION_TYPE_SET -> { + BsonArray( + (value as Set<*>).map { + storageTypeToBsonValue( + CollectionType.RLM_COLLECTION_TYPE_NONE, + elementType, + it + ) + } + ) + } + CollectionType.RLM_COLLECTION_TYPE_DICTIONARY -> { + @Suppress("UNCHECKED_CAST") + val map = value as Map + BsonDocument( + map.mapValues { (_, v) -> + storageTypeToBsonValue( + CollectionType.RLM_COLLECTION_TYPE_NONE, + elementType, + v + ) + } + ) + } + else -> sdkError("Unknown collection type: $collectionType") + } + } + + @Suppress("ComplexMethod") + private fun realmAnyToBsonValue(realmAny: RealmAny?): BsonValue = when (realmAny?.type) { + null -> BsonNull + RealmAny.Type.BOOL -> BsonBoolean(realmAny.asBoolean()) + RealmAny.Type.INT -> BsonInt64(realmAny.asLong()) + RealmAny.Type.STRING -> BsonString(realmAny.asString()) + RealmAny.Type.BINARY -> BsonBinary(realmAny.asByteArray()) + RealmAny.Type.TIMESTAMP -> realmAny.asRealmInstant().asBsonDateTime() + RealmAny.Type.FLOAT -> BsonDouble(realmAny.asFloat().toDouble()) + RealmAny.Type.DOUBLE -> BsonDouble(realmAny.asDouble()) + RealmAny.Type.DECIMAL128 -> realmAny.asDecimal128() + RealmAny.Type.OBJECT_ID -> realmAny.asObjectId() + RealmAny.Type.UUID -> realmAny.asRealmUUID().asBsonBinary() + RealmAny.Type.OBJECT -> { + // Objects in RealmAny cannot be EmbeddedObjects + val target = realmAny.asRealmObject(BaseRealmObject::class) + @Suppress("invisible_reference", "invisible_member") + val targetCompanion = io.realm.kotlin.internal.platform.realmObjectCompanionOrThrow(target::class) + val primaryKeySchemaProperty: RealmProperty = targetCompanion.io_realm_kotlin_schema().primaryKey ?: throw SerializationException( + "Cannot serialize class without primary key: '${targetCompanion.io_realm_kotlin_className}'" + ) + val (_, primaryKeyAccessor) = targetCompanion.io_realm_kotlin_fields[primaryKeySchemaProperty.name] ?: throw SerializationException( + "Cannot serialize class without primary key: '${targetCompanion.io_realm_kotlin_className}'" + ) + val primaryKey: BsonValue = storageTypeToBsonValue( + CollectionType.RLM_COLLECTION_TYPE_NONE, + primaryKeySchemaProperty.type.storageType, + primaryKeyAccessor.get(target) + ) + BsonDocument( + "\$ref" to BsonString(targetCompanion.io_realm_kotlin_className), + "\$id" to primaryKey + ) + } + RealmAny.Type.LIST -> { + BsonArray(realmAny.asList().map { realmAnyToBsonValue(it) }) + } + RealmAny.Type.DICTIONARY -> { + BsonDocument(realmAny.asDictionary().mapValues { (_, v) -> realmAnyToBsonValue(v) }) + } + } + + @Suppress("LongMethod", "ComplexMethod") + internal fun bsonValueToStorageType( + collectionType: CollectionType, + elementType: RealmStorageType, + kClass: KClass<*>, + bsonValue: BsonValue?, + ): Any? { + if (bsonValue == null || bsonValue == BsonNull) return null + return when (collectionType) { + CollectionType.RLM_COLLECTION_TYPE_NONE -> when (elementType) { + RealmStorageType.BOOL -> bsonValue.asBoolean().value + RealmStorageType.INT -> when (kClass) { + Byte::class -> bsonValue.asNumber().longValue().toByte() + Char::class -> bsonValue.asNumber().intValue().toChar() + Short::class -> bsonValue.asNumber().intValue().toShort() + Int::class -> bsonValue.asNumber().intValue() + Long::class -> bsonValue.asNumber().longValue() + MutableRealmInt::class -> MutableRealmInt.create( + bsonValue.asNumber().longValue() + ) + else -> sdkError("Unexpected KClass ('${kClass.simpleName}') for element with storage type '$elementType'") + } + RealmStorageType.STRING -> bsonValue.asString().value + RealmStorageType.BINARY -> bsonValue.asBinary().data + RealmStorageType.OBJECT -> { + @Suppress("invisible_reference", "invisible_member") + val targetCompanion = + io.realm.kotlin.internal.platform.realmObjectCompanionOrNull(kClass) + ?: sdkError("Unexpected kClass ('${kClass::simpleName}') without realm companion") + when (val primaryKeySchemaProperty = targetCompanion.io_realm_kotlin_schema().primaryKey) { + // Embedded objects does not have primary keys + null -> bsonToObject(targetCompanion, bsonValue.asDocument()) + else -> { + val (targetKClass, primaryKeyAccessor) = targetCompanion.io_realm_kotlin_fields[primaryKeySchemaProperty.name] + ?: throw SerializationException( + "Target class does not have a primary key: '${targetCompanion.io_realm_kotlin_className}'" + ) + val targetInstance = + (targetCompanion.io_realm_kotlin_newInstance() as BaseRealmObject) + (primaryKeyAccessor as KMutableProperty1).set( + targetInstance, + bsonValueToStorageType( + CollectionType.RLM_COLLECTION_TYPE_NONE, + primaryKeySchemaProperty.type.storageType, + targetKClass, + bsonValue + ) + ) + targetInstance + } + } + } + + RealmStorageType.FLOAT -> bsonValue.asDouble().value.toFloat() + RealmStorageType.DOUBLE -> bsonValue.asDouble().value + RealmStorageType.DECIMAL128 -> bsonValue.asDecimal128() + RealmStorageType.TIMESTAMP -> bsonValue.asDateTime().asRealmInstant() + RealmStorageType.OBJECT_ID -> bsonValue.asObjectId() + RealmStorageType.UUID -> bsonValue.asBinary().asRealmUUID() + RealmStorageType.ANY -> bsonValueToRealmAny(bsonValue) + } + CollectionType.RLM_COLLECTION_TYPE_LIST -> { + ( + bsonValue.asArray().map { + bsonValueToStorageType( + CollectionType.RLM_COLLECTION_TYPE_NONE, elementType, kClass, it + ) + } + ).toRealmList() + } + CollectionType.RLM_COLLECTION_TYPE_DICTIONARY -> { + ( + bsonValue.asDocument().mapValues { + bsonValueToStorageType( + CollectionType.RLM_COLLECTION_TYPE_NONE, elementType, kClass, it.value + ) + } + ).toRealmDictionary() + } + + CollectionType.RLM_COLLECTION_TYPE_SET -> { + ( + bsonValue.asArray().map { + bsonValueToStorageType( + CollectionType.RLM_COLLECTION_TYPE_NONE, elementType, kClass, it + ) + } + ).toRealmSet() + } + else -> sdkError("Unknown collection type: $collectionType") + } + } + + @Suppress("ComplexMethod", "LongMethod") + private fun bsonValueToRealmAny( + bsonValue: BsonValue?, + ): RealmAny? { + return when (bsonValue?.bsonType) { + null, + BsonType.NULL -> null + // RealmAny.Type.FLOAT + // RealmAny.Type.DOUBLE + BsonType.DOUBLE -> RealmAny.create(bsonValue.asDouble().value) + // RealmAny.Type.STRING + BsonType.STRING -> RealmAny.create(bsonValue.asString().value) + // RealmAny.Type.INT + BsonType.INT32 -> RealmAny.create(bsonValue.asInt32().value) + BsonType.INT64 -> RealmAny.create(bsonValue.asInt64().value) + // RealmAny.Type.DECIMAL128 + BsonType.DECIMAL128 -> RealmAny.create(bsonValue.asDecimal128()) + // RealmAny.Type.BINARY + // RealmAny.Type.UUID handled as binary, we can't distinguish it + BsonType.BINARY -> RealmAny.create(bsonValue.asBinary().data) + // RealmAny.Type.OBJECT_ID + BsonType.OBJECT_ID -> RealmAny.Companion.create(bsonValue.asObjectId()) + // RealmAny.Type.BOOL + BsonType.BOOLEAN -> RealmAny.create(bsonValue.asBoolean().value) + // RealmAny.Type.TIMESTAMP + BsonType.DATE_TIME -> RealmAny.Companion.create(bsonValue.asDateTime().asRealmInstant()) + BsonType.DOCUMENT -> { + val document = bsonValue.asDocument() + val type: String? = document["\$ref"]?.asString()?.value + val targetCompanion = schema[type] + val primaryKey = document["\$id"] + if (targetCompanion != null && primaryKey != null) { + val primaryKeySchemaProperty = + targetCompanion.io_realm_kotlin_schema().primaryKey + ?: throw SerializationException( + "Target class does not have a primary key: '${"$"}ref=$type'" + ) + val (primaryKeyType, primaryKeyAccessor) = targetCompanion.io_realm_kotlin_fields[primaryKeySchemaProperty.name] + ?: throw SerializationException( + "Target class does not have a primary key: '${"$"}ref=$type'" + ) + val instance: RealmObject = + targetCompanion.io_realm_kotlin_newInstance() as RealmObject + (primaryKeyAccessor as KMutableProperty1).set( + instance, + bsonValueToStorageType( + CollectionType.RLM_COLLECTION_TYPE_NONE, + primaryKeySchemaProperty.type.storageType, + primaryKeyType, + primaryKey + ) + ) + RealmAny.create(instance) + } else { + RealmAny.create( + document.mapValues { (_, v) -> bsonValueToRealmAny(v) } + .toRealmDictionary() + ) + } + } + BsonType.ARRAY -> { + RealmAny.create(bsonValue.asArray().map { bsonValueToRealmAny(it) }.toRealmList()) + } + BsonType.TIMESTAMP, + BsonType.END_OF_DOCUMENT, + BsonType.UNDEFINED, + BsonType.REGULAR_EXPRESSION, + BsonType.DB_POINTER, + BsonType.JAVASCRIPT, + BsonType.SYMBOL, + BsonType.JAVASCRIPT_WITH_SCOPE, + BsonType.MIN_KEY, + BsonType.MAX_KEY + -> throw SerializationException("Deserializer does not support ${bsonValue.bsonType}") + } + } +} diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/MongoDatabaseImpl.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/MongoDatabaseImpl.kt new file mode 100644 index 0000000000..49fc55b8e5 --- /dev/null +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/MongoDatabaseImpl.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2023 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.mongodb.internal + +import io.realm.kotlin.mongodb.mongo.MongoCollection +import io.realm.kotlin.mongodb.mongo.MongoDatabase +import org.mongodb.kbson.BsonDocument +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import org.mongodb.kbson.serialization.EJson + +@PublishedApi +@OptIn(ExperimentalKBsonSerializerApi::class) +internal class MongoDatabaseImpl constructor( + @PublishedApi + internal val client: MongoClientImpl, + override val name: String, + val eJson: EJson, +) : MongoDatabase { + + override fun collection(collectionName: String): MongoCollection { + return MongoDatabaseCollection(this, collectionName, this.eJson) + } + + override fun collection(collectionName: String, eJson: EJson?): MongoCollection = + MongoDatabaseCollection(this, collectionName, eJson ?: this.eJson) +} diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/UserImpl.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/UserImpl.kt index 17ba80da91..3b41746c5b 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/UserImpl.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/UserImpl.kt @@ -27,7 +27,10 @@ import io.realm.kotlin.mongodb.UserIdentity import io.realm.kotlin.mongodb.auth.ApiKeyAuth import io.realm.kotlin.mongodb.exceptions.CredentialsCannotBeLinkedException import io.realm.kotlin.mongodb.exceptions.ServiceException +import io.realm.kotlin.mongodb.mongo.MongoClient import kotlinx.coroutines.channels.Channel +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import org.mongodb.kbson.serialization.EJson // TODO Public due to being a transitive dependency to SyncConfigurationImpl public class UserImpl( @@ -176,6 +179,12 @@ public class UserImpl( } } + @ExperimentalKBsonSerializerApi + override fun mongoClient(serviceName: String, eJson: EJson?): MongoClient { + if (!loggedIn) throw IllegalStateException("Cannot obtain a MongoClient from a logged out user") + return MongoClientImpl(this, serviceName, eJson ?: app.configuration.ejson) + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || this::class != other::class) return false diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/mongo/MongoClient.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/mongo/MongoClient.kt new file mode 100644 index 0000000000..b54d11b151 --- /dev/null +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/mongo/MongoClient.kt @@ -0,0 +1,118 @@ +/* + * Copyright 2023 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.mongodb.mongo + +import io.realm.kotlin.internal.RealmObjectCompanion +import io.realm.kotlin.mongodb.internal.MongoDBSerializer +import io.realm.kotlin.types.BaseRealmObject +import io.realm.kotlin.types.RealmObject +import kotlinx.serialization.KSerializer +import kotlinx.serialization.modules.SerializersModule +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import org.mongodb.kbson.serialization.EJson +import kotlin.reflect.KClass + +/** + * A **Mongo client** is used to access an App Service's Data Source directly without Sync support. + * + * This API corresponds to the Atlas App Service "MongoDB API". Please consult the + * [MongoDB API Reference](https://www.mongodb.com/docs/atlas/app-services/functions/mongodb/api/) + * for a detailed description of methods and arguments. + * + * Serialization to and from EJSON is performed with [KBSON](https://github.com/mongodb/kbson) + * that supports the [Kotlin Serialization framework](https://github.com/Kotlin/kotlinx.serialization) + * and handles serialization to and from classes marked with [Serializable]. Serialization can be + * customized by customizing the [EJson]-serializer passed to the various [MongoClient], + * [MongoDatabase] and [MongoCollection]-factory methods. + * + * Object references (links) are serialized solely by their primary keys, so to serialize the + * MongoDB API requests and responses to and from realm objects ([RealmObject], + * [EmbeddedRealmObject] and [AsymmetricRealmObject]) the serialization framework must be + * configured with special serializers for those. This can be done with + * ``` + * val user = app.currentUser + * val client = user.mongoClient( + * "serviceName", + * EJson( + * serializersModule = realmSerializerModule( + * setOf( + * MongoDBCollectionDataType1::class, + * MongoDBCollectionDataType2::class + * ) + * ) + * ) + * ``` + * + * *NOTE* Since the MongoDB API responses only includes primary key information for links, + * serialization of responses into realm objects ([RealmObject], [EmbeddedRealmObject] and + * [AsymmetricRealmObject]) will create instances of the target objects with only the primary key + * property set. All other properties from the realm objects will have the default values specified + * in the class definition. + * + * *NOTE* The EJSON serializer requires to opt-in to the experimental [ExperimentalKBsonSerializerApi]. + */ +public interface MongoClient { + + /** + * The name of the data source that the [MongoClient] is connecting to. + */ + public val serviceName: String + + /** + * Get a [MongoDatabase] object to access data from the remote collections of the data source. + * + * Serialization to and from EJSON is performed with [KBSON](https://github.com/mongodb/kbson) + * and requires to opt-in to the experimental [ExperimentalKBsonSerializerApi]-feature. + * + * @param databaseName name of the database from the data source. + * @param eJson the EJson serializer that the [MongoDatabase] should use to convert objects and + * primary keys with. Will default to the client's [EJson] instance. For details on + * configuration of serialization see + * [MongoClient]. + */ + @ExperimentalKBsonSerializerApi + public fun database(databaseName: String, eJson: EJson? = null): MongoDatabase +} + +/** + * Creates [SerializersModule] with MongoDB API compliant serializers for all the realm objects + * ([RealmObject], [EmbeddedRealmObject] and [AsymmetricRealmObject]) in the given [schema]. + * + * The target types of links in mixed fields cannot be derived from the schema definition of the + * realm objects. To be able to deserialize and create the correct instance of links in mixed + * fields, all serializers needs to know of the full set of realm objects. This means that the + * serializer module must be constructed with knowledge of all references classes in the schema. + */ +public fun realmSerializerModule(schema: Set>): SerializersModule { + val companions: Map = + schema.associate { kClass -> + @Suppress("invisible_reference", "invisible_member") + io.realm.kotlin.internal.platform.realmObjectCompanionOrThrow(kClass).let { + it.io_realm_kotlin_className to it + } + } + val serializers: List, KSerializer<*>>> = schema.map { + it to MongoDBSerializer(it, companions) + } + + return SerializersModule { + serializers.forEach { + @Suppress("UNCHECKED_CAST") + contextual(it.first as KClass, it.second as KSerializer) + } + } +} diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/mongo/MongoCollection.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/mongo/MongoCollection.kt new file mode 100644 index 0000000000..da07302a66 --- /dev/null +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/mongo/MongoCollection.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2023 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.mongodb.mongo + +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import org.mongodb.kbson.serialization.EJson + +/** + * A __mongo collection__ provides access to retrieve and update data from the database's + * collection with specific typed serialization. + * + * This API corresponds to the Atlas App Service "MongoDB API". Please consult the + * [MongoDB API Reference](https://www.mongodb.com/docs/atlas/app-services/functions/mongodb/api/) + * for a detailed description of methods and arguments. + * + * Input arguments and responses to the App Service HTTP requests will be serialized from and to + * the type [T] using [Kotlin's Serialization framework](https://kotlinlang.org/docs/serialization.html) + * and can be customized by [Serializable]-annotations or customizing the [EJson]-serializer passed + * to the various [MongoClient], [MongoDatabase] and [MongoCollection]-factory methods. For details + * on configuring the serialization see [MongoClient]. + * + * All operations on a [MongoCollection] will throw an: + * - [ServiceException] if the underlying App Service HTTP requests fails + * - [SerializationException] if input arguments cannot be serialized to a valid EJson document + * or if the App Service response could not be deserialized to the return types. + * + * @param T the default type that remote entities of the collection will be serialized from and + * to. + */ +public interface MongoCollection { + + /** + * Name of the remote collection. + */ + public val name: String + + /** + * Get an instance of the same collection with a different set of default types serialization. + * + * @param eJson the EJson serializer that the [MongoCollection] should use to convert objects and + * primary keys with. Will default to the databases [EJson] instance. For details on + * configuration of serialization see [MongoClient]. + */ + @ExperimentalKBsonSerializerApi + public fun withDocumentClass(eJson: EJson? = null): MongoCollection +} diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/mongo/MongoDatabase.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/mongo/MongoDatabase.kt new file mode 100644 index 0000000000..f9dc739cde --- /dev/null +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/mongo/MongoDatabase.kt @@ -0,0 +1,66 @@ +/* + * Copyright 2023 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.mongodb.mongo + +import org.mongodb.kbson.BsonDocument +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import org.mongodb.kbson.serialization.EJson + +/** + * A handle to a remote **Atlas App Service database** that provides access to its [MongoCollection]s. + */ +public interface MongoDatabase { + + /** + * Name of the remote database. + */ + public val name: String + + /** + * Get a [MongoCollection] that exposed methods to retrieve and update data from the database's + * collection. + * + * Serialization to and from EJSON is performed with [KBSON](https://github.com/mongodb/kbson) + * and requires to opt-in to the experimental [ExperimentalKBsonSerializerApi]-feature. + * + * @param collectionName the name of the collection name that the [MongoCollection] will + * connect to. + * @return a [MongoCollection] that will accept and return entities from the remote collection + * as [BsonDocument] values. + */ + public fun collection(collectionName: String): MongoCollection + + /** + * Get a [MongoCollection] that exposed methods to retrieve and update data from the database's + * collection with specific typed serialization. + * + * Serialization to and from EJSON is performed with [KBSON](https://github.com/mongodb/kbson) + * and requires to opt-in to the experimental [ExperimentalKBsonSerializerApi]-feature. + * + * @param collectionName the name of the collection name that the [MongoCollection] will + * connect to. + * @param eJson the EJson serializer that the [MongoCollection] should use to convert objects and + * primary keys with. Will default to the databases [EJson] instance. For details on + * configuration of serialization see [MongoClient]. + * @param T the default type that remote entities of the collection will be serialized from and + * to. + * @return a [MongoCollection] that will accept and return entities from the remote collection + * as [T] values. + */ + @ExperimentalKBsonSerializerApi + public fun collection(collectionName: String, eJson: EJson? = null): MongoCollection +} diff --git a/packages/plugin-compiler/src/main/kotlin/io/realm/kotlin/compiler/RealmModelSyntheticPropertiesGeneration.kt b/packages/plugin-compiler/src/main/kotlin/io/realm/kotlin/compiler/RealmModelSyntheticPropertiesGeneration.kt index 1f6948ef1e..b689042620 100644 --- a/packages/plugin-compiler/src/main/kotlin/io/realm/kotlin/compiler/RealmModelSyntheticPropertiesGeneration.kt +++ b/packages/plugin-compiler/src/main/kotlin/io/realm/kotlin/compiler/RealmModelSyntheticPropertiesGeneration.kt @@ -90,12 +90,16 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetEnumValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrPropertyReferenceImpl import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl +import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classFqName +import org.jetbrains.kotlin.ir.types.classOrNull +import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.types.isNullable import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.ir.types.starProjectedType +import org.jetbrains.kotlin.ir.types.typeOrNull import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.util.companionObject import org.jetbrains.kotlin.ir.util.constructors @@ -165,6 +169,11 @@ class RealmModelSyntheticPropertiesGeneration(private val pluginContext: IrPlugi realmObjectInterface.defaultType, pluginContext.irBuiltIns.anyNType.makeNullable() ) + // Pair, KMutableProperty1> + private val fieldTypeAndProperty = pairClass.typeWith( + pluginContext.irBuiltIns.kClassClass.starProjectedType, + realmObjectMutablePropertyType + ) private val mapOf = pluginContext.referenceFunctions(KOTLIN_COLLECTIONS_MAPOF) .first { val parameters = it.owner.valueParameters @@ -172,16 +181,11 @@ class RealmModelSyntheticPropertiesGeneration(private val pluginContext: IrPlugi } private val companionFieldsType = mapClass.typeWith( pluginContext.irBuiltIns.stringType, - realmObjectMutablePropertyType - ) - @Suppress("UnusedPrivateMember") - private val companionComputedFieldsType = mapClass.typeWith( - pluginContext.irBuiltIns.stringType, - realmObjectPropertyType + fieldTypeAndProperty, ) private val companionFieldsElementType = pairClass.typeWith( pluginContext.irBuiltIns.stringType, - realmObjectMutablePropertyType + fieldTypeAndProperty ) val realmClassImpl = pluginContext.lookupClassOrThrow(ClassIds.REALM_CLASS_IMPL) @@ -246,7 +250,7 @@ class RealmModelSyntheticPropertiesGeneration(private val pluginContext: IrPlugi * - `public fun `io_realm_kotlin_schema`(): RealmClassImpl` is added by calling [addSchemaMethodBody]. * - `public fun `io_realm_kotlin_newInstance`(): Any` is added by calling [addNewInstanceMethodBody]. */ - @Suppress("LongMethod") + @Suppress("LongMethod", "ComplexMethod") fun addCompanionFields( clazz: IrClass, companion: IrClass, @@ -284,7 +288,7 @@ class RealmModelSyntheticPropertiesGeneration(private val pluginContext: IrPlugi IrConstImpl.string(startOffset, endOffset, pluginContext.irBuiltIns.stringType, className) } - // Add `public val `io_realm_kotlin_fields`: Map>` property. + // Add `public val `io_realm_kotlin_fields`: Map, KProperty1>>` property. companion.addValueProperty( pluginContext, realmObjectCompanionInterface, @@ -301,7 +305,7 @@ class RealmModelSyntheticPropertiesGeneration(private val pluginContext: IrPlugi superQualifierSymbol = null ).apply { putTypeArgument(index = 0, type = pluginContext.irBuiltIns.stringType) - putTypeArgument(index = 1, type = realmObjectPropertyType) + putTypeArgument(index = 1, type = fieldTypeAndProperty) putValueArgument( index = 0, valueArgument = IrVarargImpl( @@ -309,20 +313,35 @@ class RealmModelSyntheticPropertiesGeneration(private val pluginContext: IrPlugi UNDEFINED_OFFSET, pluginContext.irBuiltIns.arrayClass.typeWith(companionFieldsElementType), type, - // Generate list of properties: List>> + // Generate list of properties: List, KMutableProperty1<*, *>>>> properties!!.entries.map { val property = it.value.declaration - val propertyType = if (it.value.isComputed) realmObjectPropertyType else + val targetType: IrType = property.backingField!!.type + val propertyElementType: IrType = when (it.value.collectionType) { + CollectionType.NONE -> targetType + CollectionType.LIST -> (targetType as IrSimpleType).arguments[0].typeOrNull!! + CollectionType.SET -> (targetType as IrSimpleType).arguments[0].typeOrNull!! + CollectionType.DICTIONARY -> (targetType as IrSimpleType).arguments[0].typeOrNull!! + } + val elementKClassRef = IrClassReferenceImpl( + startOffset = startOffset, + endOffset = endOffset, + type = pluginContext.irBuiltIns.kClassClass.typeWith(propertyElementType), + symbol = propertyElementType.classOrNull!!, + classType = propertyElementType.classOrNull!!.defaultType, + ) + val objectPropertyType = if (it.value.isComputed) realmObjectPropertyType else realmObjectMutablePropertyType - // Pair>() + val elementType = pairClass.typeWith(pluginContext.irBuiltIns.kClassClass.typeWith(), objectPropertyType) + // Pair>>() IrConstructorCallImpl.fromSymbolOwner( startOffset = startOffset, endOffset = endOffset, - type = companionFieldsElementType, + type = elementType, constructorSymbol = pairCtor ).apply { putTypeArgument(0, pluginContext.irBuiltIns.stringType) - putTypeArgument(1, propertyType) + putTypeArgument(1, elementType) putValueArgument( 0, IrConstImpl.string( @@ -334,16 +353,35 @@ class RealmModelSyntheticPropertiesGeneration(private val pluginContext: IrPlugi ) putValueArgument( 1, - IrPropertyReferenceImpl( + IrConstructorCallImpl.fromSymbolOwner( startOffset = startOffset, endOffset = endOffset, - type = kPropertyType, - symbol = property.symbol, - typeArgumentsCount = 0, - field = null, - getter = property.getter?.symbol, - setter = property.setter?.symbol - ) + type = elementType, + constructorSymbol = pairCtor + ).apply { + putTypeArgument( + 0, + pluginContext.irBuiltIns.kClassClass.starProjectedType + ) + putTypeArgument(1, objectPropertyType) + putValueArgument( + 0, + elementKClassRef + ) + putValueArgument( + 1, + IrPropertyReferenceImpl( + startOffset = startOffset, + endOffset = endOffset, + type = kPropertyType, + symbol = property.symbol, + typeArgumentsCount = 0, + field = null, + getter = property.getter?.symbol, + setter = property.setter?.symbol + ) + ) + } ) } } diff --git a/packages/plugin-compiler/src/main/kotlin/io/realm/kotlin/compiler/SyncLoweringExtension.kt b/packages/plugin-compiler/src/main/kotlin/io/realm/kotlin/compiler/SyncLoweringExtension.kt index db92d791b4..28d3443ea7 100644 --- a/packages/plugin-compiler/src/main/kotlin/io/realm/kotlin/compiler/SyncLoweringExtension.kt +++ b/packages/plugin-compiler/src/main/kotlin/io/realm/kotlin/compiler/SyncLoweringExtension.kt @@ -104,10 +104,10 @@ private class SyncLowering(private val pluginContext: IrPluginContext, private v appCreateAppId.symbol to ( appCreateAppIdBundleId to { expression: IrCall -> IrGetObjectValueImpl( - expression.startOffset, - expression.endOffset, - IrSimpleTypeImpl(appImplCompanionSymbol, false, emptyList(), emptyList()), - appImplCompanionSymbol + startOffset = expression.startOffset, + endOffset = expression.endOffset, + type = IrSimpleTypeImpl(appImplCompanionSymbol, false, emptyList(), emptyList()), + symbol = appImplCompanionSymbol ) } ), diff --git a/packages/plugin-compiler/src/test/resources/sample/expected/01_AFTER.ValidateIrBeforeLowering.ir b/packages/plugin-compiler/src/test/resources/sample/expected/01_AFTER.ValidateIrBeforeLowering.ir index 53764b38bc..b271c40cba 100644 --- a/packages/plugin-compiler/src/test/resources/sample/expected/01_AFTER.ValidateIrBeforeLowering.ir +++ b/packages/plugin-compiler/src/test/resources/sample/expected/01_AFTER.ValidateIrBeforeLowering.ir @@ -1,6 +1,6 @@ // --- IR for
after Validate IR before lowering MODULE_FRAGMENT name:
- FILE fqName:sample.input fileName:/Users/claus.rorbech/proj/realm-kotlin-work/packages/plugin-compiler/build/resources/test/sample/input/Sample.kt + FILE fqName:sample.input fileName:input/Sample.kt CLASS CLASS name:Sample modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.RealmObject; io.realm.kotlin.internal.RealmObjectInternal] $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:sample.input.Sample CONSTRUCTOR visibility:public <> () returnType:sample.input.Sample [primary] @@ -7293,600 +7293,1064 @@ MODULE_FRAGMENT name:
GET_FIELD 'FIELD name:io_realm_kotlin_className type:kotlin.String visibility:private' type=kotlin.String origin=null receiver: GET_VAR ': sample.input.Sample.Companion declared in sample.input.Sample.Companion.' type=sample.input.Sample.Companion origin=null PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] - FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private + FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private EXPRESSION_BODY - CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map> origin=null + CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null : kotlin.String - : kotlin.reflect.KProperty1 - pairs: VARARG type=kotlin.Array>> varargElementType=kotlin.collections.Map> - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.Pair, kotlin.reflect.KMutableProperty1> + pairs: VARARG type=kotlin.Array, kotlin.reflect.KMutableProperty1>>> varargElementType=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="id" - second: PROPERTY_REFERENCE 'public final id: kotlin.Long [var]' field=null getter='public final fun (): kotlin.Long declared in sample.input.Sample' setter='public final fun (: kotlin.Long): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Long modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final id: kotlin.Long [var]' field=null getter='public final fun (): kotlin.Long declared in sample.input.Sample' setter='public final fun (: kotlin.Long): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="stringField" - second: PROPERTY_REFERENCE 'public final stringField: kotlin.String? [var]' field=null getter='public final fun (): kotlin.String? declared in sample.input.Sample' setter='public final fun (: kotlin.String?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:String modality:FINAL visibility:public superTypes:[kotlin.Comparable; kotlin.CharSequence; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final stringField: kotlin.String? [var]' field=null getter='public final fun (): kotlin.String? declared in sample.input.Sample' setter='public final fun (: kotlin.String?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="byteField" - second: PROPERTY_REFERENCE 'public final byteField: kotlin.Byte? [var]' field=null getter='public final fun (): kotlin.Byte? declared in sample.input.Sample' setter='public final fun (: kotlin.Byte?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Byte modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final byteField: kotlin.Byte? [var]' field=null getter='public final fun (): kotlin.Byte? declared in sample.input.Sample' setter='public final fun (: kotlin.Byte?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="charField" - second: PROPERTY_REFERENCE 'public final charField: kotlin.Char? [var]' field=null getter='public final fun (): kotlin.Char? declared in sample.input.Sample' setter='public final fun (: kotlin.Char?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Char modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final charField: kotlin.Char? [var]' field=null getter='public final fun (): kotlin.Char? declared in sample.input.Sample' setter='public final fun (: kotlin.Char?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="shortField" - second: PROPERTY_REFERENCE 'public final shortField: kotlin.Short? [var]' field=null getter='public final fun (): kotlin.Short? declared in sample.input.Sample' setter='public final fun (: kotlin.Short?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Short modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final shortField: kotlin.Short? [var]' field=null getter='public final fun (): kotlin.Short? declared in sample.input.Sample' setter='public final fun (: kotlin.Short?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="intField" - second: PROPERTY_REFERENCE 'public final intField: kotlin.Int? [var]' field=null getter='public final fun (): kotlin.Int? declared in sample.input.Sample' setter='public final fun (: kotlin.Int?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Int modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final intField: kotlin.Int? [var]' field=null getter='public final fun (): kotlin.Int? declared in sample.input.Sample' setter='public final fun (: kotlin.Int?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="longField" - second: PROPERTY_REFERENCE 'public final longField: kotlin.Long? [var]' field=null getter='public final fun (): kotlin.Long? declared in sample.input.Sample' setter='public final fun (: kotlin.Long?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Long modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final longField: kotlin.Long? [var]' field=null getter='public final fun (): kotlin.Long? declared in sample.input.Sample' setter='public final fun (: kotlin.Long?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="booleanField" - second: PROPERTY_REFERENCE 'public final booleanField: kotlin.Boolean? [var]' field=null getter='public final fun (): kotlin.Boolean? declared in sample.input.Sample' setter='public final fun (: kotlin.Boolean?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Boolean modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final booleanField: kotlin.Boolean? [var]' field=null getter='public final fun (): kotlin.Boolean? declared in sample.input.Sample' setter='public final fun (: kotlin.Boolean?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="floatField" - second: PROPERTY_REFERENCE 'public final floatField: kotlin.Float? [var]' field=null getter='public final fun (): kotlin.Float? declared in sample.input.Sample' setter='public final fun (: kotlin.Float?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Float modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final floatField: kotlin.Float? [var]' field=null getter='public final fun (): kotlin.Float? declared in sample.input.Sample' setter='public final fun (: kotlin.Float?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="doubleField" - second: PROPERTY_REFERENCE 'public final doubleField: kotlin.Double? [var]' field=null getter='public final fun (): kotlin.Double? declared in sample.input.Sample' setter='public final fun (: kotlin.Double?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Double modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final doubleField: kotlin.Double? [var]' field=null getter='public final fun (): kotlin.Double? declared in sample.input.Sample' setter='public final fun (: kotlin.Double?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="decimal128Field" - second: PROPERTY_REFERENCE 'public final decimal128Field: org.mongodb.kbson.BsonDecimal128?{ org.mongodb.kbson.Decimal128Kt.Decimal128? } [var]' field=null getter='public final fun (): org.mongodb.kbson.BsonDecimal128?{ org.mongodb.kbson.Decimal128Kt.Decimal128? } declared in sample.input.Sample' setter='public final fun (: org.mongodb.kbson.BsonDecimal128?{ org.mongodb.kbson.Decimal128Kt.Decimal128? }): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonDecimal128 modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final decimal128Field: org.mongodb.kbson.BsonDecimal128?{ org.mongodb.kbson.Decimal128Kt.Decimal128? } [var]' field=null getter='public final fun (): org.mongodb.kbson.BsonDecimal128?{ org.mongodb.kbson.Decimal128Kt.Decimal128? } declared in sample.input.Sample' setter='public final fun (: org.mongodb.kbson.BsonDecimal128?{ org.mongodb.kbson.Decimal128Kt.Decimal128? }): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="timestampField" - second: PROPERTY_REFERENCE 'public final timestampField: io.realm.kotlin.types.RealmInstant? [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmInstant? declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmInstant?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmInstant modality:ABSTRACT visibility:public superTypes:[kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final timestampField: io.realm.kotlin.types.RealmInstant? [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmInstant? declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmInstant?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="bsonObjectIdField" - second: PROPERTY_REFERENCE 'public final bsonObjectIdField: org.mongodb.kbson.BsonObjectId? [var]' field=null getter='public final fun (): org.mongodb.kbson.BsonObjectId? declared in sample.input.Sample' setter='public final fun (: org.mongodb.kbson.BsonObjectId?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonObjectId modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue; kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final bsonObjectIdField: org.mongodb.kbson.BsonObjectId? [var]' field=null getter='public final fun (): org.mongodb.kbson.BsonObjectId? declared in sample.input.Sample' setter='public final fun (: org.mongodb.kbson.BsonObjectId?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="uuidField" - second: PROPERTY_REFERENCE 'public final uuidField: io.realm.kotlin.types.RealmUUID? [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmUUID? declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmUUID?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmUUID modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final uuidField: io.realm.kotlin.types.RealmUUID? [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmUUID? declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmUUID?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="byteArrayField" - second: PROPERTY_REFERENCE 'public final byteArrayField: kotlin.ByteArray? [var]' field=null getter='public final fun (): kotlin.ByteArray? declared in sample.input.Sample' setter='public final fun (: kotlin.ByteArray?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:ByteArray modality:FINAL visibility:public superTypes:[kotlin.Any; kotlin.Cloneable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final byteArrayField: kotlin.ByteArray? [var]' field=null getter='public final fun (): kotlin.ByteArray? declared in sample.input.Sample' setter='public final fun (: kotlin.ByteArray?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="mutableRealmInt" - second: PROPERTY_REFERENCE 'public final mutableRealmInt: io.realm.kotlin.types.MutableRealmInt? [var]' field=null getter='public final fun (): io.realm.kotlin.types.MutableRealmInt? declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.MutableRealmInt?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:MutableRealmInt modality:ABSTRACT visibility:public superTypes:[kotlin.Comparable; kotlin.Number]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final mutableRealmInt: io.realm.kotlin.types.MutableRealmInt? [var]' field=null getter='public final fun (): io.realm.kotlin.types.MutableRealmInt? declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.MutableRealmInt?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="child" - second: PROPERTY_REFERENCE 'public final child: sample.input.Child? [var]' field=null getter='public final fun (): sample.input.Child? declared in sample.input.Sample' setter='public final fun (: sample.input.Child?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:Child modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.RealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final child: sample.input.Child? [var]' field=null getter='public final fun (): sample.input.Child? declared in sample.input.Sample' setter='public final fun (: sample.input.Child?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableRealmAny" - second: PROPERTY_REFERENCE 'public final nullableRealmAny: io.realm.kotlin.types.RealmAny? [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmAny? declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmAny?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmAny modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableRealmAny: io.realm.kotlin.types.RealmAny? [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmAny? declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmAny?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="stringListField" - second: PROPERTY_REFERENCE 'public final stringListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:String modality:FINAL visibility:public superTypes:[kotlin.Comparable; kotlin.CharSequence; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final stringListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="byteListField" - second: PROPERTY_REFERENCE 'public final byteListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Byte modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final byteListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="charListField" - second: PROPERTY_REFERENCE 'public final charListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Char modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final charListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="shortListField" - second: PROPERTY_REFERENCE 'public final shortListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Short modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final shortListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="intListField" - second: PROPERTY_REFERENCE 'public final intListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Int modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final intListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="longListField" - second: PROPERTY_REFERENCE 'public final longListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Long modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final longListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="booleanListField" - second: PROPERTY_REFERENCE 'public final booleanListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Boolean modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final booleanListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="floatListField" - second: PROPERTY_REFERENCE 'public final floatListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Float modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final floatListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="doubleListField" - second: PROPERTY_REFERENCE 'public final doubleListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Double modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final doubleListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="timestampListField" - second: PROPERTY_REFERENCE 'public final timestampListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmInstant modality:ABSTRACT visibility:public superTypes:[kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final timestampListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="bsonObjectIdListField" - second: PROPERTY_REFERENCE 'public final bsonObjectIdListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonObjectId modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue; kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final bsonObjectIdListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="uuidListField" - second: PROPERTY_REFERENCE 'public final uuidListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmUUID modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final uuidListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="binaryListField" - second: PROPERTY_REFERENCE 'public final binaryListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:ByteArray modality:FINAL visibility:public superTypes:[kotlin.Any; kotlin.Cloneable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final binaryListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="decimal128ListField" - second: PROPERTY_REFERENCE 'public final decimal128ListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonDecimal128 modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final decimal128ListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="objectListField" - second: PROPERTY_REFERENCE 'public final objectListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:Sample modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.RealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final objectListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="embeddedRealmObjectListField" - second: PROPERTY_REFERENCE 'public final embeddedRealmObjectListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:EmbeddedChild modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.EmbeddedRealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final embeddedRealmObjectListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableStringListField" - second: PROPERTY_REFERENCE 'public final nullableStringListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:String modality:FINAL visibility:public superTypes:[kotlin.Comparable; kotlin.CharSequence; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableStringListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableByteListField" - second: PROPERTY_REFERENCE 'public final nullableByteListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Byte modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableByteListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableCharListField" - second: PROPERTY_REFERENCE 'public final nullableCharListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Char modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableCharListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableShortListField" - second: PROPERTY_REFERENCE 'public final nullableShortListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Short modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableShortListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableIntListField" - second: PROPERTY_REFERENCE 'public final nullableIntListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Int modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableIntListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableLongListField" - second: PROPERTY_REFERENCE 'public final nullableLongListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Long modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableLongListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableBooleanListField" - second: PROPERTY_REFERENCE 'public final nullableBooleanListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Boolean modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableBooleanListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableFloatListField" - second: PROPERTY_REFERENCE 'public final nullableFloatListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Float modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableFloatListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableDoubleListField" - second: PROPERTY_REFERENCE 'public final nullableDoubleListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Double modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableDoubleListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableTimestampListField" - second: PROPERTY_REFERENCE 'public final nullableTimestampListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmInstant modality:ABSTRACT visibility:public superTypes:[kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableTimestampListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableBsonObjectIdListField" - second: PROPERTY_REFERENCE 'public final nullableBsonObjectIdListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonObjectId modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue; kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableBsonObjectIdListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableUUIDListField" - second: PROPERTY_REFERENCE 'public final nullableUUIDListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmUUID modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableUUIDListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableBinaryListField" - second: PROPERTY_REFERENCE 'public final nullableBinaryListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:ByteArray modality:FINAL visibility:public superTypes:[kotlin.Any; kotlin.Cloneable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableBinaryListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableDecimal128ListField" - second: PROPERTY_REFERENCE 'public final nullableDecimal128ListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonDecimal128 modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableDecimal128ListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableRealmAnyListField" - second: PROPERTY_REFERENCE 'public final nullableRealmAnyListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmAny modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableRealmAnyListField: io.realm.kotlin.types.RealmList [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmList declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmList): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="stringSetField" - second: PROPERTY_REFERENCE 'public final stringSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:String modality:FINAL visibility:public superTypes:[kotlin.Comparable; kotlin.CharSequence; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final stringSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="byteSetField" - second: PROPERTY_REFERENCE 'public final byteSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Byte modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final byteSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="charSetField" - second: PROPERTY_REFERENCE 'public final charSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Char modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final charSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="shortSetField" - second: PROPERTY_REFERENCE 'public final shortSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Short modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final shortSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="intSetField" - second: PROPERTY_REFERENCE 'public final intSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Int modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final intSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="longSetField" - second: PROPERTY_REFERENCE 'public final longSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Long modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final longSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="booleanSetField" - second: PROPERTY_REFERENCE 'public final booleanSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Boolean modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final booleanSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="floatSetField" - second: PROPERTY_REFERENCE 'public final floatSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Float modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final floatSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="doubleSetField" - second: PROPERTY_REFERENCE 'public final doubleSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Double modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final doubleSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="timestampSetField" - second: PROPERTY_REFERENCE 'public final timestampSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmInstant modality:ABSTRACT visibility:public superTypes:[kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final timestampSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="bsonObjectIdSetField" - second: PROPERTY_REFERENCE 'public final bsonObjectIdSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonObjectId modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue; kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final bsonObjectIdSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="uuidSetField" - second: PROPERTY_REFERENCE 'public final uuidSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmUUID modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final uuidSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="binarySetField" - second: PROPERTY_REFERENCE 'public final binarySetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:ByteArray modality:FINAL visibility:public superTypes:[kotlin.Any; kotlin.Cloneable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final binarySetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="decimal128SetField" - second: PROPERTY_REFERENCE 'public final decimal128SetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonDecimal128 modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final decimal128SetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="objectSetField" - second: PROPERTY_REFERENCE 'public final objectSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:Sample modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.RealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final objectSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableStringSetField" - second: PROPERTY_REFERENCE 'public final nullableStringSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:String modality:FINAL visibility:public superTypes:[kotlin.Comparable; kotlin.CharSequence; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableStringSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableByteSetField" - second: PROPERTY_REFERENCE 'public final nullableByteSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Byte modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableByteSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableCharSetField" - second: PROPERTY_REFERENCE 'public final nullableCharSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Char modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableCharSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableShortSetField" - second: PROPERTY_REFERENCE 'public final nullableShortSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Short modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableShortSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableIntSetField" - second: PROPERTY_REFERENCE 'public final nullableIntSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Int modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableIntSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableLongSetField" - second: PROPERTY_REFERENCE 'public final nullableLongSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Long modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableLongSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableBooleanSetField" - second: PROPERTY_REFERENCE 'public final nullableBooleanSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Boolean modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableBooleanSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableFloatSetField" - second: PROPERTY_REFERENCE 'public final nullableFloatSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Float modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableFloatSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableDoubleSetField" - second: PROPERTY_REFERENCE 'public final nullableDoubleSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Double modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableDoubleSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableTimestampSetField" - second: PROPERTY_REFERENCE 'public final nullableTimestampSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmInstant modality:ABSTRACT visibility:public superTypes:[kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableTimestampSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableBsonObjectIdSetField" - second: PROPERTY_REFERENCE 'public final nullableBsonObjectIdSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonObjectId modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue; kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableBsonObjectIdSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableUUIDSetField" - second: PROPERTY_REFERENCE 'public final nullableUUIDSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmUUID modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableUUIDSetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableBinarySetField" - second: PROPERTY_REFERENCE 'public final nullableBinarySetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:ByteArray modality:FINAL visibility:public superTypes:[kotlin.Any; kotlin.Cloneable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableBinarySetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableDecimal128SetField" - second: PROPERTY_REFERENCE 'public final nullableDecimal128SetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonDecimal128 modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableDecimal128SetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableRealmAnySetField" - second: PROPERTY_REFERENCE 'public final nullableRealmAnySetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmAny modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableRealmAnySetField: io.realm.kotlin.types.RealmSet [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmSet declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmSet): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="stringDictionaryField" - second: PROPERTY_REFERENCE 'public final stringDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:String modality:FINAL visibility:public superTypes:[kotlin.Comparable; kotlin.CharSequence; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final stringDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="byteDictionaryField" - second: PROPERTY_REFERENCE 'public final byteDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Byte modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final byteDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="charDictionaryField" - second: PROPERTY_REFERENCE 'public final charDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Char modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final charDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="shortDictionaryField" - second: PROPERTY_REFERENCE 'public final shortDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Short modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final shortDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="intDictionaryField" - second: PROPERTY_REFERENCE 'public final intDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Int modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final intDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="longDictionaryField" - second: PROPERTY_REFERENCE 'public final longDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Long modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final longDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="booleanDictionaryField" - second: PROPERTY_REFERENCE 'public final booleanDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Boolean modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final booleanDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="floatDictionaryField" - second: PROPERTY_REFERENCE 'public final floatDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Float modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final floatDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="doubleDictionaryField" - second: PROPERTY_REFERENCE 'public final doubleDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Double modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final doubleDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="timestampDictionaryField" - second: PROPERTY_REFERENCE 'public final timestampDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmInstant modality:ABSTRACT visibility:public superTypes:[kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final timestampDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="bsonObjectIdDictionaryField" - second: PROPERTY_REFERENCE 'public final bsonObjectIdDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonObjectId modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue; kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final bsonObjectIdDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="uuidDictionaryField" - second: PROPERTY_REFERENCE 'public final uuidDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmUUID modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final uuidDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="binaryDictionaryField" - second: PROPERTY_REFERENCE 'public final binaryDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:ByteArray modality:FINAL visibility:public superTypes:[kotlin.Any; kotlin.Cloneable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final binaryDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="decimal128DictionaryField" - second: PROPERTY_REFERENCE 'public final decimal128DictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonDecimal128 modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final decimal128DictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableStringDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableStringDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:String modality:FINAL visibility:public superTypes:[kotlin.Comparable; kotlin.CharSequence; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableStringDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableByteDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableByteDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Byte modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableByteDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableCharDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableCharDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Char modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableCharDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableShortDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableShortDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Short modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableShortDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableIntDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableIntDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Int modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableIntDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableLongDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableLongDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Long modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableLongDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableBooleanDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableBooleanDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Boolean modality:FINAL visibility:public superTypes:[kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableBooleanDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableFloatDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableFloatDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Float modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableFloatDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableDoubleDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableDoubleDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Double modality:FINAL visibility:public superTypes:[kotlin.Number; kotlin.Comparable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableDoubleDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableTimestampDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableTimestampDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmInstant modality:ABSTRACT visibility:public superTypes:[kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableTimestampDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableBsonObjectIdDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableBsonObjectIdDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonObjectId modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue; kotlin.Comparable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableBsonObjectIdDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableUUIDDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableUUIDDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmUUID modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableUUIDDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableBinaryDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableBinaryDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:ByteArray modality:FINAL visibility:public superTypes:[kotlin.Any; kotlin.Cloneable; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableBinaryDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableDecimal128DictionaryField" - second: PROPERTY_REFERENCE 'public final nullableDecimal128DictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:BsonDecimal128 modality:FINAL visibility:public superTypes:[org.mongodb.kbson.BsonValue]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableDecimal128DictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableRealmAnyDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableRealmAnyDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:RealmAny modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableRealmAnyDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableObjectDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableObjectDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:Sample modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.RealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableObjectDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="nullableEmbeddedObjectDictionaryField" - second: PROPERTY_REFERENCE 'public final nullableEmbeddedObjectDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:EmbeddedChild modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.EmbeddedRealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final nullableEmbeddedObjectDictionaryField: io.realm.kotlin.types.RealmDictionary [var]' field=null getter='public final fun (): io.realm.kotlin.types.RealmDictionary declared in sample.input.Sample' setter='public final fun (: io.realm.kotlin.types.RealmDictionary): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="linkingObjectsByList" - second: PROPERTY_REFERENCE 'public final linkingObjectsByList: io.realm.kotlin.query.RealmResults [delegated,val]' field=null getter='public final fun (): io.realm.kotlin.query.RealmResults declared in sample.input.Sample' setter=null type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:Sample modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.RealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final linkingObjectsByList: io.realm.kotlin.query.RealmResults [delegated,val]' field=null getter='public final fun (): io.realm.kotlin.query.RealmResults declared in sample.input.Sample' setter=null type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="linkingObjectsBySet" - second: PROPERTY_REFERENCE 'public final linkingObjectsBySet: io.realm.kotlin.query.RealmResults [delegated,val]' field=null getter='public final fun (): io.realm.kotlin.query.RealmResults declared in sample.input.Sample' setter=null type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:Sample modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.RealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final linkingObjectsBySet: io.realm.kotlin.query.RealmResults [delegated,val]' field=null getter='public final fun (): io.realm.kotlin.query.RealmResults declared in sample.input.Sample' setter=null type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="linkingObjectsByDictionary" - second: PROPERTY_REFERENCE 'public final linkingObjectsByDictionary: io.realm.kotlin.query.RealmResults [delegated,val]' field=null getter='public final fun (): io.realm.kotlin.query.RealmResults declared in sample.input.Sample' setter=null type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:Sample modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.RealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final linkingObjectsByDictionary: io.realm.kotlin.query.RealmResults [delegated,val]' field=null getter='public final fun (): io.realm.kotlin.query.RealmResults declared in sample.input.Sample' setter=null type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="persistedNameStringField" - second: PROPERTY_REFERENCE 'public final publicNameStringField: kotlin.String? [var]' field=null getter='public final fun (): kotlin.String? declared in sample.input.Sample' setter='public final fun (: kotlin.String?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:String modality:FINAL visibility:public superTypes:[kotlin.Comparable; kotlin.CharSequence; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final publicNameStringField: kotlin.String? [var]' field=null getter='public final fun (): kotlin.String? declared in sample.input.Sample' setter='public final fun (: kotlin.String?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="persistedNameChildField" - second: PROPERTY_REFERENCE 'public final publicNameChildField: sample.input.Child? [var]' field=null getter='public final fun (): sample.input.Child? declared in sample.input.Sample' setter='public final fun (: sample.input.Child?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:Child modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.RealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final publicNameChildField: sample.input.Child? [var]' field=null getter='public final fun (): sample.input.Child? declared in sample.input.Sample' setter='public final fun (: sample.input.Child?): kotlin.Unit declared in sample.input.Sample' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="persistedNameLinkingObjectsField" - second: PROPERTY_REFERENCE 'public final publicNameLinkingObjectsField: io.realm.kotlin.query.RealmResults [delegated,val]' field=null getter='public final fun (): io.realm.kotlin.query.RealmResults declared in sample.input.Sample' setter=null type=kotlin.reflect.KMutableProperty1 origin=null - FUN name: visibility:public modality:FINAL <> ($this:sample.input.Sample.Companion) returnType:kotlin.collections.Map> + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:Sample modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.RealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final publicNameLinkingObjectsField: io.realm.kotlin.query.RealmResults [delegated,val]' field=null getter='public final fun (): io.realm.kotlin.query.RealmResults declared in sample.input.Sample' setter=null type=kotlin.reflect.KMutableProperty1 origin=null + FUN name: visibility:public modality:FINAL <> ($this:sample.input.Sample.Companion) returnType:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> correspondingProperty: PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] overridden: - public abstract fun (): kotlin.collections.Map> declared in io.realm.kotlin.internal.RealmObjectCompanion + public abstract fun (): kotlin.collections.Map, kotlin.reflect.KProperty1>> declared in io.realm.kotlin.internal.RealmObjectCompanion $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:sample.input.Sample.Companion BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map> declared in sample.input.Sample.Companion' - GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private' type=kotlin.collections.Map> origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> declared in sample.input.Sample.Companion' + GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null receiver: GET_VAR ': sample.input.Sample.Companion declared in sample.input.Sample.Companion.' type=sample.input.Sample.Companion origin=null PROPERTY name:io_realm_kotlin_primaryKey visibility:public modality:FINAL [var] FIELD name:io_realm_kotlin_primaryKey type:kotlin.reflect.KMutableProperty1 visibility:private @@ -8160,35 +8624,47 @@ MODULE_FRAGMENT name:
GET_FIELD 'FIELD name:io_realm_kotlin_className type:kotlin.String visibility:private' type=kotlin.String origin=null receiver: GET_VAR ': sample.input.Child.Companion declared in sample.input.Child.Companion.' type=sample.input.Child.Companion origin=null PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] - FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private + FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private EXPRESSION_BODY - CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map> origin=null + CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null : kotlin.String - : kotlin.reflect.KProperty1 - pairs: VARARG type=kotlin.Array>> varargElementType=kotlin.collections.Map> - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.Pair, kotlin.reflect.KMutableProperty1> + pairs: VARARG type=kotlin.Array, kotlin.reflect.KMutableProperty1>>> varargElementType=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="name" - second: PROPERTY_REFERENCE 'public final name: kotlin.String? [var]' field=null getter='public final fun (): kotlin.String? declared in sample.input.Child' setter='public final fun (: kotlin.String?): kotlin.Unit declared in sample.input.Child' type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:String modality:FINAL visibility:public superTypes:[kotlin.Comparable; kotlin.CharSequence; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final name: kotlin.String? [var]' field=null getter='public final fun (): kotlin.String? declared in sample.input.Child' setter='public final fun (: kotlin.String?): kotlin.Unit declared in sample.input.Child' type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="linkingObjectsByObject" - second: PROPERTY_REFERENCE 'public final linkingObjectsByObject: io.realm.kotlin.query.RealmResults [delegated,val]' field=null getter='public final fun (): io.realm.kotlin.query.RealmResults declared in sample.input.Child' setter=null type=kotlin.reflect.KMutableProperty1 origin=null - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:Sample modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.RealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final linkingObjectsByObject: io.realm.kotlin.query.RealmResults [delegated,val]' field=null getter='public final fun (): io.realm.kotlin.query.RealmResults declared in sample.input.Child' setter=null type=kotlin.reflect.KMutableProperty1 origin=null + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="persistedNameParent" - second: PROPERTY_REFERENCE 'public final publicNameParent: io.realm.kotlin.query.RealmResults [delegated,val]' field=null getter='public final fun (): io.realm.kotlin.query.RealmResults declared in sample.input.Child' setter=null type=kotlin.reflect.KMutableProperty1 origin=null - FUN name: visibility:public modality:FINAL <> ($this:sample.input.Child.Companion) returnType:kotlin.collections.Map> + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:Sample modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.RealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final publicNameParent: io.realm.kotlin.query.RealmResults [delegated,val]' field=null getter='public final fun (): io.realm.kotlin.query.RealmResults declared in sample.input.Child' setter=null type=kotlin.reflect.KMutableProperty1 origin=null + FUN name: visibility:public modality:FINAL <> ($this:sample.input.Child.Companion) returnType:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> correspondingProperty: PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] overridden: - public abstract fun (): kotlin.collections.Map> declared in io.realm.kotlin.internal.RealmObjectCompanion + public abstract fun (): kotlin.collections.Map, kotlin.reflect.KProperty1>> declared in io.realm.kotlin.internal.RealmObjectCompanion $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:sample.input.Child.Companion BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map> declared in sample.input.Child.Companion' - GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private' type=kotlin.collections.Map> origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> declared in sample.input.Child.Companion' + GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null receiver: GET_VAR ': sample.input.Child.Companion declared in sample.input.Child.Companion.' type=sample.input.Child.Companion origin=null PROPERTY name:io_realm_kotlin_primaryKey visibility:public modality:FINAL [var] FIELD name:io_realm_kotlin_primaryKey type:kotlin.reflect.KMutableProperty1 visibility:private @@ -8406,25 +8882,29 @@ MODULE_FRAGMENT name:
GET_FIELD 'FIELD name:io_realm_kotlin_className type:kotlin.String visibility:private' type=kotlin.String origin=null receiver: GET_VAR ': sample.input.EmbeddedParent.Companion declared in sample.input.EmbeddedParent.Companion.' type=sample.input.EmbeddedParent.Companion origin=null PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] - FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private + FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private EXPRESSION_BODY - CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map> origin=null + CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null : kotlin.String - : kotlin.reflect.KProperty1 - pairs: VARARG type=kotlin.Array>> varargElementType=kotlin.collections.Map> - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.Pair, kotlin.reflect.KMutableProperty1> + pairs: VARARG type=kotlin.Array, kotlin.reflect.KMutableProperty1>>> varargElementType=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="child" - second: PROPERTY_REFERENCE 'public final child: sample.input.EmbeddedChild? [var]' field=null getter='public final fun (): sample.input.EmbeddedChild? declared in sample.input.EmbeddedParent' setter='public final fun (: sample.input.EmbeddedChild?): kotlin.Unit declared in sample.input.EmbeddedParent' type=kotlin.reflect.KMutableProperty1 origin=null - FUN name: visibility:public modality:FINAL <> ($this:sample.input.EmbeddedParent.Companion) returnType:kotlin.collections.Map> + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS CLASS name:EmbeddedChild modality:OPEN visibility:public superTypes:[io.realm.kotlin.types.EmbeddedRealmObject; io.realm.kotlin.internal.RealmObjectInternal]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final child: sample.input.EmbeddedChild? [var]' field=null getter='public final fun (): sample.input.EmbeddedChild? declared in sample.input.EmbeddedParent' setter='public final fun (: sample.input.EmbeddedChild?): kotlin.Unit declared in sample.input.EmbeddedParent' type=kotlin.reflect.KMutableProperty1 origin=null + FUN name: visibility:public modality:FINAL <> ($this:sample.input.EmbeddedParent.Companion) returnType:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> correspondingProperty: PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] overridden: - public abstract fun (): kotlin.collections.Map> declared in io.realm.kotlin.internal.RealmObjectCompanion + public abstract fun (): kotlin.collections.Map, kotlin.reflect.KProperty1>> declared in io.realm.kotlin.internal.RealmObjectCompanion $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:sample.input.EmbeddedParent.Companion BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map> declared in sample.input.EmbeddedParent.Companion' - GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private' type=kotlin.collections.Map> origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> declared in sample.input.EmbeddedParent.Companion' + GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null receiver: GET_VAR ': sample.input.EmbeddedParent.Companion declared in sample.input.EmbeddedParent.Companion.' type=sample.input.EmbeddedParent.Companion origin=null PROPERTY name:io_realm_kotlin_primaryKey visibility:public modality:FINAL [var] FIELD name:io_realm_kotlin_primaryKey type:kotlin.reflect.KMutableProperty1 visibility:private @@ -8640,25 +9120,29 @@ MODULE_FRAGMENT name:
GET_FIELD 'FIELD name:io_realm_kotlin_className type:kotlin.String visibility:private' type=kotlin.String origin=null receiver: GET_VAR ': sample.input.EmbeddedChild.Companion declared in sample.input.EmbeddedChild.Companion.' type=sample.input.EmbeddedChild.Companion origin=null PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] - FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private + FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private EXPRESSION_BODY - CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map> origin=null + CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null : kotlin.String - : kotlin.reflect.KProperty1 - pairs: VARARG type=kotlin.Array>> varargElementType=kotlin.collections.Map> - CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.Pair, kotlin.reflect.KMutableProperty1> + pairs: VARARG type=kotlin.Array, kotlin.reflect.KMutableProperty1>>> varargElementType=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> + CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null : kotlin.String - : kotlin.reflect.KMutableProperty1 + : kotlin.Pair> first: CONST String type=kotlin.String value="name" - second: PROPERTY_REFERENCE 'public final name: kotlin.String? [var]' field=null getter='public final fun (): kotlin.String? declared in sample.input.EmbeddedChild' setter='public final fun (: kotlin.String?): kotlin.Unit declared in sample.input.EmbeddedChild' type=kotlin.reflect.KMutableProperty1 origin=null - FUN name: visibility:public modality:FINAL <> ($this:sample.input.EmbeddedChild.Companion) returnType:kotlin.collections.Map> + second: CONSTRUCTOR_CALL 'public constructor (first: A of kotlin.Pair, second: B of kotlin.Pair) [primary] declared in kotlin.Pair' type=kotlin.Pair> origin=null + : kotlin.reflect.KClass<*> + : kotlin.reflect.KMutableProperty1 + first: CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:String modality:FINAL visibility:public superTypes:[kotlin.Comparable; kotlin.CharSequence; java.io.Serializable]' type=kotlin.reflect.KClass + second: PROPERTY_REFERENCE 'public final name: kotlin.String? [var]' field=null getter='public final fun (): kotlin.String? declared in sample.input.EmbeddedChild' setter='public final fun (: kotlin.String?): kotlin.Unit declared in sample.input.EmbeddedChild' type=kotlin.reflect.KMutableProperty1 origin=null + FUN name: visibility:public modality:FINAL <> ($this:sample.input.EmbeddedChild.Companion) returnType:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> correspondingProperty: PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] overridden: - public abstract fun (): kotlin.collections.Map> declared in io.realm.kotlin.internal.RealmObjectCompanion + public abstract fun (): kotlin.collections.Map, kotlin.reflect.KProperty1>> declared in io.realm.kotlin.internal.RealmObjectCompanion $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:sample.input.EmbeddedChild.Companion BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map> declared in sample.input.EmbeddedChild.Companion' - GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private' type=kotlin.collections.Map> origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> declared in sample.input.EmbeddedChild.Companion' + GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null receiver: GET_VAR ': sample.input.EmbeddedChild.Companion declared in sample.input.EmbeddedChild.Companion.' type=sample.input.EmbeddedChild.Companion origin=null PROPERTY name:io_realm_kotlin_primaryKey visibility:public modality:FINAL [var] FIELD name:io_realm_kotlin_primaryKey type:kotlin.reflect.KMutableProperty1 visibility:private diff --git a/packages/plugin-compiler/src/test/resources/schema/expected/01_AFTER.ValidateIrBeforeLowering.ir b/packages/plugin-compiler/src/test/resources/schema/expected/01_AFTER.ValidateIrBeforeLowering.ir index 391f5b3a9e..2ced721b6a 100644 --- a/packages/plugin-compiler/src/test/resources/schema/expected/01_AFTER.ValidateIrBeforeLowering.ir +++ b/packages/plugin-compiler/src/test/resources/schema/expected/01_AFTER.ValidateIrBeforeLowering.ir @@ -77,20 +77,20 @@ MODULE_FRAGMENT name:
GET_FIELD 'FIELD name:io_realm_kotlin_className type:kotlin.String visibility:private' type=kotlin.String origin=null receiver: GET_VAR ': schema.input.A.Companion declared in schema.input.A.Companion.' type=schema.input.A.Companion origin=null PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] - FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private + FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private EXPRESSION_BODY - CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map> origin=null + CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null : kotlin.String - : kotlin.reflect.KProperty1 - pairs: VARARG type=kotlin.Array>> varargElementType=kotlin.collections.Map> - FUN name: visibility:public modality:FINAL <> ($this:schema.input.A.Companion) returnType:kotlin.collections.Map> + : kotlin.Pair, kotlin.reflect.KMutableProperty1> + pairs: VARARG type=kotlin.Array, kotlin.reflect.KMutableProperty1>>> varargElementType=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> + FUN name: visibility:public modality:FINAL <> ($this:schema.input.A.Companion) returnType:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> correspondingProperty: PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] overridden: - public abstract fun (): kotlin.collections.Map> declared in io.realm.kotlin.internal.RealmObjectCompanion + public abstract fun (): kotlin.collections.Map, kotlin.reflect.KProperty1>> declared in io.realm.kotlin.internal.RealmObjectCompanion $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:schema.input.A.Companion BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map> declared in schema.input.A.Companion' - GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private' type=kotlin.collections.Map> origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> declared in schema.input.A.Companion' + GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null receiver: GET_VAR ': schema.input.A.Companion declared in schema.input.A.Companion.' type=schema.input.A.Companion origin=null PROPERTY name:io_realm_kotlin_primaryKey visibility:public modality:FINAL [var] FIELD name:io_realm_kotlin_primaryKey type:kotlin.reflect.KMutableProperty1 visibility:private @@ -246,20 +246,20 @@ MODULE_FRAGMENT name:
GET_FIELD 'FIELD name:io_realm_kotlin_className type:kotlin.String visibility:private' type=kotlin.String origin=null receiver: GET_VAR ': schema.input.B.Companion declared in schema.input.B.Companion.' type=schema.input.B.Companion origin=null PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] - FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private + FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private EXPRESSION_BODY - CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map> origin=null + CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null : kotlin.String - : kotlin.reflect.KProperty1 - pairs: VARARG type=kotlin.Array>> varargElementType=kotlin.collections.Map> - FUN name: visibility:public modality:FINAL <> ($this:schema.input.B.Companion) returnType:kotlin.collections.Map> + : kotlin.Pair, kotlin.reflect.KMutableProperty1> + pairs: VARARG type=kotlin.Array, kotlin.reflect.KMutableProperty1>>> varargElementType=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> + FUN name: visibility:public modality:FINAL <> ($this:schema.input.B.Companion) returnType:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> correspondingProperty: PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] overridden: - public abstract fun (): kotlin.collections.Map> declared in io.realm.kotlin.internal.RealmObjectCompanion + public abstract fun (): kotlin.collections.Map, kotlin.reflect.KProperty1>> declared in io.realm.kotlin.internal.RealmObjectCompanion $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:schema.input.B.Companion BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map> declared in schema.input.B.Companion' - GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private' type=kotlin.collections.Map> origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> declared in schema.input.B.Companion' + GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null receiver: GET_VAR ': schema.input.B.Companion declared in schema.input.B.Companion.' type=schema.input.B.Companion origin=null PROPERTY name:io_realm_kotlin_primaryKey visibility:public modality:FINAL [var] FIELD name:io_realm_kotlin_primaryKey type:kotlin.reflect.KMutableProperty1 visibility:private @@ -415,20 +415,20 @@ MODULE_FRAGMENT name:
GET_FIELD 'FIELD name:io_realm_kotlin_className type:kotlin.String visibility:private' type=kotlin.String origin=null receiver: GET_VAR ': schema.input.C.Companion declared in schema.input.C.Companion.' type=schema.input.C.Companion origin=null PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] - FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private + FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private EXPRESSION_BODY - CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map> origin=null + CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections.MapsKt' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null : kotlin.String - : kotlin.reflect.KProperty1 - pairs: VARARG type=kotlin.Array>> varargElementType=kotlin.collections.Map> - FUN name: visibility:public modality:FINAL <> ($this:schema.input.C.Companion) returnType:kotlin.collections.Map> + : kotlin.Pair, kotlin.reflect.KMutableProperty1> + pairs: VARARG type=kotlin.Array, kotlin.reflect.KMutableProperty1>>> varargElementType=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> + FUN name: visibility:public modality:FINAL <> ($this:schema.input.C.Companion) returnType:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> correspondingProperty: PROPERTY name:io_realm_kotlin_fields visibility:public modality:FINAL [var] overridden: - public abstract fun (): kotlin.collections.Map> declared in io.realm.kotlin.internal.RealmObjectCompanion + public abstract fun (): kotlin.collections.Map, kotlin.reflect.KProperty1>> declared in io.realm.kotlin.internal.RealmObjectCompanion $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:schema.input.C.Companion BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map> declared in schema.input.C.Companion' - GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map> visibility:private' type=kotlin.collections.Map> origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> declared in schema.input.C.Companion' + GET_FIELD 'FIELD name:io_realm_kotlin_fields type:kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> visibility:private' type=kotlin.collections.Map, kotlin.reflect.KMutableProperty1>> origin=null receiver: GET_VAR ': schema.input.C.Companion declared in schema.input.C.Companion.' type=schema.input.C.Companion origin=null PROPERTY name:io_realm_kotlin_primaryKey visibility:public modality:FINAL [var] FIELD name:io_realm_kotlin_primaryKey type:kotlin.reflect.KMutableProperty1 visibility:private diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/CopyFromRealmTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/CopyFromRealmTests.kt index 6803f9e7a5..178e6515b0 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/CopyFromRealmTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/CopyFromRealmTests.kt @@ -54,6 +54,7 @@ import io.realm.kotlin.types.RealmSet import io.realm.kotlin.types.RealmUUID import org.mongodb.kbson.BsonObjectId import org.mongodb.kbson.Decimal128 +import kotlin.reflect.KClass import kotlin.reflect.KMutableProperty1 import kotlin.reflect.KProperty1 import kotlin.reflect.KType @@ -98,13 +99,13 @@ class CopyFromRealmTests { fun primitiveValues() { // This also checks that any default values set in the class are being overridden correctly. val type = Sample::class val schemaProperties = type.realmObjectCompanionOrThrow().io_realm_kotlin_schema().properties - val fields: Map> = type.realmObjectCompanionOrThrow().io_realm_kotlin_fields + val fields: Map, KProperty1>> = type.realmObjectCompanionOrThrow().io_realm_kotlin_fields // Dynamically set data on the Sample object val originalObject = Sample() schemaProperties.forEach { prop: RealmProperty -> if (prop.type is ValuePropertyType) { - val accessor: KMutableProperty1 = fields[prop.name] as KMutableProperty1 + val accessor: KMutableProperty1 = fields[prop.name]!!.second as KMutableProperty1 val fieldValue: Any? = createPrimitiveValueData(accessor) accessor.set(originalObject, fieldValue) } @@ -121,7 +122,7 @@ class CopyFromRealmTests { // Validate that all primitive list fields were round-tripped correctly. schemaProperties.forEach { prop: RealmProperty -> if (prop.type is ValuePropertyType) { - val accessor: KMutableProperty1 = fields[prop.name] as KMutableProperty1 + val accessor: KMutableProperty1 = fields[prop.name]!!.second as KMutableProperty1 val value: Any? = createPrimitiveValueData(accessor) if (prop.type.storageType == RealmStorageType.BINARY) { @@ -300,13 +301,13 @@ class CopyFromRealmTests { fun primitiveLists() { val type = Sample::class val schemaProperties = type.realmObjectCompanionOrThrow().io_realm_kotlin_schema().properties - val fields: Map> = type.realmObjectCompanionOrThrow().io_realm_kotlin_fields + val fields: Map, KProperty1>> = type.realmObjectCompanionOrThrow().io_realm_kotlin_fields // Dynamically set data on the Sample object val originalObject = Sample() schemaProperties.forEach { prop: RealmProperty -> if (prop.type is ListPropertyType && !(prop.type as ListPropertyType).isComputed) { - val accessor: KMutableProperty1 = fields[prop.name] as KMutableProperty1 + val accessor: KMutableProperty1 = fields[prop.name]!!.second as KMutableProperty1 val list: List = createPrimitiveListData(prop, accessor) accessor.set(originalObject, list) } @@ -323,7 +324,7 @@ class CopyFromRealmTests { // Validate that all primitive list fields were round-tripped correctly. schemaProperties.forEach { prop: RealmProperty -> if (prop.type is ListPropertyType && !(prop.type as ListPropertyType).isComputed) { - val accessor: KMutableProperty1 = fields[prop.name] as KMutableProperty1 + val accessor: KMutableProperty1 = fields[prop.name]!!.second as KMutableProperty1 val list: List = createPrimitiveListData(prop, accessor) if (prop.type.storageType == RealmStorageType.BINARY) { @@ -394,13 +395,13 @@ class CopyFromRealmTests { fun primitiveSets() { val type = Sample::class val schemaProperties = type.realmObjectCompanionOrThrow().io_realm_kotlin_schema().properties - val fields: Map> = type.realmObjectCompanionOrThrow().io_realm_kotlin_fields + val fields: Map, KProperty1>> = type.realmObjectCompanionOrThrow().io_realm_kotlin_fields // Dynamically set data on the Sample object val originalObject = Sample() schemaProperties.forEach { prop: RealmProperty -> if (prop.type is SetPropertyType) { - val accessor: KMutableProperty1 = fields[prop.name] as KMutableProperty1 + val accessor: KMutableProperty1 = fields[prop.name]!!.second as KMutableProperty1 val set: Set = createPrimitiveSetData(prop, accessor) accessor.set(originalObject, set) } @@ -417,7 +418,7 @@ class CopyFromRealmTests { // Validate that all primitive list fields were round-tripped correctly. schemaProperties.forEach { prop: RealmProperty -> if (prop.type is SetPropertyType) { - val accessor: KMutableProperty1 = fields[prop.name] as KMutableProperty1 + val accessor: KMutableProperty1 = fields[prop.name]!!.second as KMutableProperty1 val set: Set = createPrimitiveSetData(prop, accessor) if (prop.type.storageType == RealmStorageType.BINARY) { @@ -486,13 +487,13 @@ class CopyFromRealmTests { fun primitiveDictionaries() { val type = Sample::class val schemaProperties = type.realmObjectCompanionOrThrow().io_realm_kotlin_schema().properties - val fields: Map> = type.realmObjectCompanionOrThrow().io_realm_kotlin_fields + val fields: Map, KProperty1>> = type.realmObjectCompanionOrThrow().io_realm_kotlin_fields // Dynamically set data on the Sample object val originalObject = Sample() schemaProperties.forEach { prop: RealmProperty -> if (prop.type is MapPropertyType) { - val accessor: KMutableProperty1 = fields[prop.name] as KMutableProperty1 + val accessor: KMutableProperty1 = fields[prop.name]!!.second as KMutableProperty1 val dictionary: RealmDictionary = createPrimitiveDictionaryData(prop, accessor) accessor.set(originalObject, dictionary) } @@ -509,7 +510,7 @@ class CopyFromRealmTests { // Validate that all primitive list fields were round-tripped correctly. schemaProperties.forEach { prop: RealmProperty -> if (prop.type is MapPropertyType) { - val accessor: KMutableProperty1 = fields[prop.name] as KMutableProperty1 + val accessor: KMutableProperty1 = fields[prop.name]!!.second as KMutableProperty1 val dictionary: RealmDictionary = createPrimitiveDictionaryData(prop, accessor) if (prop.type.storageType == RealmStorageType.BINARY) { diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/SampleTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/SampleTests.kt index 3931202124..ae980a4ade 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/SampleTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/SampleTests.kt @@ -179,6 +179,7 @@ class SampleTests { @Test @Suppress("LongMethod") fun primitiveTypes() { + val oid = org.mongodb.kbson.ObjectId() realm.writeBlocking { copyToRealm(Sample()).apply { stringField = "Realm Kotlin" @@ -192,6 +193,7 @@ class SampleTests { doubleField = 1.19851106 decimal128Field = Decimal128("2.155544073709551618E-6157") timestampField = RealmInstant.from(42, 420) + bsonObjectIdField = oid } } @@ -210,6 +212,7 @@ class SampleTests { assertEquals(1.19851106, objects[0].doubleField) assertEquals(Decimal128("2.155544073709551618E-6157"), objects[0].decimal128Field) assertEquals(RealmInstant.from(42, 420), objects[0].timestampField) + assertEquals(oid, objects[0].bsonObjectIdField) } // querying on each type diff --git a/packages/test-sync/build.gradle.kts b/packages/test-sync/build.gradle.kts index f24c626ba6..83f24c8ec2 100644 --- a/packages/test-sync/build.gradle.kts +++ b/packages/test-sync/build.gradle.kts @@ -244,6 +244,7 @@ kotlin { dependencies { implementation(kotlin("test")) implementation(kotlin("test-junit")) + implementation(kotlin("reflect")) } } } diff --git a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/entities/sync/MongoDBClientSchemas.kt b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/entities/sync/MongoDBClientSchemas.kt new file mode 100644 index 0000000000..666c1ef489 --- /dev/null +++ b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/entities/sync/MongoDBClientSchemas.kt @@ -0,0 +1,65 @@ +/* + * Copyright 2024 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.entities.sync + +import io.realm.kotlin.types.EmbeddedRealmObject +import io.realm.kotlin.types.RealmAny +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import kotlinx.serialization.Serializable +import org.mongodb.kbson.BsonObjectId +import org.mongodb.kbson.ObjectId +import kotlin.random.Random + +@Serializable +@Suppress("ConstructorParameterNaming") +class CollectionDataType(var name: String = "Default", @PrimaryKey var _id: Int = Random.nextInt()) : + RealmObject { + constructor() : this("Default") +} + +class ParentCollectionDataType : RealmObject { + @PrimaryKey + @Suppress("VariableNaming") + var _id: ObjectId = BsonObjectId() + var name: String = "PARENT-DEFAULT" + var child: ChildCollectionDataType? = null + var embeddedChild: EmbeddedChildCollectionDataType? = null + var any: RealmAny? = null +} + +@Serializable +class ChildCollectionDataType : RealmObject { + @PrimaryKey + @Suppress("VariableNaming") + var _id: ObjectId = BsonObjectId() + var name: String = "CHILD-DEFAULT" +} + +@Serializable +class EmbeddedChildCollectionDataType : EmbeddedRealmObject { + @Suppress("VariableNaming") + var _id: ObjectId = BsonObjectId() + var name: String = "EMBEDDEDCHILD-DEFAULT" +} + +internal val COLLECTION_SCHEMAS = setOf( + CollectionDataType::class, + ParentCollectionDataType::class, + ChildCollectionDataType::class, + EmbeddedChildCollectionDataType::class, +) diff --git a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/entities/sync/SyncObjectWithAllTypes.kt b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/entities/sync/SyncObjectWithAllTypes.kt index b72debd629..1f4f65129f 100644 --- a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/entities/sync/SyncObjectWithAllTypes.kt +++ b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/entities/sync/SyncObjectWithAllTypes.kt @@ -32,7 +32,6 @@ import io.realm.kotlin.types.RealmUUID import io.realm.kotlin.types.annotations.PrimaryKey import org.mongodb.kbson.BsonObjectId import org.mongodb.kbson.Decimal128 -import kotlin.random.Random private typealias FieldDataFactory = (SyncObjectWithAllTypes) -> Unit private typealias FieldValidator = (SyncObjectWithAllTypes) -> Unit @@ -40,8 +39,9 @@ private typealias FieldValidator = (SyncObjectWithAllTypes) -> Unit @Suppress("MagicNumber") class SyncObjectWithAllTypes : RealmObject { @PrimaryKey + @Suppress("VariableNaming") - var _id: String = "id-${Random.nextLong()}" + var _id: String = "id-${BsonObjectId()}" // Non-nullable types var stringField: String = "hello world" diff --git a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/common/Schema.kt b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/common/Schema.kt index a7731d06f9..0f9f967f2a 100644 --- a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/common/Schema.kt +++ b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/common/Schema.kt @@ -18,6 +18,7 @@ package io.realm.kotlin.test.mongodb.common import io.realm.kotlin.entities.Location import io.realm.kotlin.entities.sync.BinaryObject +import io.realm.kotlin.entities.sync.COLLECTION_SCHEMAS import io.realm.kotlin.entities.sync.ChildPk import io.realm.kotlin.entities.sync.ObjectIdPk import io.realm.kotlin.entities.sync.ParentPk @@ -52,7 +53,8 @@ private val DEFAULT_SCHEMAS = setOf( ) val PARTITION_BASED_SCHEMA = DEFAULT_SCHEMAS -// Amount of schema classes that should be created on the server. EmbeddedRealmObjects are not -// included in this count -const val FLEXIBLE_SYNC_SCHEMA_COUNT = 11 -val FLEXIBLE_SYNC_SCHEMA = DEFAULT_SCHEMAS + ASYMMETRIC_SCHEMAS +// Amount of schema classes that should be created on the server. EmbeddedRealmObjects and +// AsymmetricRealmObjects are not included in this count. +// Run FlexibleSyncSchemaTests.flexibleSyncSchemaCount for verification. +const val FLEXIBLE_SYNC_SCHEMA_COUNT = 14 +val FLEXIBLE_SYNC_SCHEMA = DEFAULT_SCHEMAS + ASYMMETRIC_SCHEMAS + COLLECTION_SCHEMAS diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/CredentialsTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/CredentialsTests.kt index ee84b4ddca..b666ebb3dc 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/CredentialsTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/CredentialsTests.kt @@ -369,7 +369,7 @@ class CredentialsTests { payload = mapOf("mail" to TestHelper.randomEmail(), "id" to 0) ) - assertFailsWithMessage("[Service][AuthError(4346)] Error: Authentication failed.") { + assertFailsWithMessage("Error: Authentication failed.") { runBlocking { app.login(credentials) } diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/UserProfileTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/UserProfileTests.kt index 929fe66582..87e056b344 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/UserProfileTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/UserProfileTests.kt @@ -78,7 +78,7 @@ class UserProfileTests { } private lateinit var app: TestApp - lateinit var profileBody: Map + lateinit var profileBody: Map private fun setDefaultProfile() { profileBody = mapOf( @@ -89,8 +89,8 @@ class UserProfileTests { "last_name" to userProfile.lastName, "gender" to userProfile.gender, "birthday" to userProfile.birthday, - "min_age" to "${userProfile.minAge}", - "max_age" to "${userProfile.maxAge}" + "min_age" to userProfile.minAge, + "max_age" to userProfile.maxAge ) } @@ -115,6 +115,14 @@ class UserProfileTests { body: String, callback: ResponseCallback ) { + val profileData = profileBody.map { (k, v) -> + val value = when (v) { + is String -> Json.encodeToString(v) + is Long -> Json.encodeToString(v) + else -> TODO("Unsupported user data type $k : $v") + } + "\"$k\" : $value" + }.joinToString(separator = ",", prefix = "{", postfix = "}") { it } val result: String = when { url.endsWith("/providers/local-userpass/login") -> """ @@ -141,7 +149,7 @@ class UserProfileTests { } } ], - "data": ${Json.encodeToString(profileBody)}, + "data": $profileData, "type": "normal", "roles": [ { @@ -196,12 +204,12 @@ class UserProfileTests { document.entries.forEach { (key: String, value: BsonValue) -> assertContains(profileBody.keys, key) - val stringValue = when (value.bsonType) { + val parsedValue: Any = when (value.bsonType) { BsonType.STRING -> value.asString().value - BsonType.INT64 -> value.asInt64().value.toString() + BsonType.INT64 -> value.asInt64().value else -> TODO() } - assertEquals(profileBody[key], stringValue, "failed comparing key $key") + assertEquals(profileBody[key], parsedValue, "failed comparing key $key") } } diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/UserTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/UserTests.kt index 9f9b3d4232..6fb44e5f98 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/UserTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/UserTests.kt @@ -14,27 +14,36 @@ * limitations under the License. */ -@file:OptIn(ExperimentalKBsonSerializerApi::class, ExperimentalRealmSerializerApi::class) +@file:OptIn(ExperimentalRealmSerializerApi::class) package io.realm.kotlin.test.mongodb.common import io.realm.kotlin.Realm import io.realm.kotlin.annotations.ExperimentalRealmSerializerApi +import io.realm.kotlin.entities.sync.CollectionDataType import io.realm.kotlin.internal.platform.fileExists import io.realm.kotlin.internal.platform.runBlocking import io.realm.kotlin.mongodb.AuthenticationProvider import io.realm.kotlin.mongodb.Credentials import io.realm.kotlin.mongodb.User import io.realm.kotlin.mongodb.exceptions.CredentialsCannotBeLinkedException +import io.realm.kotlin.mongodb.exceptions.ServiceException import io.realm.kotlin.mongodb.ext.customData import io.realm.kotlin.mongodb.ext.customDataAsBsonDocument +import io.realm.kotlin.mongodb.ext.insertOne +import io.realm.kotlin.mongodb.mongo.MongoClient import io.realm.kotlin.mongodb.sync.SyncConfiguration import io.realm.kotlin.test.mongodb.TestApp import io.realm.kotlin.test.mongodb.asTestApp +import io.realm.kotlin.test.mongodb.common.mongo.CustomDataType +import io.realm.kotlin.test.mongodb.common.mongo.TEST_SERVICE_NAME +import io.realm.kotlin.test.mongodb.common.mongo.customEjsonSerializer +import io.realm.kotlin.test.mongodb.common.utils.assertFailsWithMessage import io.realm.kotlin.test.util.TestHelper import io.realm.kotlin.test.util.TestHelper.randomEmail import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlinx.serialization.SerializationException import org.mongodb.kbson.BsonDocument import org.mongodb.kbson.BsonString import org.mongodb.kbson.ExperimentalKBsonSerializerApi @@ -45,6 +54,7 @@ import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith import kotlin.test.assertFalse +import kotlin.test.assertIs import kotlin.test.assertNotEquals import kotlin.test.assertNotNull import kotlin.test.assertNotSame @@ -723,6 +733,67 @@ class UserTests { } } + @Test + @OptIn(ExperimentalKBsonSerializerApi::class) + fun mongoClient_defaultSerializer() = runBlocking { + val (email, password) = randomEmail() to "123456" + val user = runBlocking { + createUserAndLogin(email, password) + } + @OptIn(ExperimentalRealmSerializerApi::class) + val client: MongoClient = user.mongoClient(TEST_SERVICE_NAME) + assertIs(client.database(app.clientAppId).collection("CollectionDataType").insertOne(CollectionDataType("object-1"))) + } + + @Test + @OptIn(ExperimentalKBsonSerializerApi::class) + fun mongoClient_customSerializer() = runBlocking { + val (email, password) = randomEmail() to "123456" + val user = runBlocking { + createUserAndLogin(email, password) + } + val collectionWithDefaultSerializer = + user.mongoClient(TEST_SERVICE_NAME) + .database(app.clientAppId) + .collection("CollectionDataType") + assertFailsWithMessage("Serializer for class 'CustomDataType' is not found.") { + collectionWithDefaultSerializer.insertOne(CustomDataType("dog-1")) + } + + val collectionWithCustomSerializer = + user.mongoClient(TEST_SERVICE_NAME, customEjsonSerializer).database(app.clientAppId) + .collection("CollectionDataType") + assertIs(collectionWithCustomSerializer.insertOne(CustomDataType("dog-1"))) + } + + @Test + @OptIn(ExperimentalKBsonSerializerApi::class) + fun mongoClient_unknownClient() = runBlocking { + val (email, password) = randomEmail() to "123456" + val user = runBlocking { + createUserAndLogin(email, password) + } + val mongoClient = user.mongoClient("UNKNOWN_SERVICE") + val collection = + mongoClient.database(app.clientAppId).collection("CollectionDataType") + assertFailsWithMessage("Cannot access member 'insertOne' of undefined") { + collection.insertOne(CollectionDataType("object-1")) + } + } + + @Test + @OptIn(ExperimentalKBsonSerializerApi::class) + fun mongoClient_throwsOnLoggedOutUser() = runBlocking { + val (email, password) = randomEmail() to "123456" + val user = runBlocking { + createUserAndLogin(email, password) + } + user.logOut() + assertFailsWithMessage("Cannot obtain a MongoClient from a logged out user") { + user.mongoClient("UNKNOWN_SERVICE") + } + } + private fun updatecustomDataAsBsonDocument(user: User, data: BsonDocument) { // Name of collection and property used for storing custom user data. Must match server config.json val COLLECTION_NAME = "UserData" diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/mongo/MongoClientTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/mongo/MongoClientTests.kt new file mode 100644 index 0000000000..10287cdfe1 --- /dev/null +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/mongo/MongoClientTests.kt @@ -0,0 +1,120 @@ +/* + * Copyright 2023 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.test.mongodb.common.mongo + +import io.realm.kotlin.entities.sync.CollectionDataType +import io.realm.kotlin.internal.platform.runBlocking +import io.realm.kotlin.mongodb.exceptions.ServiceException +import io.realm.kotlin.mongodb.ext.collection +import io.realm.kotlin.mongodb.ext.insertOne +import io.realm.kotlin.mongodb.mongo.MongoClient +import io.realm.kotlin.test.mongodb.TEST_APP_FLEX +import io.realm.kotlin.test.mongodb.TestApp +import io.realm.kotlin.test.mongodb.common.utils.assertFailsWithMessage +import kotlinx.serialization.SerializationException +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertIs + +internal const val TEST_SERVICE_NAME = "BackingDB" + +@OptIn(ExperimentalKBsonSerializerApi::class) +class MongoClientTests { + + lateinit var app: TestApp + lateinit var client: MongoClient + + @BeforeTest + fun setUp() { + app = TestApp( + this::class.simpleName, + appName = TEST_APP_FLEX, + ) + val user = app.createUserAndLogin() + client = user.mongoClient(TEST_SERVICE_NAME) + } + + @AfterTest + fun teadDown() { + if (this::app.isInitialized) { + app.close() + } + } + + @Test + fun properties() { + assertEquals(TEST_SERVICE_NAME, client.serviceName) + } + + @Test + fun database_defaultSerializer() = runBlocking { + assertIs(client.database(app.clientAppId).collection("CollectionDataType").insertOne(CollectionDataType("object-1"))) + } + + @Test + @OptIn(ExperimentalKBsonSerializerApi::class) + fun database_customSerializer() = runBlocking { + val collectionWithDefaultSerializer = client.database(app.clientAppId) + .collection("CollectionDataType") + assertFailsWithMessage("Serializer for class 'CustomDataType' is not found.") { + collectionWithDefaultSerializer.insertOne(CustomDataType("object-1")) + } + val collectionWithCustomSerializer = client.database(app.clientAppId, customEjsonSerializer) + .collection("CollectionDataType") + assertIs(collectionWithCustomSerializer.insertOne(CustomDataType("object-1"))) + } + + @Test + fun database_createsCollectionOnInsertToUnknownDatabase() = runBlocking { + val database = client.database("Unknown") + val collection = database.collection("NewCollection") + assertIs(collection.insertOne(CollectionDataType("object-1")) as Int) + } + + @Test + fun collection_defaultSerializer() = runBlocking { + assertIs(client.collection().insertOne(CollectionDataType("object-1"))) + } + + @Test + fun collection_customSerializer() = runBlocking { + val collectionWithDefaultSerializer = client.collection() + assertFailsWithMessage("Serializer for class 'CustomDataType' is not found.") { + collectionWithDefaultSerializer.withDocumentClass().insertOne(CustomDataType("object-1")) + } + + val collectionWithCustomSerializer = client.collection( + customEjsonSerializer + ) + assertIs( + collectionWithCustomSerializer.insertOne( + CustomDataType("object-1") + ) + ) + } + + @Test + fun collection_unknownSchemaType() = runBlocking { + val collectionWithDefaultSerializer = client.collection() + assertFailsWithMessage("no matching collection found that maps to a table with title \"NonSchemaType\".") { + collectionWithDefaultSerializer.insertOne(NonSchemaType()) + } + } +} diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/mongo/MongoCollectionTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/mongo/MongoCollectionTests.kt new file mode 100644 index 0000000000..2b7e9e0255 --- /dev/null +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/mongo/MongoCollectionTests.kt @@ -0,0 +1,1496 @@ +/* + * Copyright 2023 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.test.mongodb.common.mongo + +import io.realm.kotlin.Realm +import io.realm.kotlin.entities.sync.COLLECTION_SCHEMAS +import io.realm.kotlin.entities.sync.ChildCollectionDataType +import io.realm.kotlin.entities.sync.CollectionDataType +import io.realm.kotlin.entities.sync.EmbeddedChildCollectionDataType +import io.realm.kotlin.entities.sync.ParentCollectionDataType +import io.realm.kotlin.ext.asRealmObject +import io.realm.kotlin.ext.query +import io.realm.kotlin.internal.platform.runBlocking +import io.realm.kotlin.mongodb.User +import io.realm.kotlin.mongodb.exceptions.ServiceException +import io.realm.kotlin.mongodb.ext.aggregate +import io.realm.kotlin.mongodb.ext.collection +import io.realm.kotlin.mongodb.ext.count +import io.realm.kotlin.mongodb.ext.deleteMany +import io.realm.kotlin.mongodb.ext.deleteOne +import io.realm.kotlin.mongodb.ext.find +import io.realm.kotlin.mongodb.ext.findOne +import io.realm.kotlin.mongodb.ext.findOneAndDelete +import io.realm.kotlin.mongodb.ext.findOneAndReplace +import io.realm.kotlin.mongodb.ext.findOneAndUpdate +import io.realm.kotlin.mongodb.ext.insertMany +import io.realm.kotlin.mongodb.ext.insertOne +import io.realm.kotlin.mongodb.ext.updateMany +import io.realm.kotlin.mongodb.ext.updateOne +import io.realm.kotlin.mongodb.mongo.MongoClient +import io.realm.kotlin.mongodb.mongo.MongoCollection +import io.realm.kotlin.mongodb.mongo.MongoDatabase +import io.realm.kotlin.mongodb.mongo.realmSerializerModule +import io.realm.kotlin.mongodb.sync.SyncConfiguration +import io.realm.kotlin.mongodb.syncSession +import io.realm.kotlin.notifications.ResultsChange +import io.realm.kotlin.test.mongodb.TEST_APP_FLEX +import io.realm.kotlin.test.mongodb.TestApp +import io.realm.kotlin.test.mongodb.asTestApp +import io.realm.kotlin.test.mongodb.common.FLEXIBLE_SYNC_SCHEMA +import io.realm.kotlin.test.mongodb.common.utils.assertFailsWithMessage +import io.realm.kotlin.test.mongodb.common.utils.retry +import io.realm.kotlin.test.util.receiveOrFail +import io.realm.kotlin.test.util.use +import io.realm.kotlin.types.BaseRealmObject +import io.realm.kotlin.types.RealmAny +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PersistedName +import kotlinx.coroutines.async +import kotlinx.coroutines.channels.Channel +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerializationException +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.modules.SerializersModule +import org.mongodb.kbson.BsonDocument +import org.mongodb.kbson.BsonInt32 +import org.mongodb.kbson.BsonString +import org.mongodb.kbson.BsonValue +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import org.mongodb.kbson.ObjectId +import org.mongodb.kbson.serialization.EJson +import org.mongodb.kbson.serialization.encodeToBsonValue +import kotlin.random.Random +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertIs +import kotlin.test.assertNotEquals +import kotlin.test.assertNull +import kotlin.test.assertTrue +import kotlin.time.Duration.Companion.seconds + +/** + * Test class that verifies MongoDB Client API interactions through the + * `MongoClient.database(...).collection(...)`-API. + */ +class MongoCollectionFromDatabaseTests : MongoCollectionTests() { + + lateinit var database: MongoDatabase + + @BeforeTest + override fun setUp() { + super.setUp() + val databaseName = app.configuration.appId + @OptIn(ExperimentalKBsonSerializerApi::class) + database = client.database(databaseName) + @OptIn(ExperimentalKBsonSerializerApi::class) + collection = collection() + } + + @Test + override fun findOne_unknownCollection() = runBlocking { + // Unknown collections will create the collection if inserting document, so only use + // NonSchemaType for queries + @OptIn(ExperimentalKBsonSerializerApi::class) + val unknownCollection = collection() + assertNull(unknownCollection.findOne()) + } +} + +/** + * Test class that verifies MongoDB Client API interactions through the + * `MongoClient.collection(...)`-API. + */ +class MongoCollectionFromClientTests : MongoCollectionTests() { + + @BeforeTest + override fun setUp() { + super.setUp() + @OptIn(ExperimentalKBsonSerializerApi::class) + collection = collection() + } + + @Test + fun name_persistedName() { + @OptIn(ExperimentalKBsonSerializerApi::class) + assertEquals("CollectionDataType", client.collection().name) + } + + @OptIn(ExperimentalKBsonSerializerApi::class) + @Test + override fun findOne_unknownCollection() = runBlocking { + @OptIn(ExperimentalKBsonSerializerApi::class) + val unknownCollection = collection() + assertFailsWithMessage("no matching collection found that maps to a table with title \"NonSchemaType\"") { + unknownCollection.findOne() + } + } +} + +sealed class MongoCollectionTests { + + lateinit var app: TestApp + lateinit var user: User + lateinit var client: MongoClient + lateinit var collection: MongoCollection + + @BeforeTest + open fun setUp() { + app = TestApp( + testId = this::class.simpleName, + appName = TEST_APP_FLEX, + builder = { + it.httpLogObfuscator(null) + } + ) + + app.asTestApp.run { + runBlocking { + COLLECTION_SCHEMAS.forEach { + deleteDocuments(app.configuration.appId, it.simpleName!!, "{}") + } + } + } + user = app.createUserAndLogin() + @OptIn(ExperimentalKBsonSerializerApi::class) + client = user.mongoClient( + serviceName = TEST_SERVICE_NAME, + eJson = EJson( + serializersModule = realmSerializerModule( + setOf( + ParentCollectionDataType::class, + ChildCollectionDataType::class + ) + ) + ) + ) + } + + @AfterTest + fun tearDown() { + app.asTestApp.run { + runBlocking { + COLLECTION_SCHEMAS.forEach { + deleteDocuments(app.configuration.appId, it.simpleName!!, "{}") + } + } + } + if (this::app.isInitialized) { + app.close() + } + } + + @Test + fun name() { + assertEquals("CollectionDataType", collection.name) + } + + @Test + fun withDocumentClass() = runBlocking { + // Original typing + assertIs(collection.insertOne(CollectionDataType("object-1", Random.nextInt()))) + assertIs(collection.findOne()) + + // Reshaped + @OptIn(ExperimentalKBsonSerializerApi::class) + val bsonCollection: MongoCollection = collection.withDocumentClass() + assertIs(bsonCollection.insertOne(BsonDocument("_id" to BsonInt32(Random.nextInt()), "name" to BsonString("object-2")))) + assertIs(bsonCollection.findOne()) + assertEquals(2, bsonCollection.count()) + } + + @Test + fun withDocumentClass_withCustomSerialization() = runBlocking { + @OptIn(ExperimentalKBsonSerializerApi::class) + val reshapedCollectionWithDefaultSerializer: MongoCollection = + collection.withDocumentClass() + + assertFailsWithMessage("Serializer for class 'CustomDataType' is not found.") { + reshapedCollectionWithDefaultSerializer.insertOne(CustomDataType("object-2")) + } + + @OptIn(ExperimentalKBsonSerializerApi::class) + val reshapedCollectionWithCustomSerializer: MongoCollection = + collection.withDocumentClass(customEjsonSerializer) + + assertIs(reshapedCollectionWithCustomSerializer.insertOne(CustomDataType("object-2"))) + } + + @Test + fun count() = runBlocking { + assertEquals(0, collection.count()) + + collection.insertMany((1..10).map { CollectionDataType("object-${it % 5}") }) + + assertEquals(10, collection.count()) + assertEquals(5, collection.count(limit = 5)) + assertEquals(2, collection.count(filter = BsonDocument("name" to BsonString("object-0")))) + assertEquals(2, collection.count(filter = BsonDocument("name", "object-0"))) + assertEquals( + 1, + collection.count(filter = BsonDocument("name" to BsonString("object-0")), limit = 1) + ) + } + + @Test + fun count_invalidFilter() = runBlocking { + assertFailsWithMessage("operator") { + collection.count(filter = BsonDocument("\$who", "object-0")) + } + } + + @Test + fun findOne() = runBlocking { + // Empty collections + assertNull(collection.findOne()) + + collection.insertMany((1..10).map { CollectionDataType("object-${it % 5}") }) + + // No match + assertNull(collection.findOne(filter = BsonDocument("name", "cat"))) + + // Multiple matches, still only one document + // Default types + collection.findOne(filter = BsonDocument("name", "object-0")).run { + assertIs(this) + assertEquals("object-0", this.name) + } + + // Projection + val collectionDataType = CollectionDataType("object-6") + assertEquals(collectionDataType._id, collection.insertOne(collectionDataType)) + + collection.findOne(filter = BsonDocument("name", "object-6")).run { + assertIs(this) + assertEquals("object-6", this.name) + assertEquals(collectionDataType._id, this._id) + } + + // Project without name + collection.findOne( + filter = BsonDocument("name", "object-6"), + projection = BsonDocument("""{ "name" : 0}""") + ).run { + assertIs(this) + assertEquals("Default", this.name) + // _id is included by default + assertEquals(collectionDataType._id, this._id) + } + // Project without _id, have to be explicitly excluded + collection.findOne( + filter = BsonDocument("name", "object-6"), + projection = BsonDocument("""{ "_id" : 0}""") + ).run { + assertIs(this) + assertEquals(collectionDataType.name, name) + assertNotEquals(collectionDataType._id, this._id) + } + + // Sort + collection.findOne(sort = BsonDocument(mapOf("name" to BsonInt32(-1)))).run { + assertIs(this) + assertEquals("object-6", this.name) + } + collection.findOne(sort = BsonDocument(mapOf("name" to BsonInt32(1)))).run { + assertIs(this) + assertEquals("object-0", this.name) + } + } + + @OptIn(ExperimentalKBsonSerializerApi::class) + @Test + fun findOne_explicitTypes() = runBlocking { + // Empty collection + assertNull(collection.findOne()) + + collection.insertMany((1..10).map { CollectionDataType("object-${it % 5}") }) + + // Explicit types + val findOne: BsonDocument? = collection.withDocumentClass().findOne(filter = BsonDocument("name", "object-0")) + findOne.run { + assertIs(this) + assertEquals("object-0", this["name"]!!.asString().value) + } + } + + @Test + fun findOne_links() = runBlocking { + Realm.open( + SyncConfiguration.Builder(user, FLEXIBLE_SYNC_SCHEMA) + .initialSubscriptions { + add(it.query()) + add(it.query()) + } + .build() + ).use { realm -> + val syncedParent = realm.write { + copyToRealm(ParentCollectionDataType().apply { child = ChildCollectionDataType() }) + } + realm.syncSession.uploadAllLocalChanges(30.seconds) + + @OptIn(ExperimentalKBsonSerializerApi::class) + val parentCollection = collection() + + val mongoDBClientParent = retry( + { parentCollection.findOne() }, + { response: ParentCollectionDataType? -> response != null }, + ) + assertEquals(syncedParent._id, mongoDBClientParent!!._id) + assertEquals(syncedParent.child!!._id, mongoDBClientParent.child!!._id) + } + } + + @Test + fun findOne_typedLinks() = runBlocking { + Realm.open( + SyncConfiguration.Builder(user, FLEXIBLE_SYNC_SCHEMA) + .initialSubscriptions { + add(it.query()) + add(it.query()) + } + .build() + ).use { realm -> + val syncedParent = realm.write { + copyToRealm( + ParentCollectionDataType().apply { + any = RealmAny.create(ChildCollectionDataType()) + } + ) + } + // We need to upload schema before proceeding + realm.syncSession.uploadAllLocalChanges(30.seconds) + + @OptIn(ExperimentalKBsonSerializerApi::class) + val parentCollection = collection() + + val mongoDBClientParent = retry( + action = { parentCollection.findOne() }, + until = { response -> response != null } + ) + assertEquals(syncedParent._id, mongoDBClientParent!!._id) + assertEquals(syncedParent.any!!.asRealmObject()._id, mongoDBClientParent.any!!.asRealmObject()._id) + } + } + + @Test + fun findOne_typedLinks_unknownClassBecomesDictionary() = runBlocking { + Realm.open( + SyncConfiguration.Builder(user, FLEXIBLE_SYNC_SCHEMA) + .initialSubscriptions { + add(it.query()) + add(it.query()) + } + .build() + ).use { realm -> + realm.write { + copyToRealm( + ParentCollectionDataType().apply { + any = RealmAny.create(ChildCollectionDataType()) + } + ) + } + // We need to upload schema before proceeding + realm.syncSession.uploadAllLocalChanges(30.seconds) + + @OptIn(ExperimentalKBsonSerializerApi::class) + val parentCollection = collection( + EJson( + serializersModule = realmSerializerModule( + setOf(ParentCollectionDataType::class) + ) + ) + ) + + // We need to await until the response is non-null otherwise there will be nothing + // to deserialize and no exception will be thrown + retry( + action = { parentCollection.findOne() }, + until = { response -> response != null } + )!!.run { + assertEquals("ChildCollectionDataType", any!!.asDictionary()["${"$"}ref"]!!.asString()) + } + } + } + + @OptIn(ExperimentalKBsonSerializerApi::class) + @Test + fun findOne_embeddedObjects() = runBlocking { + // Empty collections + assertNull(collection.findOne()) + + val parentCollection = collection() + parentCollection.insertOne( + ParentCollectionDataType().apply { + embeddedChild = EmbeddedChildCollectionDataType().apply { name = "EMBEDDED-NAME" } + } + ) + + parentCollection.find().single().run { + assertEquals("EMBEDDED-NAME", embeddedChild!!.name) + } + } + + @OptIn(ExperimentalKBsonSerializerApi::class) + @Test + fun findOne_extraFieldsAreDiscarded() = runBlocking { + val withDocumentClass = collection.withDocumentClass() + withDocumentClass.insertOne( + BsonDocument( + mapOf( + "_id" to BsonInt32(Random.nextInt()), + "name" to BsonString("object-1"), + "extra" to BsonString("extra"), + ) + ) + ) + + // Show that remote method returns extra properties + withDocumentClass.findOne()!!.let { + assertEquals("extra", it["extra"]!!.asString().value) + } + // But these properties are silently discarded by the serialization framework + assertIs(collection.findOne()) + } + + @Test + fun findOne_missingFieldsGetsDefaults() = runBlocking { + collection.insertOne(CollectionDataType("object-1")) + collection.findOne( + projection = BsonDocument("""{ "name" : 0}""") + ).run { + assertIs(this) + assertEquals("Default", this.name) + } + } + + @Test + abstract fun findOne_unknownCollection() + + @Test + fun findOne_fails() = runBlocking { + assertFailsWithMessage("operator") { + collection.findOne(BsonDocument("\$who", 1)) + } + } + + @Test + fun find() = runBlocking { + assertTrue { collection.find().isEmpty() } + + val names = (1..10).map { "object-${it % 5}" } + val ids: List = collection.insertMany(names.map { CollectionDataType(it) }) + + assertEquals(10, collection.find().size) + + collection.find(filter = BsonDocument("name", "object-1")).let { + assertEquals(2, it.size) + } + + // Limit + collection.find( + limit = 5, + ).let { + assertEquals(5, it.size) + } + + // Projection + collection.find( + filter = BsonDocument("name", "object-1"), + projection = BsonDocument("""{ "name" : 0}"""), + ).let { + assertEquals(2, it.size) + it.forEach { + assertEquals("Default", it.name) + // _id is included by default + assertTrue(it._id in ids) + } + } + collection.find( + filter = BsonDocument("name", "object-1"), + projection = BsonDocument("""{ "_id" : 0}"""), + ).let { + assertEquals(2, it.size) + it.forEach { + assertEquals("object-1", it.name) + // Objects have new ids + assertFalse(it._id in ids) + } + } + + // Sort + collection.find(sort = BsonDocument("""{ "name" : -1}""")).let { results -> + assertEquals(names.sorted().reversed(), results.map { it.name }) + } + collection.find(sort = BsonDocument("""{ "name" : 1}""")).let { results -> + assertEquals(names.sorted(), results.map { it.name }) + } + } + + @Test + @OptIn(ExperimentalKBsonSerializerApi::class) + fun find_explicitTypes() = runBlocking { + collection.find().let { assertTrue { it.isEmpty() } } + + val reshapedCollection = collection.withDocumentClass() + + val names = (1..10).map { "object-${it % 5}" } + reshapedCollection.insertMany(names.map { BsonDocument("_id" to BsonInt32(Random.nextInt()), "name" to BsonString(it)) }) + + reshapedCollection.find().let { results -> + results.forEach { + assertIs(it) + assertTrue { it.asDocument()["name"]!!.asString().value in names } + } + } + } + + @Test + fun find_fails() = runBlocking { + assertFailsWithMessage("unknown top level operator: \$who.") { + collection.find(filter = BsonDocument("\$who", 1)).first() + } + } + + @Test + fun aggregate() = runBlocking { + collection.aggregate(listOf()).let { assertTrue { it.isEmpty() } } + + val names = (1..10).map { "object-${it % 5}" } + collection.insertMany(names.map { CollectionDataType(it) }) + + collection.aggregate( + pipeline = listOf() + ).let { + assertEquals(10, it.size) + it.forEach { + assertTrue { it.name in names } + } + } + + collection.aggregate( + pipeline = listOf(BsonDocument("\$sort", BsonDocument("name", -1)), BsonDocument("\$limit", 2)) + ).let { + assertEquals(2, it.size) + it.forEach { + assertEquals("object-4", it.name) + } + } + } + + @Test + fun aggregate_fails() = runBlocking { + assertFailsWithMessage("Unrecognized pipeline stage name: '\$who'.") { + collection.aggregate(pipeline = listOf(BsonDocument("\$who", 1))) + } + } + + @Test + fun insertOne() = runBlocking { + assertEquals(0, collection.find().size) + + collection.insertOne(CollectionDataType("object-1")).let { + assertIs(it) + } + assertEquals(1, collection.find().size) + } + + @Test + @OptIn(ExperimentalKBsonSerializerApi::class) + fun insertOne_links() = runBlocking { + // Open a synced realm and verified that the linked entities we upload through the + Realm.open( + SyncConfiguration.Builder(user, FLEXIBLE_SYNC_SCHEMA) + .initialSubscriptions { + add(it.query()) + add(it.query()) + } + .build() + ).use { realm -> + // We need to upload schema before proceeding + realm.syncSession.uploadAllLocalChanges() + + // We set up listeners to be able to react on when the objects are seen in the synced realm + val childChannel = Channel>(10) + val childListener = + async { realm.query().asFlow().collect { childChannel.send(it) } } + childChannel.receiveOrFail(message = "Didn't receive initial value").let { + assertTrue { it.list.isEmpty() } + } + val parentChannel = Channel>(10) + val parentListener = + async { realm.query().asFlow().collect { parentChannel.send(it) } } + parentChannel.receiveOrFail(message = "Didn't receive initial value").let { + assertTrue { it.list.isEmpty() } + } + + val childCollection = collection() + val unmanagedChild = ChildCollectionDataType() + assertEquals(unmanagedChild._id, childCollection.insertOne(unmanagedChild)) + // We can't rely on the translator to incorporate the insertOnes in order so we need to + // assure that the child is actually added before verifying the link in the parent. + childChannel.receiveOrFail(message = "Didn't receive initial value").let { + assertEquals(unmanagedChild._id, it.list.first()._id) + } + + val parentCollection = collection() + val unmanagedParent = ParentCollectionDataType().apply { + this.child = unmanagedChild + } + val actual = parentCollection.insertOne(unmanagedParent) + assertEquals(unmanagedParent._id, actual) + + // Verifying that the parent include the correct link + parentChannel.receiveOrFail( + timeout = 5.seconds, + message = "Didn't receive update value" + ).let { + val parent = it.list.first() + assertEquals(unmanagedParent._id, parent._id) + parent.child!!.let { + assertEquals(unmanagedChild._id, it._id) + assertEquals(unmanagedChild.name, it.name) + } + } + parentListener.cancel() + childListener.cancel() + } + } + + @Test + @OptIn(ExperimentalKBsonSerializerApi::class) + fun insertOne_typedLinks() = runBlocking { + // Open a synced realm and verified that the linked entities we upload through the + Realm.open( + SyncConfiguration.Builder(user, FLEXIBLE_SYNC_SCHEMA) + .initialSubscriptions { + add(it.query()) + add(it.query()) + } + .build() + ).use { realm -> + // We need to upload schema before proceeding + realm.syncSession.uploadAllLocalChanges() + + // We set up listeners to be able to react on when the objects are seen in the synced realm + val childChannel = Channel>(10) + val childListener = + async { realm.query().asFlow().collect { childChannel.send(it) } } + childChannel.receiveOrFail(message = "Didn't receive initial value").let { + assertTrue { it.list.isEmpty() } + } + val parentChannel = Channel>(10) + val parentListener = + async { realm.query().asFlow().collect { parentChannel.send(it) } } + parentChannel.receiveOrFail(message = "Didn't receive initial value").let { + assertTrue { it.list.isEmpty() } + } + + val childCollection = collection() + assertEquals(0, childCollection.find().size) + val unmanagedChild = ChildCollectionDataType() + assertEquals(unmanagedChild._id, childCollection.insertOne(unmanagedChild)) + // We can't rely on the translator to incorporate the insertOnes in order so we need to + // assure that the child is actually added before verifying the link in the parent. + childChannel.receiveOrFail(message = "Didn't receive initial value").let { + assertEquals(unmanagedChild._id, it.list.first()._id) + } + + val parentCollection = collection() + val unmanagedParent = ParentCollectionDataType().apply { + this.any = RealmAny.create(unmanagedChild) + } + + val actual = parentCollection.insertOne(unmanagedParent) + assertEquals(unmanagedParent._id, actual) + + // Verifying that the parent include the correct link + parentChannel.receiveOrFail( + timeout = 5.seconds, + message = "Didn't receive update value" + ).let { + val parent = it.list.first() + assertEquals(unmanagedParent._id, parent._id) + parent.any!!.asRealmObject().let { + assertEquals(unmanagedChild._id, it._id) + assertEquals(unmanagedChild.name, it.name) + } + } + parentListener.cancel() + childListener.cancel() + } + } + + @OptIn(ExperimentalKBsonSerializerApi::class) + @Test + fun insertOne_embeddedObjects() = runBlocking { + val parentCollection = collection() + // Empty collections + assertNull(parentCollection.findOne()) + parentCollection.insertOne( + ParentCollectionDataType().apply { + embeddedChild = EmbeddedChildCollectionDataType().apply { name = "EMBEDDED-NAME" } + } + ) + + parentCollection.find().single().run { + assertEquals("EMBEDDED-NAME", embeddedChild!!.name) + } + } + + @OptIn(ExperimentalKBsonSerializerApi::class) + @Test + fun insertOne_explicitTypes() = runBlocking { + assertEquals(0, collection.find().size) + // Inserting document without _id will use ObjectId as _id + collection.withDocumentClass().insertOne( + BsonDocument("_id" to BsonInt32(Random.nextInt()), "name" to BsonString("object-1")) + ).let { + assertIs(it) + } + // Inserted document will have ObjectId key and cannot be serialized into CollectionDataType + // so find must also use BsonDocument + assertEquals(1, collection.find().size) + } + + @Test + fun insertOne_throwsOnExistingPrimaryKey() = runBlocking { + assertEquals(0, collection.find().size) + + val document = CollectionDataType("object-1") + collection.insertOne(document).let { + assertIs(it) + } + assertFailsWithMessage("Duplicate key error") { + collection.insertOne(document) + } + assertEquals(1, collection.find().size) + } + + @OptIn(ExperimentalKBsonSerializerApi::class) + @Test + fun insertOne_throwsOnMissingRequiredFields() = runBlocking { + assertFailsWithMessage("insert not permitted") { + collection.withDocumentClass().insertOne(BsonDocument("_id", ObjectId())) + } + } + + @OptIn(ExperimentalKBsonSerializerApi::class) + @Test + fun insertOne_throwsOnTypeMismatch() = runBlocking { + assertFailsWithMessage("insert not permitted") { + collection.withDocumentClass().insertOne( + BsonDocument(mapOf("_id" to ObjectId(), "name" to BsonString("object-1"))) + ) + } + } + @Test + fun insertMany() = runBlocking { + assertEquals(0, collection.find().size) + + collection.insertMany((1..10).map { CollectionDataType("object-${it % 5}") }).let { ids -> + assertEquals(10, ids.size) + ids.forEach { id -> + assertIs(id) + } + } + + assertEquals(10, collection.find().size) + } + + @Test + fun insertMany_explictTyped() = runBlocking { + assertEquals(0, collection.find().size) + + collection.insertMany( + (1..10).map { + BsonDocument( + "_id" to BsonInt32(Random.nextInt()), + "name" to BsonString("object-${it % 5}") + ) + } + ).let { + assertEquals(10, it.size) + it.forEach { + assertIs(it) + } + } + assertEquals(10, collection.find().size) + } + + // InsertMany with links + + @Test + fun insertMany_throwsOnEmptyList() = runBlocking { + assertFailsWithMessage("must provide at least one element") { + collection.insertMany(emptyList()) + } + } + + @Test + fun insertMany_throwsOnExistingPrimaryKey() = runBlocking { + assertEquals(0, collection.find().size) + + val document = CollectionDataType("object-1") + assertFailsWithMessage("Duplicate key error") { + collection.insertMany(listOf(document.apply { name = "sadf" }, document)) + } + // Above call will throw an error, but we have actually inserted one document + assertEquals(1, collection.find().size) + } + + @Test + fun insertMany_throwsOnMissingRequiredFields() = runBlocking { + assertFailsWithMessage("insert not permitted") { + collection.insertMany(listOf(BsonDocument())) + } + } + + @Test + fun insertMany_throwsOnTypeMismatch() = runBlocking { + assertFailsWithMessage("insert not permitted") { + collection.insertMany( + listOf( + BsonDocument( + mapOf( + "_id" to ObjectId(), + "name" to BsonString("object-1") + ) + ) + ) + ) + } + } + + @Test + fun deleteOne() = runBlocking { + assertFalse { collection.deleteOne(filter = BsonDocument()) } + + assertEquals( + 2, + collection.insertMany( + listOf( + CollectionDataType("object-1"), + CollectionDataType("object-1") + ) + ).size + ) + assertEquals(2, collection.count(filter = BsonDocument("""{ "name": "object-1" }"""))) + + assertTrue { collection.deleteOne(filter = BsonDocument("""{ "name": "object-1" }""")) } + assertEquals(1, collection.count(filter = BsonDocument("""{ "name": "object-1" }"""))) + } + + @Test + fun deleteOne_fails() = runBlocking { + assertFailsWithMessage("unknown top level operator: \$who.") { + collection.deleteOne(filter = BsonDocument("\$who", 1)) + } + } + + @Test + fun deleteMany() = runBlocking { + assertEquals(0, collection.deleteMany(filter = BsonDocument())) + + collection.insertMany((1..10).map { CollectionDataType("object-${it % 5}") }) + assertEquals(10, collection.find().size) + + assertEquals(2, collection.deleteMany(filter = BsonDocument("""{ "name": "object-1" }"""))) + + assertEquals(8, collection.find().size) + + assertEquals(8, collection.deleteMany(filter = BsonDocument())) + } + + @Test + fun deleteMany_fails() = runBlocking { + assertFailsWithMessage("unknown top level operator: \$who.") { + collection.deleteMany(filter = BsonDocument("\$who", 1)) + } + } + + @Test + fun updateOne() = runBlocking { + assertEquals(0, collection.count()) + + assertEquals( + 4, + collection.insertMany( + listOf( + CollectionDataType("object-1"), + CollectionDataType("object-1"), + CollectionDataType("object-1"), + CollectionDataType("object-1") + ) + ).size + ) + assertEquals(4, collection.count()) + + // Update no match + collection.updateOne( + filter = BsonDocument("""{ "name": "NOMATCH"}"""), + update = BsonDocument("\$set", BsonDocument("""{ "name": "UPDATED"}""")), + ).let { (updated, upsertedId) -> + assertFalse(updated) + assertNull(upsertedId) + } + + // Update with match match + collection.updateOne( + filter = BsonDocument("""{ "name": "object-1"}"""), + update = BsonDocument("\$set", BsonDocument("""{ "name": "object-2"}""")), + ).let { (updated, upsertedId) -> + assertTrue(updated) + assertNull(upsertedId) + } + assertEquals(4, collection.count()) + assertEquals(3, collection.count(filter = BsonDocument("""{"name": "object-1"}"""))) + assertEquals(1, collection.count(filter = BsonDocument("""{"name": "object-2"}"""))) + + // Upsert no match + collection.updateOne( + filter = BsonDocument("""{ "name": "object-3"}"""), + update = BsonDocument(""" { "name": "object-2", "_id" : ${Random.nextInt()}}"""), + upsert = true + ).let { (updated, upsertedId) -> + assertFalse(updated) + assertIs(upsertedId) + } + assertEquals(5, collection.count()) + assertEquals(2, collection.count(filter = BsonDocument("""{"name": "object-2"}"""))) + + // Upsert with match + collection.updateOne( + filter = BsonDocument(json = """{ "name": "object-2"}"""), + update = BsonDocument(""" { "name": "object-3"}"""), + upsert = true + ).let { (updated, upsertedId) -> + assertTrue(updated) + assertNull(upsertedId) + } + assertEquals(5, collection.count()) + assertEquals(1, collection.count(filter = BsonDocument("""{"name": "object-2"}"""))) + } + + @Test + fun updateOne_explicitTypes() = runBlocking { + val upsertWithoutMatch = collection.updateOne( + filter = BsonDocument("""{ "name": "object-3"}"""), + update = BsonDocument(""" { "name": "object-2", "_id" : ${Random.nextInt()}}"""), + upsert = true + ) + upsertWithoutMatch.let { (updated, upsertedId) -> + assertFalse(updated) + assertIs(upsertedId) + } + } + + @Test + fun updateOne_fails() = runBlocking { + assertFailsWithMessage("unknown top level operator: \$who.") { + collection.updateOne(filter = BsonDocument("\$who", 1), update = BsonDocument()) + } + } + + @Test + fun updateMany() = runBlocking { + assertEquals(0, collection.count()) + assertEquals( + 4, + collection.insertMany( + listOf( + CollectionDataType("x"), + CollectionDataType("x"), + CollectionDataType("y"), + CollectionDataType("z") + ) + ).size + ) + assertEquals(4, collection.count()) + // Update with no match + collection.updateMany( + filter = BsonDocument("""{"name": "NOMATCH"}"""), + update = BsonDocument("""{"name": "UPDATED"}"""), + ).let { (modifiedCount, upsertedId) -> + assertEquals(0L, modifiedCount) + assertNull(upsertedId) + } + assertEquals(0, collection.count(filter = BsonDocument("""{"name": "UPDATED"}"""))) + assertEquals(4, collection.count()) + + // Update with match + collection.updateMany( + filter = BsonDocument("""{ "name": "x"}"""), + update = BsonDocument("""{ "name": "UPDATED"}"""), + ).let { (modifiedCount, upsertedId) -> + assertEquals(2L, modifiedCount) + assertNull(upsertedId) + } + assertEquals(2, collection.count(filter = BsonDocument("""{"name": "UPDATED"}"""))) + assertEquals(4, collection.count()) + + // Upsert no match + collection.updateMany( + filter = BsonDocument("""{ "name": "NOMATCH"}"""), + update = BsonDocument(""" { "name": "UPSERTED", "_id" : ${Random.nextInt()}}"""), + upsert = true + ).let { (modifiedCount, upsertedId) -> + assertEquals(0L, modifiedCount) + assertIs(upsertedId) + } + assertEquals(5, collection.count()) + assertEquals(1, collection.count(filter = BsonDocument("""{"name": "UPSERTED"}"""))) + + // Upsert with match + collection.updateMany( + filter = BsonDocument("""{ "name": "y"}"""), + update = BsonDocument(""" { "name": "z"}"""), upsert = true + ).let { (modifiedCount, upsertedId) -> + assertEquals(1L, modifiedCount) + assertNull(upsertedId) + } + assertEquals(5, collection.count()) + assertEquals(0, collection.count(filter = BsonDocument("""{"name": "y"}"""))) + } + + @Test + fun updateMany_explicitTypes() = runBlocking { + collection.updateMany( + filter = BsonDocument("""{ "name": "object-3"}"""), + update = BsonDocument(""" { "name": "object-2", "_id" : ${Random.nextInt()}}"""), + upsert = true + ).let { (modifiedCount, upsertedId) -> + assertEquals(0, modifiedCount) + assertIs(upsertedId) + } + } + + @Test + fun updateMany_fails() = runBlocking { + assertFailsWithMessage("Unknown modifier: \$who") { + collection.updateOne(filter = BsonDocument(), update = BsonDocument("\$who", 1)) + } + } + + @Test + fun findOneAndUpdate() = runBlocking { + assertNull(collection.findOneAndUpdate(filter = BsonDocument(), update = BsonDocument())) + + val names = (1..10).map { "object-${it % 5}" } + val ids: List = collection.insertMany(names.map { CollectionDataType(it) }) + + // Update with no match + assertNull( + collection.findOneAndUpdate( + filter = BsonDocument("""{"name": "NOMATCH"}"""), + update = BsonDocument("""{"name": "UPDATED"}"""), + ) + ) + assertEquals(0, collection.count(filter = BsonDocument("""{"name": "UPDATED"}"""))) + + // Update with match - return old + collection.findOneAndUpdate( + filter = BsonDocument("""{ "name": "object-1"}"""), + update = BsonDocument("""{ "name": "UPDATED"}"""), + )!!.let { + assertEquals("object-1", it.name) + } + assertEquals(1, collection.count(filter = BsonDocument("""{"name": "UPDATED"}"""))) + // Update with match - return new + collection.findOneAndUpdate( + filter = BsonDocument("""{ "name": "object-1"}"""), + update = BsonDocument("""{ "name": "UPDATED"}"""), + returnNewDoc = true + )!!.let { + assertEquals("UPDATED", it.name) + } + assertEquals(2, collection.count(filter = BsonDocument("""{"name": "UPDATED"}"""))) + + // Upsert no match + assertNull( + collection.findOneAndUpdate( + filter = BsonDocument("""{ "name": "NOMATCH"}"""), + update = BsonDocument(""" { "name": "UPSERTED", "_id" : ${Random.nextInt()}}"""), + upsert = true, + ) + ) + // Upsert no match - return new document + collection.findOneAndUpdate( + filter = BsonDocument("""{ "name": "NOMATCH"}"""), + update = BsonDocument(""" { "name": "UPSERTED", "_id" : ${Random.nextInt()}}"""), + upsert = true, + returnNewDoc = true, + )!!.let { + assertEquals("UPSERTED", it.name) + } + + // Upsert with match + collection.findOneAndUpdate( + filter = BsonDocument("""{ "name": "object-2"}"""), + update = BsonDocument(""" { "name": "UPSERTED" }"""), + upsert = true, + )!!.let { + assertEquals("object-2", it.name) + } + collection.findOneAndUpdate( + filter = BsonDocument("""{ "name": "object-2"}"""), + update = BsonDocument(""" { "name": "UPSERTED"}"""), + upsert = true, + returnNewDoc = true, + )!!.let { + assertEquals("UPSERTED", it.name) + } + + // Project without name + collection.findOneAndUpdate( + filter = BsonDocument("name", "object-3"), + update = BsonDocument(""" { "name": "UPDATED"}"""), + projection = BsonDocument("""{ "name" : 0}""") + )!!.run { + assertEquals("Default", this.name) + // _id is included by default and matched one of the previously inserted objects + assertTrue { this._id in ids } + } + // Project without _id, have to be explicitly excluded + collection.findOneAndUpdate( + filter = BsonDocument("name", "object-3"), + update = BsonDocument(""" { "name": "UPDATED"}"""), + projection = BsonDocument("""{ "_id" : 0}""") + )!!.run { + assertEquals("object-3", name) + // We don't know the id as the constructor default generated a new one + assertFalse { this._id in ids } + } + + // Sort + val sortedNames: List = collection.find().map { it.name }.sorted() + collection.findOneAndUpdate( + filter = BsonDocument(), + update = BsonDocument(""" { "name": "FIRST"}"""), + sort = BsonDocument(mapOf("name" to BsonInt32(1))) + )!!.run { + assertEquals(sortedNames.first(), this.name) + } + collection.findOneAndUpdate( + filter = BsonDocument(), + update = BsonDocument(""" { "name": "LAST"}"""), + sort = BsonDocument(mapOf("name" to BsonInt32(-1))) + )!!.run { + assertEquals(sortedNames.last(), this.name) + } + } + + @OptIn(ExperimentalKBsonSerializerApi::class) + @Test + fun findOneAndUpdate_explicitTypes() = runBlocking { + collection.insertOne(CollectionDataType("object-1")) + + collection.withDocumentClass().findOneAndUpdate( + filter = BsonDocument("""{ "name": "object-1"}"""), + update = BsonDocument("""{ "name": "UPDATED"}"""), + )!!.let { + assertEquals("object-1", it.asDocument()["name"]!!.asString().value) + } + } + + @Test + fun findOneAndUpdate_fails() = runBlocking { + assertFailsWithMessage("Unknown modifier: \$who") { + collection.findOneAndUpdate(filter = BsonDocument(), update = BsonDocument("\$who", 1)) + } + } + + @Test + fun findOneAndReplace() = runBlocking { + assertNull(collection.findOneAndReplace(filter = BsonDocument(), document = BsonDocument())) + + val names = (1..10).map { "object-${it % 5}" } + val ids: List = collection.insertMany(names.map { CollectionDataType(it) }) + + // Replace with no match + assertNull( + collection.findOneAndReplace( + filter = BsonDocument("""{"name": "NOMATCH"}"""), + document = BsonDocument(""" { "name": "REPLACED", "_id" : ${Random.nextInt()}}"""), + ) + ) + assertEquals(0, collection.count(filter = BsonDocument("""{"name": "REPLACED"}"""))) + + // Replace with match - return old + collection.findOneAndReplace( + filter = BsonDocument("""{ "name": "object-1"}"""), + document = BsonDocument(""" { "name": "REPLACED"}"""), + )!!.let { + assertEquals("object-1", it.name) + } + assertEquals(1, collection.count(filter = BsonDocument("""{"name": "REPLACED"}"""))) + + // Replace with match - return new + collection.findOneAndReplace( + filter = BsonDocument("""{ "name": "object-1"}"""), + document = BsonDocument("""{ "name": "REPLACED"}"""), + returnNewDoc = true + )!!.let { + assertEquals("REPLACED", it.name) + } + assertEquals(2, collection.count(filter = BsonDocument("""{"name": "REPLACED"}"""))) + + // Upsert no match + assertNull( + collection.findOneAndReplace( + filter = BsonDocument("""{ "name": "NOMATCH"}"""), + document = BsonDocument(""" { "name": "UPSERTED", "_id" : ${Random.nextInt()}}"""), + upsert = true, + ) + ) + // Upsert no match - return new document + collection.findOneAndReplace( + filter = BsonDocument("""{ "name": "NOMATCH"}"""), + document = BsonDocument(""" { "name": "UPSERTED", "_id" : ${Random.nextInt()}}"""), + upsert = true, + returnNewDoc = true, + )!!.let { + assertEquals("UPSERTED", it.name) + } + + // Upsert with match + collection.findOneAndReplace( + filter = BsonDocument("""{ "name": "object-2"}"""), + document = BsonDocument(""" { "name": "UPSERTED" }"""), + upsert = true, + )!!.let { + assertEquals("object-2", it.name) + } + collection.findOneAndReplace( + filter = BsonDocument("""{ "name": "object-2"}"""), + document = BsonDocument(""" { "name": "UPSERTED"}"""), + upsert = true, + returnNewDoc = true, + )!!.let { + assertEquals("UPSERTED", it.name) + } + + // Project without name + collection.findOneAndReplace( + filter = BsonDocument("name", "object-3"), + document = BsonDocument(""" { "name": "REPLACED"}"""), + projection = BsonDocument("""{ "name" : 0}""") + )!!.run { + assertEquals("Default", this.name) + // _id is included by default and matched one of the previously inserted objects + assertTrue { this._id in ids } + } + // Project without _id, have to be explicitly excluded + collection.findOneAndReplace( + filter = BsonDocument("name", "object-3"), + document = BsonDocument(""" { "name": "REPLACED"}"""), + projection = BsonDocument("""{ "_id" : 0}""") + )!!.run { + assertEquals("object-3", name) + // We don't know the id as the constructor default generated a new one + assertFalse { this._id in ids } + } + + // Sort + val sortedNames: List = collection.find().map { it.name!! }.sorted() + collection.findOneAndReplace( + filter = BsonDocument(), + document = BsonDocument(""" { "name": "FIRST"}"""), + sort = BsonDocument(mapOf("name" to BsonInt32(1))) + )!!.run { + assertEquals(sortedNames.first(), this.name) + } + collection.findOneAndReplace( + filter = BsonDocument(), + document = BsonDocument(""" { "name": "LAST"}"""), + sort = BsonDocument(mapOf("name" to BsonInt32(-1))) + )!!.run { + assertEquals(sortedNames.last(), this.name) + } + } + + @OptIn(ExperimentalKBsonSerializerApi::class) + @Test + fun findOneAndReplace_explicitTypes() = runBlocking { + collection.insertOne(CollectionDataType("object-1")) + + collection.withDocumentClass().findOneAndReplace( + filter = BsonDocument("""{ "name": "object-1"}"""), + document = BsonDocument("""{ "name": "REPLACED"}"""), + )!!.let { + assertEquals("object-1", it.asDocument()["name"]!!.asString().value) + } + } + + @Test + fun findOneAndReplace_fails() = runBlocking { + assertFailsWithMessage("the replace operation document must not contain atomic operators") { + collection.findOneAndReplace( + filter = BsonDocument(), + document = BsonDocument("\$who", 1) + ) + } + } + + @Test + fun findOneAndDelete() = runBlocking { + assertNull(collection.findOneAndDelete(filter = BsonDocument(), projection = BsonDocument())) + + val names = (1..10).map { "object-${it % 5}" } + val ids: List = collection.insertMany(names.map { CollectionDataType(it) }) + + // Delete with no match + assertNull(collection.findOneAndDelete(filter = BsonDocument("""{"name": "NOMATCH"}"""))) + assertEquals(10, collection.count(filter = BsonDocument())) + + // Delete with match + collection.findOneAndDelete( + filter = BsonDocument("""{ "name": "object-1"}"""), + )!!.let { + assertEquals("object-1", it.name) + } + assertEquals(9, collection.count(filter = BsonDocument())) + + // Project without name + collection.findOneAndDelete( + filter = BsonDocument("name", "object-3"), + projection = BsonDocument("""{ "name" : 0}""") + )!!.run { + assertEquals("Default", this.name) + // _id is included by default and matched one of the previously inserted objects + assertTrue { this._id in ids } + } + // Project without _id, have to be explicitly excluded + collection.findOneAndDelete( + filter = BsonDocument("name", "object-3"), + projection = BsonDocument("""{ "_id" : 0}""") + )!!.run { + assertEquals("object-3", name) + // We don't know the id as the constructor default generated a new one + assertFalse { this._id in ids } + } + + // Sort + val sortedNames: List = collection.find().map { it.name!! }.sorted() + collection.findOneAndDelete( + filter = BsonDocument(), + sort = BsonDocument(mapOf("name" to BsonInt32(1))) + )!!.run { + assertEquals(sortedNames.first(), this.name) + } + collection.findOneAndDelete( + filter = BsonDocument(), + sort = BsonDocument(mapOf("name" to BsonInt32(-1))) + )!!.run { + assertEquals(sortedNames.last(), this.name) + } + } + + @OptIn(ExperimentalKBsonSerializerApi::class) + @Test + fun findOneAndDelete_explicitTypes() = runBlocking { + collection.insertOne(CollectionDataType("object-1")) + + collection.withDocumentClass().findOneAndDelete( + filter = BsonDocument("""{ "name": "object-1"}"""), + )!!.let { + assertEquals("object-1", it.asDocument()["name"]!!.asString().value) + } + } + + @Test + fun findOneAndDelete_fails() = runBlocking { + assertFailsWithMessage("unknown top level operator: \$who.") { + collection.findOneAndDelete(filter = BsonDocument("\$who", 1)) + } + } + + @Test + fun throwsOnLoggedOutUser() = runBlocking { + user.logOut() + assertFailsWithMessage("unauthorized") { + collection.findOne() + } + } +} + +// Helper method to be able to differentiate collection creation across test classes +@OptIn(ExperimentalKBsonSerializerApi::class) +inline fun MongoCollectionTests.collection(eJson: EJson? = null): MongoCollection { + return when (this) { + is MongoCollectionFromDatabaseTests -> database.collection(T::class.simpleName!!, eJson) + is MongoCollectionFromClientTests -> client.collection(eJson) + } +} + +// Helper method to easy BsonDocument construction from Kotlin types and avoid BsonValue wrappers. +@Suppress("name") +@OptIn(ExperimentalKBsonSerializerApi::class) +inline operator fun BsonDocument.Companion.invoke( + key: String, + value: T, +): BsonDocument { + return BsonDocument(key to EJson.Default.encodeToBsonValue(value)) +} + +// Class that is unknown to the server. Should never be inserted as the server would then +// automatically create the collection. +@Serializable +class NonSchemaType : RealmObject { + var name = "Unknown" +} + +// Distinct data type with same fields as the above CollectionDataType used to showcase injection +// of custom serializers. +@PersistedName("CollectionDataType") +class CustomDataType(var name: String, var _id: Int = Random.nextInt()) : RealmObject { + @Suppress("unused") + constructor() : this("Default") +} + +// Custom serializers to showcase that we can inject serializers throughout the MongoClient APIs. +class CustomDataTypeSerializer : KSerializer { + + val serializer = BsonValue.serializer() + override val descriptor: SerialDescriptor = serializer.descriptor + override fun deserialize(decoder: Decoder): CustomDataType { + return decoder.decodeSerializableValue(serializer).let { + val _id = it.asDocument()["_id"]!!.asInt32().value + val name = it.asDocument()["name"]!!.asString().value + CustomDataType(name, _id) + } + } + + override fun serialize(encoder: Encoder, value: CustomDataType) { + val document = BsonDocument() + document["_id"] = BsonInt32(value._id) + document["name"] = BsonString(value.name) + encoder.encodeSerializableValue(serializer, document) + } +} + +@OptIn(ExperimentalKBsonSerializerApi::class) +val customEjsonSerializer = EJson( + serializersModule = SerializersModule { + contextual(CustomDataType::class, CustomDataTypeSerializer()) + } +) diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/mongo/MongoDBSerializerTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/mongo/MongoDBSerializerTests.kt new file mode 100644 index 0000000000..c7311fc5b3 --- /dev/null +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/mongo/MongoDBSerializerTests.kt @@ -0,0 +1,568 @@ +/* + * Copyright 2024 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:OptIn(ExperimentalKBsonSerializerApi::class) + +package io.realm.kotlin.test.mongodb.common.mongo + +import io.realm.kotlin.entities.sync.SyncObjectWithAllTypes +import io.realm.kotlin.entities.sync.flx.FlexEmbeddedObject +import io.realm.kotlin.entities.sync.flx.FlexParentObject +import io.realm.kotlin.ext.asRealmObject +import io.realm.kotlin.ext.realmAnyDictionaryOf +import io.realm.kotlin.ext.realmAnyListOf +import io.realm.kotlin.ext.realmDictionaryOf +import io.realm.kotlin.ext.realmListOf +import io.realm.kotlin.ext.realmSetOf +import io.realm.kotlin.mongodb.mongo.realmSerializerModule +import io.realm.kotlin.test.mongodb.common.utils.assertFailsWithMessage +import io.realm.kotlin.types.RealmInstant +import io.realm.kotlin.types.RealmUUID +import kotlinx.serialization.SerializationException +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import org.mongodb.kbson.ObjectId +import org.mongodb.kbson.serialization.EJson +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertContentEquals +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith + +class MongoDBSerializerTests { + + lateinit var eJson: EJson + + @BeforeTest + fun setUp() { + @Suppress("invisible_member") + eJson = EJson( + serializersModule = realmSerializerModule( + setOf( + SyncObjectWithAllTypes::class, + FlexParentObject::class, + FlexEmbeddedObject::class + ) + ) + ) + } + + @Test + fun serialize() { + assertEqualWithoutWhitespace(EXPECTED_EJSON, eJson.encodeToString(syncObjectWithAllTypes)) + } + + @Test + fun serialize_embeddedObject() { + assertEqualWithoutWhitespace( + EXPECTED_EJSON_EMBEDDED, + eJson.encodeToString(syncObjectWithEmbeddedObject) + ) + } + + @Test + fun deserialize() { + val actual = eJson.decodeFromString(EXPECTED_EJSON) + with(actual) { + // Verify all different types + assertEquals(syncObjectWithAllTypes._id, _id) + assertEquals(syncObjectWithAllTypes.stringField, stringField) + assertEquals(syncObjectWithAllTypes.byteField, byteField) + assertEquals(syncObjectWithAllTypes.charField, charField) + assertEquals(syncObjectWithAllTypes.shortField, shortField) + assertEquals(syncObjectWithAllTypes.intField, intField) + assertEquals(syncObjectWithAllTypes.longField, longField) + assertEquals(syncObjectWithAllTypes.booleanField, booleanField) + assertEquals(syncObjectWithAllTypes.doubleField, doubleField) + assertEquals(syncObjectWithAllTypes.floatField, floatField) + assertEquals(syncObjectWithAllTypes.decimal128Field, decimal128Field) + assertEquals(syncObjectWithAllTypes.realmInstantField, realmInstantField) + assertContentEquals(syncObjectWithAllTypes.binaryField, binaryField) + assertEquals(syncObjectWithAllTypes.mutableRealmIntField, mutableRealmIntField) + assertEquals(syncObjectWithAllTypes.objectField!!._id, objectField!!._id) + assertEquals(syncObjectWithAllTypes.objectIdField, objectIdField) + assertEquals(syncObjectWithAllTypes.realmUUIDField, realmUUIDField) + assertEquals(syncObjectWithAllTypes.realmInstantField, realmInstantField) + // Verify RealmAny with nested lists and dictionaries + nullableRealmAnyField!!.asList().let { + val expectedRealmAnyList = syncObjectWithAllTypes.nullableRealmAnyField!!.asList() + assertEquals(expectedRealmAnyList.size, it.size) + assertEquals( + expectedRealmAnyList[0]!!.asRealmObject()._id, + it[0]!!.asRealmObject()._id + ) + // Nested list + val expectedNestedList = expectedRealmAnyList[1]!!.asList() + val actualNestList = it[1]!!.asList() + assertEquals(expectedNestedList.size, actualNestList.size) + assertEquals(expectedNestedList[0], actualNestList[0]) + assertEquals(expectedNestedList[1], actualNestList[1]) + assertEquals( + expectedNestedList[2]!!.asRealmObject()._id, + actualNestList[2]!!.asRealmObject()._id + ) + // Nested dictionary + val expectedNestedDictionary = expectedRealmAnyList[2]!!.asDictionary() + val actualNestDictionary = it[2]!!.asDictionary() + assertEquals(expectedNestedDictionary.size, actualNestDictionary.size) + assertEquals(expectedNestedDictionary["int"], actualNestDictionary["int"]) + assertEquals(expectedNestedDictionary["string"], actualNestDictionary["string"]) + assertEquals( + expectedNestedDictionary["object"]!!.asRealmObject()._id, + actualNestDictionary["object"]!!.asRealmObject()._id + ) + } + // Smoke test collection fields. Assume that type specific details are verified by the above + // tests + assertEquals(syncObjectWithAllTypes.stringRealmList, stringRealmList) + assertEquals(syncObjectWithAllTypes.stringRealmSet, stringRealmSet) + assertEquals(syncObjectWithAllTypes.stringRealmDictionary, stringRealmDictionary) + } + } + + @Test + fun deserialize_embeddedObject() { + val actual = eJson.decodeFromString(EXPECTED_EJSON_EMBEDDED) + with(actual) { + assertEquals(syncObjectWithEmbeddedObject._id, _id) + assertEquals(syncObjectWithEmbeddedObject.embedded!!.embeddedName, embedded!!.embeddedName) + } + } + + @Test + fun deserialize_defaults() { + eJson.decodeFromString("{}") + } + + @Test + fun deserialize_throwsOnMalformedJSON() { + assertFailsWith { + eJson.decodeFromString("""{ "missing_value" : }""") + } + } + + @Test + fun deserialize_throwsOnUnknownField() { + assertFailsWithMessage("Unknown field 'unknown_field' for type SyncObjectWithAllTypes") { + eJson.decodeFromString("""{ "unknown_field": 1 }""") + } + } + + @Test + fun deserialize_unknownClassRefIsTreatedAsEmbeddedDict() { + val o = eJson.decodeFromString("""{ "nullableRealmAnyField": { "${"$"}ref": "unknown_class" } }""") + assertEquals("unknown_class", o.nullableRealmAnyField!!.asDictionary()["${"$"}ref"]!!.asString()) + } + @Test + fun deserialize_missingIdIsTreatedAsEmbeddedDict() { + val o = eJson.decodeFromString( + """ + { "nullableRealmAnyField": { "${"$"}ref" : "SyncObjectWithAllTyped", "unknown_field" : "UNKNOWN" } } + """.trimIndent() + ) + val realmAnyDictionary = o.nullableRealmAnyField!!.asDictionary() + assertEquals("SyncObjectWithAllTyped", realmAnyDictionary["${"$"}ref"]!!.asString()) + assertEquals("UNKNOWN", realmAnyDictionary["unknown_field"]!!.asString()) + } +} + +private fun assertEqualWithoutWhitespace(a: String, b: String) { + assertEquals(a.replace("\\s+".toRegex(), ""), b.replace("\\s+".toRegex(), "")) +} + +// Ensure test is reproducible by clearing random/time dependant values +// EJSON cannot represent nano second precision, so nanosecond fraction must be 0 +private val date = RealmInstant.from(172, 0) +private val objectId = ObjectId(byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)) +private val uuid = RealmUUID.Companion.from(byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)) +private val child = SyncObjectWithAllTypes().apply { _id = "CHILD" } + +private val syncObjectWithAllTypes: SyncObjectWithAllTypes = SyncObjectWithAllTypes().apply { + + _id = "PARENT" + realmInstantField = date + objectIdField = objectId + objectIdRealmList = realmListOf(objectId) + objectIdRealmSet = realmSetOf(objectId) + objectIdRealmDictionary = realmDictionaryOf("key" to objectId) + realmUUIDField = uuid + realmUUIDRealmList = realmListOf(uuid) + realmUUIDRealmSet = realmSetOf(uuid) + realmUUIDRealmDictionary = realmDictionaryOf("key" to uuid) + objectField = child + nullableRealmAnyField = realmAnyListOf( + child, + realmAnyListOf(1, "Realm", child), + realmAnyDictionaryOf("int" to 1, "string" to "Realm", "object" to child) + ) +} + +private val EXPECTED_EJSON_EMBEDDED = """ + {"_id":{"${"$"}oid":"000102030405060708090a0b"},"section":{"${"$"}numberInt":"0"},"name":"","age":{"${"$"}numberInt":"42"},"child":null,"embedded":{"embeddedName":"EMBEDDED"}} +""" + +private val syncObjectWithEmbeddedObject = FlexParentObject().apply { + _id = objectId + embedded = FlexEmbeddedObject().apply { + embeddedName = "EMBEDDED" + } +} + +private val EXPECTED_EJSON = """ +{ + "_id":"PARENT", + "stringField":"hello world", + "byteField":{ + "${"$"}numberInt":"0" + }, + "charField":{ + "${"$"}numberInt":"0" + }, + "shortField":{ + "${"$"}numberInt":"0" + }, + "intField":{ + "${"$"}numberInt":"0" + }, + "longField":{ + "${"$"}numberLong":"0" + }, + "booleanField":true, + "doubleField":{ + "${"$"}numberDouble":"0.0" + }, + "floatField":{ + "${"$"}numberDouble":"0.0" + }, + "decimal128Field":{ + "${"$"}numberDecimal":"0" + }, + "realmInstantField":{ + "${"$"}date":{ + "${"$"}numberLong":"172000" + } + }, + "objectIdField":{ + "${"$"}oid":"000102030405060708090a0b" + }, + "realmUUIDField":{ + "${"$"}binary":{ + "base64":"AAECAwQFBgcICQoLDA0ODw==", + "subType":"04" + } + }, + "binaryField":{ + "${"$"}binary":{ + "base64":"Kg==", + "subType":"00" + } + }, + "mutableRealmIntField":{ + "${"$"}numberLong":"42" + }, + "objectField":"CHILD", + "stringNullableField":null, + "byteNullableField":null, + "charNullableField":null, + "shortNullableField":null, + "intNullableField":null, + "longNullableField":null, + "booleanNullableField":null, + "doubleNullableField":null, + "floatNullableField":null, + "decimal128NullableField":null, + "realmInstantNullableField":null, + "objectIdNullableField":null, + "realmUUIDNullableField":null, + "binaryNullableField":null, + "objectNullableField":null, + "mutableRealmIntNullableField":null, + "nullableRealmAnyField":[ + { + "${"$"}ref":"SyncObjectWithAllTypes", + "${"$"}id":"CHILD" + }, + [ + { + "${"$"}numberLong":"1" + }, + "Realm", + { + "${"$"}ref":"SyncObjectWithAllTypes", + "${"$"}id":"CHILD" + } + ], + { + "int":{ + "${"$"}numberLong":"1" + }, + "string":"Realm", + "object":{ + "${"$"}ref":"SyncObjectWithAllTypes", + "${"$"}id":"CHILD" + } + } + ], + "nullableRealmAnyForObjectField":null, + "stringRealmList":[ + "hello world" + ], + "byteRealmList":[ + { + "${"$"}numberInt":"0" + } + ], + "charRealmList":[ + { + "${"$"}numberInt":"0" + } + ], + "shortRealmList":[ + { + "${"$"}numberInt":"0" + } + ], + "intRealmList":[ + { + "${"$"}numberInt":"0" + } + ], + "longRealmList":[ + { + "${"$"}numberLong":"0" + } + ], + "booleanRealmList":[ + true + ], + "doubleRealmList":[ + { + "${"$"}numberDouble":"0.0" + } + ], + "floatRealmList":[ + { + "${"$"}numberDouble":"0.0" + } + ], + "decimal128RealmList":[ + { + "${"$"}numberDecimal":"0.0" + } + ], + "realmInstantRealmList":[ + { + "${"$"}date":{ + "${"$"}numberLong":"-9223372036854775808" + } + } + ], + "objectIdRealmList":[ + { + "${"$"}oid":"000102030405060708090a0b" + } + ], + "realmUUIDRealmList":[ + { + "${"$"}binary":{ + "base64":"AAECAwQFBgcICQoLDA0ODw==", + "subType":"04" + } + } + ], + "binaryRealmList":[ + { + "${"$"}binary":{ + "base64":"Kg==", + "subType":"00" + } + } + ], + "objectRealmList":[ + + ], + "nullableRealmAnyRealmList":[ + { + "${"$"}numberLong":"42" + } + ], + "stringRealmSet":[ + "hello world" + ], + "byteRealmSet":[ + { + "${"$"}numberInt":"0" + } + ], + "charRealmSet":[ + { + "${"$"}numberInt":"0" + } + ], + "shortRealmSet":[ + { + "${"$"}numberInt":"0" + } + ], + "intRealmSet":[ + { + "${"$"}numberInt":"0" + } + ], + "longRealmSet":[ + { + "${"$"}numberLong":"0" + } + ], + "booleanRealmSet":[ + true + ], + "doubleRealmSet":[ + { + "${"$"}numberDouble":"0.0" + } + ], + "floatRealmSet":[ + { + "${"$"}numberDouble":"0.0" + } + ], + "decimal128RealmSet":[ + { + "${"$"}numberDecimal":"0.0" + } + ], + "realmInstantRealmSet":[ + { + "${"$"}date":{ + "${"$"}numberLong":"-9223372036854775808" + } + } + ], + "objectIdRealmSet":[ + { + "${"$"}oid":"000102030405060708090a0b" + } + ], + "realmUUIDRealmSet":[ + { + "${"$"}binary":{ + "base64":"AAECAwQFBgcICQoLDA0ODw==", + "subType":"04" + } + } + ], + "binaryRealmSet":[ + { + "${"$"}binary":{ + "base64":"Kg==", + "subType":"00" + } + } + ], + "objectRealmSet":[ + + ], + "nullableRealmAnyRealmSet":[ + { + "${"$"}numberLong":"42" + } + ], + "stringRealmDictionary":{ + "A":"hello world" + }, + "byteRealmDictionary":{ + "A":{ + "${"$"}numberInt":"0" + } + }, + "charRealmDictionary":{ + "A":{ + "${"$"}numberInt":"0" + } + }, + "shortRealmDictionary":{ + "A":{ + "${"$"}numberInt":"0" + } + }, + "intRealmDictionary":{ + "A":{ + "${"$"}numberInt":"0" + } + }, + "longRealmDictionary":{ + "A":{ + "${"$"}numberLong":"0" + } + }, + "booleanRealmDictionary":{ + "A":true + }, + "doubleRealmDictionary":{ + "A":{ + "${"$"}numberDouble":"0.0" + } + }, + "floatRealmDictionary":{ + "A":{ + "${"$"}numberDouble":"0.0" + } + }, + "decimal128RealmDictionary":{ + "A":{ + "${"$"}numberDecimal":"0.0" + } + }, + "realmInstantRealmDictionary":{ + "A":{ + "${"$"}date":{ + "${"$"}numberLong":"-9223372036854775808" + } + } + }, + "objectIdRealmDictionary":{ + "key":{ + "${"$"}oid":"000102030405060708090a0b" + } + }, + "realmUUIDRealmDictionary":{ + "key":{ + "${"$"}binary":{ + "base64":"AAECAwQFBgcICQoLDA0ODw==", + "subType":"04" + } + } + }, + "binaryRealmDictionary":{ + "A":{ + "${"$"}binary":{ + "base64":"Kg==", + "subType":"00" + } + } + }, + "nullableObjectRealmDictionary":{ + + }, + "nullableRealmAnyRealmDictionary":{ + "A":{ + "${"$"}numberLong":"42" + } + } +} +""".trimIndent() diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/mongo/MongoDatabaseTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/mongo/MongoDatabaseTests.kt new file mode 100644 index 0000000000..ed135800ed --- /dev/null +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/mongo/MongoDatabaseTests.kt @@ -0,0 +1,100 @@ +/* + * Copyright 2023 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.test.mongodb.common.mongo + +import io.realm.kotlin.entities.sync.CollectionDataType +import io.realm.kotlin.internal.platform.runBlocking +import io.realm.kotlin.mongodb.ext.insertOne +import io.realm.kotlin.mongodb.mongo.MongoClient +import io.realm.kotlin.mongodb.mongo.MongoDatabase +import io.realm.kotlin.test.mongodb.TEST_APP_FLEX +import io.realm.kotlin.test.mongodb.TestApp +import io.realm.kotlin.test.mongodb.common.utils.assertFailsWithMessage +import kotlinx.serialization.SerializationException +import org.mongodb.kbson.BsonDocument +import org.mongodb.kbson.BsonInt32 +import org.mongodb.kbson.BsonString +import org.mongodb.kbson.ExperimentalKBsonSerializerApi +import kotlin.random.Random +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertIs + +@OptIn(ExperimentalKBsonSerializerApi::class) +class MongoDatabaseTests { + + lateinit var app: TestApp + lateinit var client: MongoClient + lateinit var databaseName: String + lateinit var database: MongoDatabase + + @BeforeTest + fun setUp() { + app = TestApp( + this::class.simpleName, + appName = TEST_APP_FLEX, + ) + val user = app.createUserAndLogin() + client = user.mongoClient(TEST_SERVICE_NAME) + databaseName = app.clientAppId + database = client.database(databaseName) + } + + @AfterTest + fun teadDown() { + if (this::app.isInitialized) { + app.close() + } + } + + @Test + fun properties() { + assertEquals(databaseName, database.name) + } + + @Test + fun collection_defaultTypes() = runBlocking { + val collection = database.collection("CollectionDataType") + val value = collection.insertOne(BsonDocument("_id" to BsonInt32(Random.nextInt()), "name" to BsonString("object-1"))) + assertIs(value) + } + + @Test + fun collection_typed() = runBlocking { + val collection = database.collection("CollectionDataType") + val value = collection.insertOne(CollectionDataType("object-1", Random.nextInt())) + assertIs(value) + } + + @Test + fun collection_defaultSerializer() = runBlocking { + assertIs(database.collection("CollectionDataType").insertOne(CollectionDataType("object-1"))) + } + + @Test + fun collection_customSerializer() = runBlocking { + val collectionWithDefaultSerializer = database.collection("CollectionDataType") + assertFailsWithMessage("Serializer for class 'CustomDataType' is not found.") { + collectionWithDefaultSerializer.insertOne(CustomDataType("object-1")) + } + + val collectionWithCustomSerializer = database.collection("CollectionDataType", customEjsonSerializer) + assertIs(collectionWithCustomSerializer.insertOne(CustomDataType("object-1"))) + } +} diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/utils/Utils.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/utils/Utils.kt index 6714eb609c..8ac26c2ab8 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/utils/Utils.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/utils/Utils.kt @@ -17,10 +17,16 @@ package io.realm.kotlin.test.mongodb.common.utils import io.realm.kotlin.mongodb.sync.SubscriptionSet import io.realm.kotlin.mongodb.sync.SyncSession +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking import kotlin.reflect.KClass import kotlin.test.assertFailsWith import kotlin.test.assertTrue +import kotlin.test.fail +import kotlin.time.Duration import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds // NOTE: Copy from :base:commonTest. It is unclear if there is an easy way to share test code like // this between :base and :sync @@ -52,6 +58,13 @@ fun assertFailsWithMessage(exceptionClass: KClass, exceptionM inline fun assertFailsWithMessage(exceptionMessage: String, noinline block: () -> Unit): T = assertFailsWithMessage(T::class, exceptionMessage, block) +inline fun CoroutineScope.assertFailsWithMessage(exceptionMessage: String, noinline block: suspend CoroutineScope.() -> Unit): T = + assertFailsWithMessage(T::class, exceptionMessage) { + runBlocking(this.coroutineContext) { + block() + } + } + suspend inline fun SubscriptionSet<*>.waitForSynchronizationOrFail() { val timeout = 5.minutes assertTrue(this.waitForSynchronization(timeout), "Failed to synchronize subscriptions in time: $timeout") @@ -61,3 +74,16 @@ suspend inline fun SyncSession.uploadAllLocalChangesOrFail() { val timeout = 5.minutes assertTrue(this.uploadAllLocalChanges(timeout), "Failed to upload local changes in time: $timeout") } + +suspend fun retry(action: suspend () -> R?, until: (R?) -> Boolean, retries: Int = 5, delay: Duration = 1.seconds): R? { + repeat(retries) { + action().let { + if (until(it)) { + return it + } else { + delay(delay) + } + } + } + fail("Exceeded retries") +} diff --git a/packages/test-sync/src/jvmTest/kotlin/io/realm/kotlin/test/mongodb/jvm/FlexibleSyncSchemaTests.kt b/packages/test-sync/src/jvmTest/kotlin/io/realm/kotlin/test/mongodb/jvm/FlexibleSyncSchemaTests.kt new file mode 100644 index 0000000000..c5d73bc4a2 --- /dev/null +++ b/packages/test-sync/src/jvmTest/kotlin/io/realm/kotlin/test/mongodb/jvm/FlexibleSyncSchemaTests.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2024 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.test.mongodb.jvm + +import io.realm.kotlin.test.mongodb.common.FLEXIBLE_SYNC_SCHEMA +import io.realm.kotlin.test.mongodb.common.FLEXIBLE_SYNC_SCHEMA_COUNT +import io.realm.kotlin.types.RealmObject +import kotlin.reflect.full.isSubclassOf +import kotlin.test.Test +import kotlin.test.assertEquals + +class FlexibleSyncSchemaTests { + + @Test + fun flexibleSyncSchemaCount() { + assertEquals( + FLEXIBLE_SYNC_SCHEMA_COUNT, + FLEXIBLE_SYNC_SCHEMA.filter { it.isSubclassOf(RealmObject::class) }.size + ) + } +}