Skip to content

Keep back-references to message evaluators that are still being built - #543

Merged
jonbodner-buf merged 3 commits into
mainfrom
jonbodner/fix-recursive-prune
Oct 22, 2026
Merged

jonbodner-buf merged 3 commits into
mainfrom
jonbodner/fix-recursive-prune

Conversation

@jonbodner-buf

@jonbodner-buf jonbodner-buf commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Recursive and mutually recursive MessageEvaluators were treated as already processed and dropped before they finished being evaluated. This led to dropping rules that were reachable through them.

Now a MessageEvaluator only reports that it is processed after it is fully built. Also google.protobuf.Struct, Value, and ListValue are always pruned unless a non-standard descriptor adds rules to them.

…done before they are actually completed. Also don't recurse into google.protobuf.Struct, Value, and ListValue.

Signed-off-by: Jon Bodner <[email protected]>
…done before they are actually completed. Also don't recurse into google.protobuf.Struct, Value, and ListValue.

Signed-off-by: Jon Bodner <[email protected]>

@pkwarren pkwarren left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Just a couple of comments on the tests.

Descriptor a = types.get("A");
Descriptor b = types.get("B");
Validator validator = ValidatorFactory.newBuilder().build();
assertThat(validator.validate(nestedA(a, b, 2, 5)).getViolations()).hasSize(2);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a reader the structure of these tests isn't clear since we're building messages dynamically. It would be easier to follow if we created .proto files under src/test/resources.

Additionally, beyond just the size if would be a stronger assertion if we verified the field paths of violations.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Most of the dynamic types are now defined in a .proto. The ones that have invalid protovalidate rules and override the google.protobuf.* types are still dynamic.

public void testStructTypesAreTautologies() throws Exception {
assertThat(isTautology(Struct.getDescriptor())).isTrue();
assertThat(isTautology(Value.getDescriptor())).isTrue();
assertThat(isTautology(ListValue.getDescriptor())).isTrue();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to testing these types on their own should we test that a message that contains three fields of these types also returns true?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

FieldRules.getDescriptor().findFieldByNumber(FieldRules.CEL_EXPRESSION_FIELD_NUMBER));

private static final Set<String> STRUCT_TYPE_NAMES =
new HashSet<>(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a constant we should wrap with Collections.unmodifiableSet.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


@Test
@Timeout(value = 15, unit = TimeUnit.SECONDS)
public void testSharedChainBuildsInLinearTime() throws Exception {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you describe what this test is protecting against? Is this something that was failing prior to this fix?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this test wasn't needed. I'm removing it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

@jonbodner-buf
jonbodner-buf merged commit e0786e4 into main Oct 22, 2026
4 checks passed
@jonbodner-buf
jonbodner-buf deleted the jonbodner/fix-recursive-prune branch October 22, 2026 23:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants