Skip to content

RuntimeProbeProtocol.kt

src/jvmMain/kotlin/afield/app/diagnostics/debug/RuntimeProbeProtocol.kt · 105 lines

package afield.app.diagnostics.debug

The JSON line protocol between Field and the JDI probe helper process: probe requests and the ack, sample, error and completion responses.

ProbeJson is the codec both sides use; responses are discriminated by their type field.

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json

val ProbeJson

val ProbeJson = Json {
    ignoreUnknownKeys = true
    encodeDefaults = true
    classDiscriminator = "type"
}

sealed interface ProbeRequest

@Serializable
sealed interface ProbeRequest {

val requestId: String

data class ProbeVariableRequest

@Serializable
@SerialName("probe")
data class ProbeVariableRequest(
    override val requestId: String,
    val className: String? = null,
    val sourceName: String? = null,
    val sourceNamePrefix: String? = null,
    val line: Int,
    val variableName: String,
    val threadName: String? = null,
    val maxHits: Int = 1,
    val timeoutMs: Long = 1_500L
) : ProbeRequest

sealed interface ProbeResponse

@Serializable
sealed interface ProbeResponse {

val requestId: String

data class AckResponse

@Serializable
@SerialName("ack")
data class AckResponse(
    override val requestId: String
) : ProbeResponse

data class ErrorResponse

@Serializable
@SerialName("error")
data class ErrorResponse(
    override val requestId: String,
    val error: String,
    val detail: String? = null
) : ProbeResponse

data class CompleteResponse

@Serializable
@SerialName("complete")
data class CompleteResponse(
    override val requestId: String,
    val hits: Int,
    val error: String? = null,
    val detail: String? = null,
    val scope: ScopeSnapshotPayload? = null
) : ProbeResponse

data class ValuePayload

@Serializable
data class ValuePayload(
    val kind: String,
    val type: String? = null,
    val text: String
)

data class ScopeSymbolPayload

@Serializable
data class ScopeSymbolPayload(
    val name: String,
    val resolution: String,
    val type: String? = null,
    val preview: String = "",
    val frameIndex: Int = -1,
    val declaringType: String? = null,
    val method: String? = null,
    val line: Int = -1
)

data class ScopeSnapshotPayload

@Serializable
data class ScopeSnapshotPayload(
    val symbols: List<ScopeSymbolPayload> = emptyList(),
    val omittedCount: Int = 0
)

data class SampleResponse

@Serializable
@SerialName("sample")
data class SampleResponse(
    override val requestId: String,
    val hitIndex: Int,
    val threadName: String,
    val declaringType: String,
    val method: String,
    val line: Int,
    val resolution: String,
    val value: ValuePayload
) : ProbeResponse