Skip to content

Support multiple validators, add "Using Validators" section#275

Merged
alexander-yevsyukov merged 81 commits intomasterfrom
doc-set-7
Mar 9, 2026
Merged

Support multiple validators, add "Using Validators" section#275
alexander-yevsyukov merged 81 commits intomasterfrom
doc-set-7

Conversation

@alexander-yevsyukov
Copy link
Collaborator

@alexander-yevsyukov alexander-yevsyukov commented Mar 2, 2026

This PR updates the code generation so that multiple Validators are used for validating fields as long as whole message classes.

ValidatorRegistry was introduced for keeping the association between a message class name and associated validator instances.

The validators are automatically discovered using the ServiceLoader mechanism of Java.

Validators in the generated code are invoked after the option-based validation occurs.

Documentation was extended accordingly.

Copilot AI review requested due to automatic review settings March 2, 2026 18:34
@alexander-yevsyukov alexander-yevsyukov self-assigned this Mar 2, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds documentation and runtime support for validating third-party (external) Protobuf messages via MessageValidator implementations, using google.protobuf.Timestamp as an example.

Changes:

  • Bumped Validation plugin/dependency snapshot version to 2.0.0-SNAPSHOT.401.
  • Added TimestampValidator + corresponding unit tests.
  • Added a new documentation page describing external message validation and updated docs/examples references.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
version.gradle.kts Bumps the Validation dependency version used by the build.
jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt Introduces an external validator for google.protobuf.Timestamp.
jvm-runtime/src/test/kotlin/io/spine/validation/TimestampValidatorSpec.kt Adds tests for TimestampValidator behavior and violation formatting.
jvm-runtime/src/main/kotlin/io/spine/validation/Validator.kt Updates KDoc and copyright year.
docs/content/docs/validation/04-third-party-messages/_index.md Adds documentation section explaining external validators and usage.
docs/content/docs/validation/01-getting-started/adding-to-build.md Updates the plugin version shown in setup instructions.
docs/_examples Updates docs examples submodule pointer.
.agents/tasks/third-party-messages-plan.md Adjusts the documentation plan to use TimestampValidator and new placement.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings March 6, 2026 21:06
alexander-yevsyukov and others added 3 commits March 6, 2026 23:07
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 51 out of 53 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (4)

jvm-runtime/src/main/kotlin/io/spine/validation/ValidatorRegistry.kt:1

  • Correct the typo “kep” → “key”.
    jvm-runtime/src/main/kotlin/io/spine/validation/ValidatorRegistry.kt:1
  • The KDoc says “a list of validators”, but the implementation stores a MutableSet<MessageValidator<*>>. Please update the documentation to reflect set semantics (e.g., uniqueness, no ordering), or change the type to a list if ordering/duplicates are intended.
    jvm-runtime/src/test/kotlin/io/spine/validation/ValidatorRegistrySpec.kt:1
  • This test relies on reflective access to a private method, which is brittle (renames/visibility changes won’t be caught by the compiler) and can fail under stricter runtime settings. Prefer exposing a test-only entry point (e.g., an internal method annotated with @VisibleForTesting, or injecting a ServiceLoader/loader function) so tests can trigger reload without reflection.
    jvm-runtime/src/main/kotlin/io/spine/validation/ValidatorRegistry.kt:1
  • The overload validate(message, parentPath, parentName) is newly introduced and is the one used by generated code for nested-field validation, but the added tests exercise the simpler validate(message) path. Please add coverage that asserts correct propagation/merging of parentPath and parentName into produced ConstraintViolations (including the nested-field path concatenation behavior).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@alexander-yevsyukov alexander-yevsyukov changed the title Add "Validating external messages section" Support multiple validators, add "Validating external messages section" Mar 9, 2026
@alexander-yevsyukov alexander-yevsyukov marked this pull request as ready for review March 9, 2026 16:57
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b00cdb6606

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copilot AI review requested due to automatic review settings March 9, 2026 17:16
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 51 out of 53 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (4)

jvm-runtime/src/main/kotlin/io/spine/validation/ValidatorRegistry.kt:1

  • cls.qualifiedName is nullable (String?), but the map key type is non-null String, so this call should not compile (and/or may behave incorrectly). Use a non-null key consistently (e.g., cls.qualifiedName!! if guaranteed, or prefer cls.java.name / cls.qualifiedOrThrow()-style helper) to match how keys are written in add()/get().
    tests/validating/src/test/kotlin/io/spine/test/options/ValidateITest.kt:1
  • The test name says “accept”, but the assertion now expects UnknownTypeException (i.e., rejection). Rename the test to reflect the new behavior (similar to the other two renamed tests in this file) to keep intent clear.
    jvm-runtime/src/test/kotlin/io/spine/validation/ValidatorRegistrySpec.kt:1
  • ValidatorRegistry.get() returns a Set, and the iteration order of the underlying concurrent set is not guaranteed. shouldContainExactly is order-sensitive for iterables and may lead to flaky tests. Prefer an order-insensitive assertion (e.g., “contains exactly in any order”, or assert size + containsAll).
    jvm-runtime/src/test/kotlin/io/spine/validation/ValidatorRegistrySpec.kt:1
  • Exceptions thrown inside executor.execute { ... } won’t fail the test thread, so assertDoesNotThrow here won’t reliably detect concurrency issues. Consider using submit() + collecting Futures and calling get() (or capturing uncaught exceptions), and assert awaitTermination(...) returns true to ensure all tasks actually completed.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@alexander-yevsyukov alexander-yevsyukov changed the title Support multiple validators, add "Validating external messages section" Support multiple validators, add "Using Validators" section Mar 9, 2026
Copilot AI review requested due to automatic review settings March 9, 2026 17:44
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 51 out of 53 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

jvm-runtime/src/test/kotlin/io/spine/validation/TimestampValidatorSpec.kt:1

  • The expected withPlaceholders string for the nanos violation is inconsistent with the template produced by TimestampValidator.invalidNanos() (it includes parentheses around the placeholder key). As written, this assertion is very likely to fail. Align either the validator message template or the test expectation so the placeholder formatting matches exactly (ideally keep the same pattern as the seconds-range message: include the range placeholder in parentheses and a : value suffix).
    jvm-runtime/src/main/kotlin/io/spine/validation/ValidatorRegistry.kt:1
  • The registry uses ConcurrentHashMap plus a concurrent set, but still synchronizes on this for add/remove/clear. This adds global contention and largely defeats the benefit of concurrent structures, while validate() reads without synchronization anyway. Prefer relying on the atomicity of ConcurrentHashMap.compute and the thread-safety of the backing set (i.e., remove the synchronized blocks), or switch to a consistent read/write locking strategy across add/remove/clear/validate.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@alexander-yevsyukov alexander-yevsyukov merged commit 459e666 into master Mar 9, 2026
8 checks passed
@alexander-yevsyukov alexander-yevsyukov deleted the doc-set-7 branch March 9, 2026 17:55
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.

3 participants