Implement lazy message conversion for protovalidate#402
Draft
andrewparmet wants to merge 17 commits into
Draft
Conversation
…tovalidate - Replace PackageHacks.kt / ProtoktEvaluator / ProtoktEvaluatorBuilder with direct use of protovalidate-java's new public validate(MessageReflector, Descriptor) entrypoint. - ProtoktMessageReflector implements MessageReflector; ProtoktObjectValue implements Value. Both live in the public protokt.v1.buf.validate package. - Validator.validate(message) looks up the descriptor by @GeneratedMessage's fullTypeName. - Make RuntimeContext incremental: descriptor registry is a PersistentMap and a new operator plus(descriptor) returns a copy with the descriptor registered. Avoids O(N²) rebuild when loading descriptors one at a time. - protokt-reflect now depends on kotlinx-collections-immutable. - Wire mavenLocal into the Java project convention so the protovalidate-java SNAPSHOT resolves during local development.
# Conflicts: # gradle/libs.versions.toml # protokt-protovalidate/src/main/kotlin/build/buf/protovalidate/PackageHacks.kt # protokt-protovalidate/src/main/kotlin/protokt/v1/buf/validate/Validator.kt # testing/protovalidate-conformance/build.gradle.kts
Duration, Timestamp, wrappers, and Empty have fixed field layouts and map to a single CEL-native value. Read the fields straight off the protokt message by descriptor and return the CEL-native form directly, skipping the round-trip through RuntimeContext.convertValue and BaseProtoCelValueConverter.toRuntimeValue. Any, Value, Struct, and ListValue keep the DynamicMessage fallback: their shape is open so we let cel-java's converter handle them. FieldMask drops off the WKT list entirely; with cel-java Patch 2 applied it flows through the ordinary ProtoktStructValue path like any other message. Unset wrapper fields now materialize as NullValue.NULL_VALUE per the CEL spec.
This was referenced May 27, 2026
protovalidate-java's MessageReflector now exposes the descriptor itself, so Validator.validate takes only the reflector. Implement getDescriptorForType on ProtoktMessageReflector and drop the second argument from the delegate call.
2744188 to
0433ce5
Compare
… entries Get the MessageReflector + StructValue path to 2840/2840 conformance parity. - ProtoktObjectValue.rawValue: translate UInt/ULong/Enum/Bytes/List/Map to the boxed Java types com.google.protobuf.Message#getField returns; map fields surface as List<MapEntry>. - ProtoktMessageReflector.getField: reverse protokt's wrap annotation when a MESSAGE-typed field surfaces as a scalar, returning a JvmMessageReflector over the unwrapped com.google.protobuf.Message. - Bump protovalidate (testing protos + conformance CLI) to 1.2.0 to match library message wording, and pin protovalidateJava to the standard god-branch snapshot. - Wire -Xfriend-paths in protokt-protovalidate, promote fieldOptions / wrap in RuntimeContext from private to internal.
0433ce5 to
35aa5a8
Compare
Commit the protokt protovalidate integration to the planner CEL runtime. - Drop the manual BaseProtoCelValueConverter.toRuntimeValue pre-unwrap for open WKTs (Any, Value, Struct, ListValue). It was a workaround for the standard DefaultInterpreter's select path, which calls maybeUnwrap but not toRuntimeValue on the way out. The planner's dispatch does both, so handing it the plain com.google.protobuf.Message (or a DynamicMessage default for unset fields) and letting it convert on read is sufficient. - Remove the now-unused WellKnownTypes.unwrap helper, its converter field, and the BaseProtoCelValueConverter import. - Pin cel = 0.13.0-planner-SNAPSHOT to consume the planner-only cel-java branch (two fixes instead of three). Conformance holds at 2840/2840.
3 tasks
cel-java 0.13.1 ships the CelValue-path fixes the protovalidate integration relied on (fixed32/64 as unsigned, FieldMask navigable as a message), so the local cel fork snapshot is no longer needed. Pin stock dev.cel:cel:0.13.1.
This was referenced Jun 14, 2026
Open
This branch had accumulated changes unrelated to protovalidate from its old base: a generated grpc-krpc yarn.lock, proto-google-common-protos API dumps, a gradle-wrapper downgrade, reverts of edition-2023 packing in FieldParser and of multi-type dispatch in the conformance driver, a conformance proto-export restructure, and stale version reversions in libs.versions.toml. Reset all of those to origin/main so the diff is just the protovalidate integration: ProtoktMessageReflector, ProtoktStructValue, the Validator and RuntimeContext wiring, the protokt-protovalidate friend-paths build config, mavenLocal for the protovalidate-java snapshot, and the cel/protovalidate version pins. Conformance holds at 2840/2840.
pkwarren
pushed a commit
to bufbuild/protovalidate-java
that referenced
this pull request
Jun 15, 2026
Moves protovalidate-java's CEL setup from the deprecated standard runtime to the planner runtime. ## Notable callouts - Wire the compiler and runtime by hand rather than through `plannerCelBuilder()`. `CelRuntimeImpl` directs callers to subset the standard library via `setStandardFunctions` rather than `setStandardEnvironmentEnabled`, so the runtime drops stdlib `matches` that way while the checker continues to use `setStandardEnvironmentEnabled(false)`. This keeps `CustomOverload`'s caching `matches` replacement (cel-java#1038). - Set `CelOptions.current().enableHeterogeneousNumericComparisons(true)`, which `CelRuntimeImpl` requires. - Update `cel-java` to 0.13.1 preparing to support alternative Protobuf runtimes. ## Related work: - cel-java: 0.13.1 carries the CelValue-path fixes this work relies on (fixed32/64 treated as unsigned; FieldMask navigable as a message, cel-expr/cel-java#1074). - protovalidate-java: #480 introduces `MessageReflector` to support alternative Protobuf runtimes, which builds on this runtime change (supersedes #202). - protokt: open-toast/protokt#402 is the downstream consumer that validates protokt messages through `MessageReflector` on this planner runtime. ## Testing `./gradlew :conformance:conformance` passes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Run conformance tests using the existing eager implementation with:
and the new lazy implementation with:
Depends on bufbuild/protovalidate-java#202