Skip to content

Commit

Permalink
Add: Finalize compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
acrusage-iaik committed Apr 22, 2024
1 parent 8667f62 commit c624345
Show file tree
Hide file tree
Showing 10 changed files with 407 additions and 166 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,27 @@ class AntlrJsonPathExpressionEvaluationVisitor(
second: JsonPathExpressionValue.ValueTypeValue,
): Boolean = when (first) {
is JsonPathExpressionValue.ValueTypeValue.JsonValue -> {
when (first.jsonElement) {
is JsonArray -> if (second is JsonPathExpressionValue.ValueTypeValue.JsonValue) {
if (second !is JsonPathExpressionValue.ValueTypeValue.JsonValue) {
false
} else when (first.jsonElement) {
JsonNull -> {
second.jsonElement == JsonNull
}

is JsonPrimitive -> {
if (second.jsonElement is JsonPrimitive) {
when {
first.jsonElement.isString != second.jsonElement.isString -> false
first.jsonElement.isString -> first.jsonElement.content == second.jsonElement.content
else -> first.jsonElement.booleanOrNull?.let { it == second.jsonElement.booleanOrNull }
?: first.jsonElement.longOrNull?.let { it == second.jsonElement.longOrNull }
?: first.jsonElement.doubleOrNull?.let { it == second.jsonElement.doubleOrNull }
?: false
}
} else false
}

is JsonArray -> {
if (second.jsonElement is JsonArray) {
(first.jsonElement.size == second.jsonElement.size) and first.jsonElement.mapIndexed { index, it ->
index to it
Expand All @@ -146,9 +165,9 @@ class AntlrJsonPathExpressionEvaluationVisitor(
)
}
} else false
} else false
}

is JsonObject -> if (second is JsonPathExpressionValue.ValueTypeValue.JsonValue) {
is JsonObject -> {
if (second.jsonElement is JsonObject) {
(first.jsonElement.keys == second.jsonElement.keys) and first.jsonElement.entries.all {
this.evaluateComparisonEqualsUnpacked(
Expand All @@ -163,24 +182,7 @@ class AntlrJsonPathExpressionEvaluationVisitor(
)
}
} else false
} else false

is JsonPrimitive -> if (second is JsonPathExpressionValue.ValueTypeValue.JsonValue) {
if (second.jsonElement is JsonPrimitive) {
when {
first.jsonElement.isString != second.jsonElement.isString -> false
first.jsonElement.isString -> first.jsonElement.content == second.jsonElement.content
else -> first.jsonElement.booleanOrNull?.let { it == second.jsonElement.booleanOrNull }
?: first.jsonElement.longOrNull?.let { it == second.jsonElement.longOrNull }
?: first.jsonElement.doubleOrNull?.let { it == second.jsonElement.doubleOrNull }
?: false
}
} else false
} else false

JsonNull -> if (second is JsonPathExpressionValue.ValueTypeValue.JsonValue) {
second.jsonElement == JsonNull
} else false
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package at.asitplus.wallet.lib.data.jsonPath
import at.asitplus.parser.generated.JsonPathParser

fun JsonPathParser.StringLiteralContext.toUnescapedString(): String {
return rfc9535Utils.unpackStringLiteral(this.text)
return Rfc9535Utils.unpackStringLiteral(this.text)
}

Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ sealed class AntlrJsonPathTypeCheckerExpressionType(val jsonPathExpressionType:
data object FunctionNodesType : NodesType()
}

data object NoType : AntlrJsonPathTypeCheckerExpressionType(null)
data object ErrorType : AntlrJsonPathTypeCheckerExpressionType(null)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ class AntlrJsonPathTypeCheckerVisitor(
// see section 2.4.3: Well-Typedness of Function Expressions
// - https://datatracker.ietf.org/doc/rfc9535/

override fun defaultResult(): AntlrJsonPathTypeCheckerExpressionType {
return AntlrJsonPathTypeCheckerExpressionType.NoType
}
override fun aggregateResult(
aggregate: AntlrJsonPathTypeCheckerExpressionType?,
nextResult: AntlrJsonPathTypeCheckerExpressionType
Expand Down Expand Up @@ -61,6 +64,23 @@ class AntlrJsonPathTypeCheckerVisitor(
return AntlrJsonPathTypeCheckerExpressionType.ValueType
}

override fun visitTest_expr(ctx: JsonPathParser.Test_exprContext): AntlrJsonPathTypeCheckerExpressionType {
return ctx.function_expr()?.let { functionExpressionContext ->
when (visitFunction_expr(functionExpressionContext)) {
is AntlrJsonPathTypeCheckerExpressionType.ValueType -> {
errorListener
?.invalidFunctionExtensionForTestExpression(
functionExpressionContext.FUNCTION_NAME().text,
)
AntlrJsonPathTypeCheckerExpressionType.ErrorType
}
is AntlrJsonPathTypeCheckerExpressionType.ErrorType -> AntlrJsonPathTypeCheckerExpressionType.ErrorType

else -> AntlrJsonPathTypeCheckerExpressionType.LogicalType
}
} ?: AntlrJsonPathTypeCheckerExpressionType.LogicalType // otherwise this is a filter query
}

override fun visitFunction_expr(ctx: JsonPathParser.Function_exprContext): AntlrJsonPathTypeCheckerExpressionType {
val functionArgumentTypes = ctx.function_argument().map {
visitFunction_argument(it)
Expand Down Expand Up @@ -123,23 +143,6 @@ class AntlrJsonPathTypeCheckerVisitor(
}
}

override fun visitTest_expr(ctx: JsonPathParser.Test_exprContext): AntlrJsonPathTypeCheckerExpressionType {
return ctx.function_expr()?.let { functionExpressionContext ->
when (visitFunction_expr(functionExpressionContext)) {
is AntlrJsonPathTypeCheckerExpressionType.ValueType -> {
errorListener
?.invalidFunctionExtensionForTestExpression(
functionExpressionContext.FUNCTION_NAME().text,
)
AntlrJsonPathTypeCheckerExpressionType.ErrorType
}
is AntlrJsonPathTypeCheckerExpressionType.ErrorType -> AntlrJsonPathTypeCheckerExpressionType.ErrorType

else -> AntlrJsonPathTypeCheckerExpressionType.LogicalType
}
} ?: AntlrJsonPathTypeCheckerExpressionType.LogicalType // otherwise this is a filter query
}

override fun visitComparison_expr(ctx: JsonPathParser.Comparison_exprContext): AntlrJsonPathTypeCheckerExpressionType {
// evaluate all comparables in order to find as many errors as possible
// otherwise, a comparison always returns a boolean anyway
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,32 @@ import at.asitplus.wallet.lib.data.jsonPath.functionExtensions.ValueFunctionExte

interface JsonPathFunctionExtensionManager {
fun addExtension(functionExtension: JsonPathFunctionExtension<*>)
fun putExtension(functionExtension: JsonPathFunctionExtension<*>)
fun removeExtension(functionExtensionName: String)
fun getExtension(name: String): JsonPathFunctionExtension<*>?
}

val defaultFunctionExtensionManager: JsonPathFunctionExtensionManager by lazy {
val defaultFunctionExtensionManager by lazy {
object : JsonPathFunctionExtensionManager {
private val extensions: MutableMap<String, JsonPathFunctionExtension<*>> = mutableMapOf()

override fun addExtension(functionExtension: JsonPathFunctionExtension<*>) {
if(extensions.containsKey(functionExtension.name)) {
throw FunctionExtensionCollisionException(functionExtension.name)
}
extensions.put(functionExtension.name, functionExtension)
extensions[functionExtension.name] = functionExtension
}

override fun putExtension(functionExtension: JsonPathFunctionExtension<*>) {
extensions[functionExtension.name] = functionExtension
}

override fun removeExtension(functionExtensionName: String) {
extensions.remove(functionExtensionName)
}

override fun getExtension(name: String): JsonPathFunctionExtension<*>? {
return extensions.get(name)
return extensions[name]
}
}.apply {
addExtension(LengthFunctionExtension)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,8 @@ import org.antlr.v4.kotlinruntime.CharStreams
import org.antlr.v4.kotlinruntime.CommonTokenStream

interface Rfc8259Utils {

fun unpackStringLiteral(string: String): String
}

val rfc8259Utils by lazy {
object : Rfc8259Utils {
override fun unpackStringLiteral(string: String): String {
companion object {
fun unpackStringLiteral(string: String): String {
val lexer = JsonStringLiteralLexer(CharStreams.fromString(string)).apply {
addErrorListener(NapierAntlrErrorListener("JSONStringLiteralLexer"))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package at.asitplus.wallet.lib.data.jsonPath

interface Rfc9535Utils {
fun unpackStringLiteral(string: String): String
}

val rfc9535Utils by lazy {
object : Rfc9535Utils {
override fun unpackStringLiteral(string: String): String {
companion object {
fun unpackStringLiteral(string: String): String {
val doubleQuotedString = if (string.startsWith("\"")) {
string // treat as normal rfc8259 double quoted string
} else {
Expand All @@ -18,7 +14,7 @@ val rfc9535Utils by lazy {
"\"$it\""
}
}
return rfc8259Utils.unpackStringLiteral(doubleQuotedString)
return Rfc8259Utils.unpackStringLiteral(doubleQuotedString)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class AgentSdJwtTest : FreeSpec({
constraints = Constraint(
fields = listOf(
ConstraintField(
path = listOf("$.given-name")
path = listOf("$['given-name']")
)
)
)
Expand Down Expand Up @@ -89,7 +89,7 @@ class AgentSdJwtTest : FreeSpec({
constraints = Constraint(
fields = listOf(
ConstraintField(
path = listOf("$.given-name")
path = listOf("$['given-name']")
)
)
)
Expand Down Expand Up @@ -125,7 +125,7 @@ class AgentSdJwtTest : FreeSpec({
constraints = Constraint(
fields = listOf(
ConstraintField(
path = listOf("$.given-name")
path = listOf("$['given-name']")
)
)
)
Expand Down Expand Up @@ -155,7 +155,7 @@ class AgentSdJwtTest : FreeSpec({
constraints = Constraint(
fields = listOf(
ConstraintField(
path = listOf("$.given-name")
path = listOf("$['given-name']")
)
)
)
Expand Down
Loading

0 comments on commit c624345

Please sign in to comment.