Skip to content

Commit 0cd3157

Browse files
committed
enable lazy conversion
1 parent df2e8db commit 0cd3157

File tree

5 files changed

+96
-3
lines changed

5 files changed

+96
-3
lines changed

buildSrc/src/main/kotlin/JavaBasedProjectConventions.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2727
fun Project.javaBasedProjectConventions() {
2828
repositories {
2929
mavenCentral()
30+
mavenLocal()
3031
}
3132

3233
dependencies {

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ protobuf-java = "3.21.7"
2525
protobuf-js = "7.2.6"
2626
protobufGradlePlugin = "0.9.4"
2727
protovalidate = "0.6.4"
28-
protovalidateJava = "0.2.1"
28+
protovalidateJava = "0.0.0-SNAPSHOT"
2929
slf4j = "2.0.6"
3030

3131
# build

protokt-protovalidate/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ plugins {
1818
}
1919

2020
enablePublishing()
21+
trackKotlinApiCompatibility()
2122

2223
dependencies {
2324
implementation(project(":protokt-reflect"))
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package protokt.v1.buf.validate
2+
3+
import build.buf.protovalidate.internal.evaluator.MessageLike
4+
import build.buf.protovalidate.internal.evaluator.Value
5+
import com.google.protobuf.Descriptors.FieldDescriptor
6+
import protokt.v1.Bytes
7+
import protokt.v1.Enum
8+
import protokt.v1.Message
9+
import protokt.v1.google.protobuf.RuntimeContext
10+
import protokt.v1.google.protobuf.getField
11+
import protokt.v1.google.protobuf.hasField
12+
13+
internal class ProtoktMessageLike(
14+
val message: Message,
15+
val context: RuntimeContext,
16+
) : MessageLike {
17+
override fun hasField(field: FieldDescriptor) =
18+
message.hasField(field)
19+
20+
override fun getField(field: FieldDescriptor) =
21+
ProtoktObjectValue(
22+
field,
23+
message.getField(field)!!,
24+
context
25+
)
26+
}
27+
28+
internal class ProtoktMessageValue(
29+
private val message: Message,
30+
private val context: RuntimeContext,
31+
) : Value {
32+
override fun messageValue() =
33+
ProtoktMessageLike(message, context)
34+
35+
override fun repeatedValue() =
36+
emptyList<Value>()
37+
38+
override fun mapValue() =
39+
emptyMap<Value, Value>()
40+
41+
override fun celValue() =
42+
context.convertValue(message)
43+
44+
override fun <T : Any> jvmValue(clazz: Class<T>) =
45+
null
46+
}
47+
48+
internal class ProtoktObjectValue(
49+
private val fieldDescriptor: FieldDescriptor,
50+
private val value: Any,
51+
private val context: RuntimeContext,
52+
) : Value {
53+
override fun messageValue(): MessageLike =
54+
ProtoktMessageLike(value as Message, context)
55+
56+
override fun repeatedValue() =
57+
(value as List<*>).map { ProtoktObjectValue(fieldDescriptor, it!!, context) }
58+
59+
override fun mapValue(): Map<Value, Value> {
60+
val input = value as Map<*, *>
61+
62+
val keyDesc = fieldDescriptor.messageType.findFieldByNumber(1)
63+
val valDesc = fieldDescriptor.messageType.findFieldByNumber(2)
64+
65+
return input.entries.associate { (key, value) ->
66+
Pair(
67+
ProtoktObjectValue(keyDesc, key!!, context),
68+
ProtoktObjectValue(valDesc, value!!, context),
69+
)
70+
}
71+
}
72+
73+
override fun celValue() =
74+
when (value) {
75+
is Enum -> value.value
76+
is UInt -> org.projectnessie.cel.common.ULong.valueOf(value.toLong())
77+
is ULong -> org.projectnessie.cel.common.ULong.valueOf(value.toLong())
78+
is Message, is Bytes -> context.convertValue(value)
79+
80+
// pray
81+
else -> value
82+
}
83+
84+
override fun <T : Any> jvmValue(clazz: Class<T>): T? =
85+
context.convertValue(value)?.let(clazz::cast)
86+
}

protokt-protovalidate/src/main/kotlin/protokt/v1/buf/validate/ProtoktValidator.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ import kotlin.reflect.full.findAnnotation
3838

3939
@Beta
4040
class ProtoktValidator(
41-
config: Config = Config.newBuilder().build()
41+
config: Config = Config.newBuilder().build(),
42+
private val lazyConvert: Boolean = true
4243
) {
4344
private val evaluatorBuilder =
4445
EvaluatorBuilder(
@@ -87,7 +88,11 @@ class ProtoktValidator(
8788
evaluatorsByFullTypeName.getValue(
8889
message::class.findAnnotation<GeneratedMessage>()!!.fullTypeName,
8990
).evaluate(
90-
MessageValue(message.toDynamicMessage(RuntimeContext(descriptors))),
91+
if (lazyConvert) {
92+
ProtoktMessageValue(message, RuntimeContext(descriptors))
93+
} else {
94+
MessageValue(message.toDynamicMessage(RuntimeContext(descriptors)))
95+
},
9196
failFast
9297
)
9398
}

0 commit comments

Comments
 (0)