Repository: ktorio/ktor
File: ktor-server/ktor-server-plugins/ktor-server-di/common/src/io/ktor/server/plugins/di/DependencyKeyCovariance.kt (Kotlin)

Code before:
    return DependencyKeyCovarianceParser(text).parse()
}

private class DependencyKeyCovarianceParser(
    private val text: String,
) {
    companion object {
        private val mappings = mapOf(
            "Supertypes" to Supertypes,
            "SuperTypes" to Supertypes,
            "Unnamed" to Unnamed,
            "Nullables" to Nullables,
            "OutTypeArgumentsSupertypes" to OutTypeArgumentsSupertypes,
            "RawTypes" to RawTypes,
            "Default" to DefaultKeyCovariance
        )
    }
    private var position = 0

    fun parse(): DependencyKeyCovariance {
        skipWhitespace()
        val result = parseAddition()
        skipWhitespace()
        if (position < text.length) {
            error("Unexpected character at position $position: '${text[position]}'")
        }
        return result
    }

    private fun parseAddition(): DependencyKeyCovariance {
        var left = parseMultiplication()

        while (true) {
            skipWhitespace()
            if (position >= text.length || peek() != '+') break

            consume('+')
            skipWhitespace()
            val right = parseMultiplication()
            left += right
        }

        return left
    }

    private fun parseMultiplication(): DependencyKeyCovariance {
        var left = parsePrimary()

        while (true) {
            skipWhitespace()
            if (position >= text.length || peek() != '*') break

Review comment (suggestion):
Minor. All `if (...) { error("message") }` constructions could be replaced by `check(...) { "message" }`
```suggestion
        check(position >= text.length) {
            "Unexpected character at position $position: '${text[position]}'"
        }
```

Code after:
 *
 * When using expressions, operators are supported, including `+`, `*`, and `()`.
 *
 * Examples:
 * - `Supertypes * Nullables` will provide all supertypes and nullable versions of those supertypes.
 * - `Supertypes + (Nullables + Unnamed)` will provide the same, but also unnamed versions of the supertypes.
 *    It will not include nullable, unnamed versions of the supertypes, however.
 */
internal fun parseKeyMapping(text: String): DependencyKeyCovariance {
    return DependencyKeyCovarianceParser(text).parse()
}

private class DependencyKeyCovarianceParser(
    private val text: String,
) {
    companion object {
        private val mappings = mapOf(
            "Supertypes" to Supertypes,
            "SuperTypes" to Supertypes,
            "Unnamed" to Unnamed,
            "Nullables" to Nullables,
            "OutTypeArgumentsSupertypes" to OutTypeArgumentsSupertypes,
            "RawTypes" to RawTypes,
            "Default" to DefaultKeyCovariance
        )
    }
    private var position = 0

    fun parse(): DependencyKeyCovariance {
        skipWhitespace()
        val result = parseAddition()
        skipWhitespace()
        check(position >= text.length) {
            "Unexpected character at position $position: '${text[position]}'"
        }
        return result
    }

    private fun parseAddition(): DependencyKeyCovariance {
        var left = parseMultiplication()

        while (true) {
            skipWhitespace()
            if (position >= text.length || peek() != '+') break

            consume('+')
            skipWhitespace()
            val right = parseMultiplication()
            left += right
        }