Coverage Summary for Class: Ghost (com.ghost.serialization)

Class Method, % Branch, % Line, % Instruction, %
Ghost 66.7% (34/51) 69.2% (90/130) 69.7% (147/211) 71.8% (735/1023)
Ghost$deserialize$$inlined$resolveSerializer$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$deserialize$$inlined$resolveSerializer$2 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$deserialize$$inlined$resolveSerializer$3 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$deserialize$1 100% (1/1) 100% (1/1) 100% (4/4)
Ghost$deserialize$1$invoke$$inlined$deserialize$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$deserialize$3 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$deserialize$3$invoke$$inlined$deserialize$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$deserialize$4 100% (1/1) 100% (1/1) 100% (4/4)
Ghost$deserialize$4$invoke$$inlined$deserialize$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$deserialize$6 100% (1/1) 100% (2/2) 100% (9/9)
Ghost$deserialize$6$invoke$$inlined$deserialize$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$deserialize$7 0% (0/1) 0% (0/2) 0% (0/9)
Ghost$deserialize$7$invoke$$inlined$deserialize$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$deserialize$8 100% (1/1) 100% (2/2) 100% (9/9)
Ghost$deserialize$8$invoke$$inlined$deserialize$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$deserializeStreaming$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$deserializeStreaming$1$invoke$$inlined$deserialize$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$encodeAndDiscard$$inlined$resolveSerializer$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$encodeToBytes$$inlined$resolveSerializer$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$encodeToSink$$inlined$serialize$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$encodeToString$$inlined$resolveSerializer$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$resolveSerializer$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$serialize$$inlined$encodeToString$1 0% (0/1) 0% (0/1) 0% (0/4)
Ghost$serialize$$inlined$resolveSerializer$1 0% (0/1) 0% (0/1) 0% (0/4)
Total 50.7% (38/75) 69.2% (90/130) 64.3% (153/238) 67.1% (761/1134)


 @file:Suppress("UNCHECKED_CAST", "OPT_IN_USAGE")
 
 package com.ghost.serialization
 
 import com.ghost.serialization.contract.GhostRegistry
 import com.ghost.serialization.contract.GhostSerializer
 import com.ghost.serialization.exception.GhostJsonException
 import com.ghost.serialization.parser.GhostJsonFlatReader
 import com.ghost.serialization.parser.GhostJsonReader
 import com.ghost.serialization.parser.GhostJsonStringReader
 import com.ghost.serialization.serializers.BooleanSerializer
 import com.ghost.serialization.serializers.ByteSerializer
 import com.ghost.serialization.serializers.CharSerializer
 import com.ghost.serialization.serializers.DoubleSerializer
 import com.ghost.serialization.serializers.FloatSerializer
 import com.ghost.serialization.serializers.IntSerializer
 import com.ghost.serialization.serializers.ListSerializer
 import com.ghost.serialization.serializers.LongSerializer
 import com.ghost.serialization.serializers.MapSerializer
 import com.ghost.serialization.serializers.SetSerializer
 import com.ghost.serialization.serializers.ShortSerializer
 import com.ghost.serialization.serializers.StringSerializer
 import com.ghost.serialization.types.RawJson
 import com.ghost.serialization.types.RawJsonSerializer
 import com.ghost.serialization.writer.GhostJsonFlatWriter
 import com.ghost.serialization.writer.GhostJsonStringWriter
 import okio.BufferedSink
 import okio.BufferedSource
 import kotlin.reflect.KClass
 import kotlin.reflect.KType
 import kotlin.reflect.typeOf
 
 /**
  * Platform synchronization primitive.
  */
 expect fun <T> runSynchronized(lock: Any, block: () -> T): T
 
 /**
  * Platform-specific thread-safe atomic map creation.
  */
 expect fun <K, V> createAtomicMap(): MutableMap<K, V>
 
 /**
  * Service loader or reflection based module discovery mechanism.
  */
 expect fun discoverRegistries(): Iterable<GhostRegistry>
 
 /**
  * Runs a block of operations using a pooled [GhostJsonReader] instance.
  */
 @OptIn(InternalGhostApi::class)
 expect fun <T> ghostInternalUseReader(bytes: ByteArray, block: (GhostJsonReader) -> T): T
 
 /**
  * Runs a block of operations using a pooled [GhostJsonStringReader] instance.
  */
 @OptIn(InternalGhostApi::class)
 expect fun <T> ghostInternalUseStringReader(json: String, block: (GhostJsonStringReader) -> T): T
 
 /**
  * Runs a block of operations using a pooled [GhostJsonFlatReader] instance.
  */
 @OptIn(InternalGhostApi::class)
 expect fun <T> ghostInternalUseFlatReader(bytes: ByteArray, limit: Int = bytes.size, block: (GhostJsonFlatReader) -> T): T
 
 /**
  * Runs a block of operations using a pooled [GhostJsonReader] reading from an Okio [BufferedSource].
  */
 @OptIn(InternalGhostApi::class)
 expect fun <T> ghostInternalUseSource(source: BufferedSource, block: (GhostJsonReader) -> T): T
 
 /**
  * Encodes via the pooled in-memory [GhostJsonStringWriter] and returns the
  * result as a [String]. The string writer holds a contiguous [CharArray]
  * (no Okio segments), so the returned string is decoded directly from
  * the produced char slice with minimal allocations.
  */
 @InternalGhostApi
 expect inline fun ghostInternalEncodeToString(crossinline block: (GhostJsonStringWriter) -> Unit): String
 
 /**
  * Pools the in-memory [GhostJsonFlatWriter] per-thread and returns the
  * encoded bytes. Use this when you need a [ByteArray] result without the
  * overhead of going through [String].
  *
  * The writer is reset (`needsComma=false, depth=0`) before each call; its
  * scratch buffer is kept warm (not released) to avoid pool round-trips
  * between requests.
  */
 @InternalGhostApi
 expect inline fun ghostInternalEncodeWithWriter(crossinline block: (GhostJsonFlatWriter) -> Unit): ByteArray
 
 /**
  * Serializes via the pooled [GhostJsonFlatWriter] but discards the output
  * without allocating a result [ByteArray]. Useful for warm-up / JIT priming
  * where the encoded bytes are not needed.
  */
 @InternalGhostApi
 expect inline fun ghostInternalEncodeAndDiscard(crossinline block: (GhostJsonFlatWriter) -> Unit)
 
 /**
  * Encodes through the pooled [GhostJsonFlatWriter] and drains the resulting
  * contiguous payload to [sink] in a single bulk write. This is the fast path
  * for `Ghost.serialize(sink, value)` — every byte-level operation goes
  * through the monomorphic flat writer (no per-byte Okio segment dispatch),
  * and the final flush is a single [BufferedSink.write] call which Okio
  * implements as a few `System.arraycopy`s into its segment buffer.
  */
 @InternalGhostApi
 expect inline fun ghostInternalEncodeAndDrainTo(sink: BufferedSink, crossinline block: (GhostJsonFlatWriter) -> Unit)
 
 /**
  * Core entry point for Ghost Serialization.
  * Provides modular discovery and serialization management across platforms.
  */
 object Ghost {
 
     /**
      * Cache storing registered serializers keyed by their unique type name.
      * Used by the compiler for name-based lookup (e.g., in polymorphic serialization).
      */
     private val serializerByName = createAtomicMap<String, GhostSerializer<*>>()
 
     /**
      * Fast-path lock-free cache mapping a [KClass] to its corresponding [GhostSerializer].
      * Annotated with `@PublishedApi` because it is accessed by public inline functions on the hot path
      * to avoid lookup overhead.
      */
     @PublishedApi
     internal val serializerCache = createAtomicMap<KClass<*>, GhostSerializer<*>>()
 
     /**
      * Fast-path lock-free cache mapping a full [KType] (e.g., generic collections like `List<Int>`)
      * to its resolved [GhostSerializer].
      * Annotated with `@PublishedApi` because it is accessed by public inline functions.
      * Kept separate from [serializerCache] to prevent generic types from colliding on the same [KClass].
      */
     @PublishedApi
     internal val typeCache = createAtomicMap<KType, GhostSerializer<*>>()
 
     /**
      * Platform-independent lock object used to synchronize access to registries and cache updates.
      */
     private val lock = Any()
 
     /**
      * Set of manually registered [GhostRegistry] instances.
      * Critical for platforms where automated discovery (ServiceLoader/reflection) is unavailable (e.g., iOS, JS, Wasm).
      */
     private val mutableRegistries = mutableSetOf<GhostRegistry>()
 
     /**
      * Holds dynamically discovered [GhostRegistry] instances via ServiceLoader or reflection.
      * Lazily initialized to optimize startup time.
      */
     private var _discoveredRegistries: Iterable<GhostRegistry>? = null
 
     /**
      * Resolves a serializer for a given class from all registered modules.
      */
     private fun <T : Any> getSerializerFromRegistries(
         clazz: KClass<T>
     ): GhostSerializer<T>? {
         // 1. Check manual registries
         for (registry in mutableRegistries) {
             registry.getSerializer(clazz)?.let { return it }
         }
 
         // 2. Check discovered registries
         if (_discoveredRegistries == null) {
             _discoveredRegistries = discoverRegistries()
         }
         val disc = _discoveredRegistries!!
 
         for (registry in disc) {
             registry.getSerializer(clazz)?.let { return it }
         }
 
         return null
     }
 
     /**
      * Helper utility to raise a serialization-related exception.
      *
      * @param message The detailed error message.
      * @throws IllegalArgumentException always thrown with the specified message.
      */
     fun throwError(message: String): Nothing {
         throw IllegalArgumentException(message)
     }
 
     /**
      * Registers a new [GhostRegistry] manually.
      *
      * Manual registration is particularly critical on platforms like iOS (Kotlin/Native)
      * and JS/Wasm where automated discovery via ServiceLoader is unavailable.
      *
      * @param registry The registry instance containing the generated serializers to register.
      */
     fun addRegistry(registry: GhostRegistry) {
         runSynchronized(lock) {
             if (mutableRegistries.add(registry)) {
                 val serializers = registry.getAllSerializers()
                 for (entry in serializers) {
                     val kclass = entry.key
                     val serializer = entry.value
                     serializerCache[kclass] = serializer
                     serializerByName[serializer.typeName] = serializer
                 }
             }
         }
     }
 
     /**
      * Used by compiler to get serializers by name.
      */
     @Suppress("unused")
     fun getSerializerByName(name: String): GhostSerializer<*>? {
         return serializerByName[name]
     }
 
     /**
      * Internal: Used by compiler-generated code to verify registered serializers.
      */
     @Suppress("unused")
     fun getSerializerNames(): List<String> {
         return serializerByName.keys.toList()
     }
 
     /**
      * Resolves a [GhostSerializer] instance for the specified class [clazz].
      * Checks primitives first, then the fast-path cache, and falls back to
      * registered modules if necessary.
      *
      * @param clazz The [KClass] of the type to resolve the serializer for.
      * @return The matching [GhostSerializer], or `null` if no serializer is found.
      */
     public fun <T : Any> getSerializer(clazz: KClass<T>): GhostSerializer<T>? {
         // Fast path for primitives
         getPrimitiveSerializer(clazz)?.let { return it }
 
         // Atomic lookup (Lock-free on JVM/Android)
         val cached = serializerCache[clazz] as? GhostSerializer<T>
         if (cached != null) {
             return cached
         }
 
         return runSynchronized(lock) {
             val doubleCheck = serializerCache[clazz] as? GhostSerializer<T>
             if (doubleCheck != null) {
                 return@runSynchronized doubleCheck
             }
 
             val found = getSerializerFromRegistries(clazz)
             if (found != null) {
                 serializerCache[clazz] = found as GhostSerializer<Any>
             }
             found
         }
     }
 
     /**
      * Fast path serializer lookup for native primitive types.
      */
     private fun <T : Any> getPrimitiveSerializer(
         clazz: KClass<T>
     ): GhostSerializer<T>? {
         return when (clazz) {
             String::class -> {
                 StringSerializer as GhostSerializer<T>
             }
             Int::class -> {
                 IntSerializer as GhostSerializer<T>
             }
             Long::class -> {
                 LongSerializer as GhostSerializer<T>
             }
             Boolean::class -> {
                 BooleanSerializer as GhostSerializer<T>
             }
             Double::class -> {
                 DoubleSerializer as GhostSerializer<T>
             }
             Float::class -> {
                 FloatSerializer as GhostSerializer<T>
             }
             Byte::class -> {
                 ByteSerializer as GhostSerializer<T>
             }
             Short::class -> {
                 ShortSerializer as GhostSerializer<T>
             }
             Char::class -> {
                 CharSerializer as GhostSerializer<T>
             }
             RawJson::class -> {
                 RawJsonSerializer as GhostSerializer<T>
             }
             else -> {
                 null
             }
         }
     }
 
     /**
      * Resolves a [GhostSerializer] instance for the specified type [type],
      * handling generic type arguments for parameterized classes like lists and maps.
      *
      * @param type The [KType] representing the type of the data structure.
      * @return The matching [GhostSerializer], or `null` if no serializer is found.
      */
     fun getSerializer(type: KType): GhostSerializer<Any>? {
         val classifier = type.classifier
 
         // Special handling for parameterized collections
         if (classifier == List::class || classifier == Map::class || classifier == Set::class) {
             val cached = typeCache[type]
             if (cached != null) {
                 return cached as GhostSerializer<Any>
             }
 
             return runSynchronized(lock) {
                 val doubleCheck = typeCache[type]
                 if (doubleCheck != null) {
                     return@runSynchronized doubleCheck as GhostSerializer<Any>
                 }
 
                 val created = when (classifier) {
                     List::class -> {
                         val itemType = type.arguments.getOrNull(0)?.type
                             ?: return@runSynchronized null
 
                         val itemSerializer = getSerializer(itemType)
                             ?: return@runSynchronized null
 
                         ListSerializer(itemSerializer)
                     }
 
                     Set::class -> {
                         val itemType = type.arguments.getOrNull(0)?.type
                             ?: return@runSynchronized null
 
                         val itemSerializer = getSerializer(itemType)
                             ?: return@runSynchronized null
 
                         SetSerializer(itemSerializer)
                     }
 
                     Map::class -> {
                         val valueType = type.arguments.getOrNull(1)?.type
                             ?: return@runSynchronized null
 
                         val valueSerializer = getSerializer(valueType)
                             ?: return@runSynchronized null
 
                         MapSerializer(valueSerializer)
                     }
 
                     else -> {
                         null
                     }
                 }
 
                 if (created != null) {
                     typeCache[type] = created
                 }
 
                 created as? GhostSerializer<Any>
             }
         }
 
         // Delegate to class-based resolution (handles primitives and caching)
         val kClass = classifier as? KClass<Any> ?: return null
         return getSerializer(kClass)
     }
 
     /**
      * Internally resolves the serializer for dynamic type-checking or compile-time resolution.
      */
     @PublishedApi
     @Suppress("UNCHECKED_CAST")
     internal fun <T : Any> resolveSerializerByType(
         kClass: KClass<T>,
         typeProducer: () -> KType
     ): GhostSerializer<T> {
         // Fast path: serializerCache is populated at startup by addRegistry/prewarm.
         // Safe for all types that were registered as KClass → serializer mappings.
         (serializerCache[kClass] as? GhostSerializer<T>)?.let { return it }
         // Slow path (first call for this KType): getSerializer(KType) internally
         // caches the result in typeCache so subsequent calls are O(1).
         // No write to serializerCache here — generic types (List<T>, Map<K,V>)
         // share the same KClass and must NOT pollute that cache.
         val type = typeProducer()
         return (getSerializer(type) ?: getSerializer(kClass as KClass<Any>))
             as? GhostSerializer<T>
             ?: throwError("$NOT_FOUND $kClass. $MISSING_ANN")
     }
 
     /**
      * Resolves the serializer for the reified type parameter [T].
      */
     public inline fun <reified T : Any> resolveSerializer(): GhostSerializer<T> {
         val cached = serializerCache[T::class]
         if (cached != null) {
             return cached as GhostSerializer<T>
         }
         return resolveSerializerByType(T::class) { typeOf<T>() }
     }
 
     /**
      * Encodes [value] and writes the resulting JSON payload into [sink].
      *
      * Employs the zero-allocation [GhostJsonFlatWriter] internally to format the data
      * into a contiguous scratch buffer and flushes it in a single block write.
      * This avoids Okio segment management and virtual dispatch overhead on the hot path.
      *
      * @param sink The Okio sink to write the JSON payload to.
      * @param value The value to serialize.
      */
     inline fun <reified T : Any> serialize(sink: BufferedSink, value: T) {
         val serializer = resolveSerializer<T>()
         ghostInternalEncodeAndDrainTo(sink) { writer ->
             serializer.serialize(writer, value)
         }
     }
 
     /**
      * Encodes [value] and writes the resulting JSON payload into [sink] using a pre-resolved [serializer].
      *
      * Bypasses type lookup and resolution overhead.
      */
     fun <T : Any> serialize(serializer: GhostSerializer<T>, sink: BufferedSink, value: T) {
         ghostInternalEncodeAndDrainTo(sink) { writer ->
             serializer.serialize(writer, value)
         }
     }
 
     /**
      * Convenience alias for [encodeToString] to maintain compatibility with standard APIs.
      *
      * @param value The value to serialize.
      * @return The serialized JSON string.
      */
     inline fun <reified T : Any> serialize(value: T): String {
         return encodeToString(value)
     }
 
     /**
      * Serializes [value] to an in-memory JSON string representation.
      *
      * Bypasses Okio segment management by writing to a flat, contiguous byte buffer
      * and performing a zero-copy string decode at the end.
      *
      * @param value The value to serialize.
      * @return The serialized JSON string.
      */
     inline fun <reified T : Any> encodeToString(value: T): String {
         val serializer = resolveSerializer<T>()
         return ghostInternalEncodeToString { writer ->
             serializer.serialize(writer, value)
         }
     }
 
     /**
      * Serializes [value] to an in-memory JSON string representation using a pre-resolved [serializer].
      *
      * Bypasses type lookup and resolution overhead.
      */
     fun <T : Any> encodeToString(serializer: GhostSerializer<T>, value: T): String {
         return ghostInternalEncodeToString { writer ->
             serializer.serialize(writer, value)
         }
     }
 
     /**
      * Serializes [value] to an in-memory JSON byte array representation.
      *
      * Skips intermediate string formatting/decoding steps by exposing the raw
      * UTF-8 bytes directly.
      *
      * @param value The value to serialize.
      * @return A [ByteArray] containing the serialized JSON UTF-8 payload.
      */
     inline fun <reified T : Any> encodeToBytes(value: T): ByteArray {
         val serializer = resolveSerializer<T>()
         return ghostInternalEncodeWithWriter { writer ->
             serializer.serialize(writer, value)
         }
     }
 
     /**
      * Serializes [value] to an in-memory JSON byte array representation using a pre-resolved [serializer].
      *
      * Bypasses type lookup and resolution overhead.
      */
     fun <T : Any> encodeToBytes(serializer: GhostSerializer<T>, value: T): ByteArray {
         return ghostInternalEncodeWithWriter { writer ->
             serializer.serialize(writer, value)
         }
     }
 
     /**
      * Serializes [value] through the pooled [GhostJsonFlatWriter] and discards
      * the output. No [BufferedSink] allocation, no Okio wrapper objects.
      *
      * @param value The value to serialize.
      */
     @Suppress("unused")
     inline fun <reified T : Any> encodeAndDiscard(value: T) {
         val serializer = resolveSerializer<T>()
         ghostInternalEncodeAndDiscard { writer ->
             serializer.serialize(writer, value)
         }
     }
 
     // ── Public deserialize API ────────────
 
     /**
      * Deserializes the JSON [json] string into an instance of type [T].
      *
      * @param json The JSON string representation of the object.
      * @return A reconstructed instance of type [T].
      * @throws com.ghost.serialization.exception.GhostJsonException if the JSON payload is malformed or structure is invalid.
      */
     inline fun <reified T : Any> deserialize(json: String): T {
         return ghostInternalUseStringReader(json) { reader ->
             deserialize(reader)
         }
     }
 
     /**
      * Deserializes the JSON [json] string using a pre-resolved [serializer].
      *
      * @param serializer The pre-resolved serializer.
      * @param json The JSON string representation of the object.
      * @return A reconstructed instance of type [T].
      */
     fun <T : Any> deserialize(serializer: GhostSerializer<T>, json: String): T {
         return ghostInternalUseStringReader(json) { reader ->
             serializer.deserialize(reader)
         }
     }
 
     /**
      * Deserializes JSON data from an Okio [BufferedSource] into an instance of type [T].
      *
      * **⚠️ Not suitable for payloads larger than ~10 MB.**
      *
      * This method calls `source.request(Long.MAX_VALUE)` internally, which forces Okio to
      * download the **entire stream into heap memory** before parsing begins. The peak RAM usage
      * is approximately **2× the payload size** (one copy in Okio's buffer, one in the scratch
      * array). On constrained environments such as Android, this will cause an OutOfMemoryError
      * for large files even if the individual buffers would fit, due to heap fragmentation.
      *
      * For payloads that may exceed available heap, use [deserializeStreaming] instead — it reads
      * in ~8 KB Okio segments and keeps memory usage constant regardless of file size.
      *
      * @param source The [BufferedSource] containing the JSON payload. Must be a bounded stream
      *   whose total size fits comfortably within the available heap (recommended < 10 MB).
      * @return A reconstructed instance of type [T].
      * @throws com.ghost.serialization.exception.GhostJsonException if the JSON payload is malformed or the structure is invalid.
      * @see deserializeStreaming for O(1)-memory streaming of large files.
      */
     @OptIn(InternalGhostApi::class)
     inline fun <reified T : Any> deserialize(source: BufferedSource): T {
         source.request(Long.MAX_VALUE)
         val limit = source.buffer.size.toInt()
         val bytes = acquireScratchBuffer(limit)
         try {
             var offset = 0
             while (offset < limit) {
                 val count = source.read(bytes, offset, limit - offset)
                 if (count == -1) {
                     break
                 }
                 offset += count
             }
             return ghostInternalUseFlatReader(bytes, limit) { reader ->
                 deserialize(reader)
             }
         } finally {
             releaseScratchBuffer(bytes)
         }
     }
 
     /**
      * Deserializes JSON data from an Okio [BufferedSource] using true O(1)-memory streaming.
      *
      * Unlike [deserialize], this method does **not** load the entire file into memory.
      * Okio paginates the source in ~8 KB segments on demand, making it safe for database
      * dumps or JSON files of hundreds of megabytes with a constant memory footprint.
      *
      * Use [deserialize] for normal REST payloads (faster flat-array parsing).
      * Use this method when file size may exceed available heap.
      *
      * @param source The BufferedSource stream containing the JSON payload.
      * @return A reconstructed instance of type [T].
      * @throws com.ghost.serialization.exception.GhostJsonException if the JSON payload is malformed or structure is invalid.
      */
     @OptIn(InternalGhostApi::class)
     inline fun <reified T : Any> deserializeStreaming(source: BufferedSource): T {
         return ghostInternalUseSource(source) { reader ->
             deserialize(reader)
         }
     }
 
     /**
      * Deserializes JSON data from [source] using a pre-resolved [serializer].
      *
      * Bypasses type lookup and resolution overhead.
      */
     fun <T : Any> deserializeStreaming(serializer: GhostSerializer<T>, source: BufferedSource): T {
         return ghostInternalUseSource(source) { reader ->
             serializer.deserialize(reader)
         }
     }
 
     /**
      * Deserializes the JSON [bytes] array into an instance of type [T].
      *
      * @param bytes A [ByteArray] containing the JSON UTF-8 payload.
      * @return A reconstructed instance of type [T].
      * @throws com.ghost.serialization.exception.GhostJsonException
      * if the JSON payload is malformed or structure is invalid.
      */
     @OptIn(InternalGhostApi::class)
     inline fun <reified T : Any> deserialize(bytes: ByteArray): T {
         return ghostInternalUseFlatReader(bytes) { reader ->
             deserialize(reader)
         }
     }
 
     /**
      * Deserializes the JSON [bytes] array using a pre-resolved [serializer].
      *
      * Bypasses type lookup and resolution overhead.
      */
     fun <T : Any> deserialize(serializer: GhostSerializer<T>, bytes: ByteArray): T {
         return ghostInternalUseFlatReader(bytes) { reader ->
             serializer.deserialize(reader)
         }
     }
 
     // ── Advanced overloads: options exposes GhostJsonReader → opt-in required ─
 
     /**
      * Advanced: Deserializes the JSON [json] string using custom parser settings.
      *
      * @param json The JSON string representation of the object.
      * @param options A configuration lambda to set reader properties.
      * @return A reconstructed instance of type [T].
      */
     @OptIn(InternalGhostApi::class)
     inline fun <reified T : Any> deserialize(
         json: String,
         crossinline options: (GhostJsonStringReader) -> Unit
     ): T {
         return ghostInternalUseStringReader(json) { reader ->
             options(reader)
             deserialize(reader)
         }
     }
 
     /**
      * Advanced: Deserializes JSON data from a [BufferedSource] stream using custom parser settings.
      *
      * @param source The BufferedSource stream containing the JSON payload.
      * @param options A configuration lambda to set reader properties.
      * @return A reconstructed instance of type [T].
      */
     @OptIn(InternalGhostApi::class)
     inline fun <reified T : Any> deserialize(
         source: BufferedSource,
         crossinline options: (GhostJsonReader) -> Unit
     ): T {
         return ghostInternalUseSource(source) { reader ->
             options(reader)
             deserialize(reader)
         }
     }
 
     /**
      * Advanced: Deserializes the JSON [bytes] array using custom parser settings.
      *
      * @param bytes A [ByteArray] containing the JSON UTF-8 payload.
      * @param options A configuration lambda to set reader properties.
      * @return A reconstructed instance of type [T].
      */
     @OptIn(InternalGhostApi::class)
     inline fun <reified T : Any> deserialize(
         bytes: ByteArray,
         crossinline options: (GhostJsonReader) -> Unit
     ): T {
         return ghostInternalUseReader(bytes) { reader ->
             options(reader)
             deserialize(reader)
         }
     }
 
     /**
      * Non-inline variant of [deserialize] that decodes a [ByteArray] into the specified [clazz].
      * Useful in reflection or framework integration contexts where reified types are unavailable.
      *
      * @param bytes A [ByteArray] containing the JSON UTF-8 payload.
      * @param clazz The KClass of the target type to deserialize.
      * @param limit The byte length boundary of the payload inside [bytes].
      * @return A reconstructed instance of type [T].
      */
     @Suppress("unused")
     @OptIn(InternalGhostApi::class)
     fun <T : Any> decodeFromBytes(bytes: ByteArray, clazz: KClass<T>, limit: Int = bytes.size): T {
         return ghostInternalUseFlatReader(bytes, limit) { reader ->
             val serializer = getSerializer(clazz)
                 ?: throwError("$NOT_FOUND ${clazz.simpleName}")
 
             serializer.deserialize(reader)
         }
     }
 
     /**
      * Non-inline variant of [deserialize] that decodes a [BufferedSource] stream into the specified [clazz].
      * Useful in reflection or framework integration contexts where reified types are unavailable.
      *
      * @param source The BufferedSource stream containing the JSON payload.
      * @param clazz The KClass of the target type to deserialize.
      * @return A reconstructed instance of type [T].
      */
     @OptIn(InternalGhostApi::class)
     fun <T : Any> decodeFromSource(source: BufferedSource, clazz: KClass<T>): T {
         source.request(Long.MAX_VALUE)
         val limit = source.buffer.size.toInt()
         val bytes = acquireScratchBuffer(limit)
         try {
             var offset = 0
             while (offset < limit) {
                 val count = source.read(bytes, offset, limit - offset)
                 if (count == -1) {
                     break
                 }
                 offset += count
             }
             return ghostInternalUseFlatReader(bytes, limit) { reader ->
                 val serializer = getSerializer(clazz)
                     ?: throwError("$NOT_FOUND ${clazz.simpleName}")
 
                 serializer.deserialize(reader)
             }
         } finally {
             releaseScratchBuffer(bytes)
         }
     }
 
     /**
      * Encodes [value] and writes it directly to [sink]. Alias for [serialize].
      *
      * @param sink The Okio sink to write the JSON payload to.
      * @param value The value to serialize.
      */
     inline fun <reified T : Any> encodeToSink(sink: BufferedSink, value: T) {
         serialize(sink, value)
     }
 
     /**
      * Non-inline variant of [encodeToSink] for contexts where the type is known
      * only as a [KClass] at runtime (e.g. Spring HttpMessageConverter, Retrofit adapters).
      *
      * @param sink The Okio sink to write the JSON payload to.
      * @param value The value to serialize.
      * @param clazz The KClass of the target type to serialize.
      */
     @OptIn(InternalGhostApi::class)
     @Suppress("unused")
     fun <T : Any> encodeToSink(sink: BufferedSink, value: T, clazz: KClass<T>) {
         val serializer = getSerializer(clazz)
             ?: throwError("$NOT_FOUND ${clazz.simpleName}. $MISSING_ANN")
         ghostInternalEncodeAndDrainTo(sink) { writer ->
             serializer.serialize(writer, value)
         }
     }
 
     /**
      * Helper deserialize routine for KSP generated serializers.
      */
     @OptIn(InternalGhostApi::class)
     inline fun <reified T : Any> deserialize(reader: GhostJsonReader): T {
         val serializer = resolveSerializer<T>()
         return serializer.deserialize(reader)
     }
 
     /**
      * Helper deserialize routine for KSP generated serializers.
      */
     @OptIn(InternalGhostApi::class)
     inline fun <reified T : Any> deserialize(reader: GhostJsonFlatReader): T {
         val serializer = resolveSerializer<T>()
         return serializer.deserialize(reader)
     }
 
     /**
      * Advanced: Deserializes directly from an existing [GhostJsonStringReader].
      * Note: This bypassing of pooling means the caller is responsible for the reader lifecycle.
      */
     inline fun <reified T : Any> deserialize(reader: GhostJsonStringReader): T {
         val serializer = resolveSerializer<T>()
         return serializer.deserialize(reader)
     }
 
     /**
      * Triggers eager loading and JIT/ART warm-up cycles for all registered serializers.
      * Call this at application startup to achieve zero-latency first-run deserialization.
      */
     fun prewarm() {
         runSynchronized(lock) {
             // Force discovery if not yet done
             if (_discoveredRegistries == null) {
                 _discoveredRegistries = discoverRegistries()
             }
 
             // Manual ones
             for (registry in mutableRegistries) {
                 registry.prewarm()
                 val serializers = registry.getAllSerializers()
                 if (serializers.isNotEmpty()) {
                     for (entry in serializers) {
                         val kclass = entry.key
                         val serializer = entry.value
                         serializerCache[kclass] = serializer
                         serializerByName[serializer.typeName] = serializer
                         serializer.warmUp()
                     }
                 }
             }
 
             // Discovered ones
             val discovered = _discoveredRegistries
             if (discovered != null) {
                 for (registry in discovered) {
                     registry.prewarm()
                     val serializers = registry.getAllSerializers()
                     if (serializers.isNotEmpty()) {
                         for (entry in serializers) {
                             val kclass = entry.key
                             val serializer = entry.value
                             serializerCache[kclass] = serializer
                             serializerByName[serializer.typeName] = serializer
                             serializer.warmUp()
                         }
                     }
                 }
             }
         }
     }
 
     internal const val DEFAULT_REGISTRY_NAME = "com.ghost.serialization.generated.GhostModuleRegistry_Default"
     internal const val TEST_REGISTRY_NAME = "com.ghost.serialization.generated.GhostModuleRegistry_Default_Test"
     internal const val ANDROID_REGISTRY_NAME = "com.ghost.serialization.generated.GhostModuleRegistry_ghost_serialization"
     internal const val INSTANCE_FIELD = "INSTANCE"
 
     /**
      * Serializer not found message prefix.
      */
     const val MISSING_ANN = "Did you annotate it with @GhostSerialization?"
 
     /**
      * Missing serializer configuration error prefix.
      */
     const val NOT_FOUND = "No Ghost serializer found for"
 
     /**
      * Test-only utility to clear global state and prevent test pollution.
      */
     @InternalGhostApi
     fun resetForTest() {
         runSynchronized(lock) {
             mutableRegistries.clear()
             _discoveredRegistries = null
             serializerCache.clear()
             typeCache.clear()
             serializerByName.clear()
         }
     }
 }