From b98202198a870f32f896c2397ce783b353ac382e Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 15:58:23 +0100 Subject: [PATCH 01/36] Bump CoreJvm Compiler -> `2.0.0-SNAPSHOT.064` --- .../main/kotlin/io/spine/dependency/local/CoreJvmCompiler.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvmCompiler.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvmCompiler.kt index 0a52ff7826..6ee3b088ed 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvmCompiler.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvmCompiler.kt @@ -46,7 +46,7 @@ object CoreJvmCompiler { /** * The version used to in the build classpath. */ - const val dogfoodingVersion = "2.0.0-SNAPSHOT.063" + const val dogfoodingVersion = "2.0.0-SNAPSHOT.064" /** * The version to be used for integration tests. From 605670b9c528ce9f3df0234c635c238cbb323acb Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 15:59:43 +0100 Subject: [PATCH 02/36] Update dependency reports --- docs/dependencies/dependencies.md | 32 +++++++++++++++---------------- docs/dependencies/pom.xml | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/dependencies/dependencies.md b/docs/dependencies/dependencies.md index 1e01107cbe..51b03e9459 100644 --- a/docs/dependencies/dependencies.md +++ b/docs/dependencies/dependencies.md @@ -1090,7 +1090,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:23 WEST 2026** using +This report was generated on **Fri May 15 15:58:25 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1791,21 +1791,21 @@ This report was generated on **Thu May 14 20:38:23 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:22 WEST 2026** using +This report was generated on **Fri May 15 15:58:24 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-docs:2.0.0-SNAPSHOT.420` +# Dependencies of `io.spine.tools:validation-docs:2.0.0-SNAPSHOT.421` ## Runtime ## Compile, tests, and tooling The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Wed May 13 20:09:04 WEST 2026** using +This report was generated on **Fri May 15 15:58:21 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2864,7 +2864,7 @@ This report was generated on **Wed May 13 20:09:04 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:23 WEST 2026** using +This report was generated on **Fri May 15 15:58:25 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3961,7 +3961,7 @@ This report was generated on **Thu May 14 20:38:23 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:23 WEST 2026** using +This report was generated on **Fri May 15 15:58:25 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4015,7 +4015,7 @@ This report was generated on **Thu May 14 20:38:23 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:19 WEST 2026** using +This report was generated on **Fri May 15 15:58:21 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4822,7 +4822,7 @@ This report was generated on **Thu May 14 20:38:19 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:23 WEST 2026** using +This report was generated on **Fri May 15 15:58:25 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5511,7 +5511,7 @@ This report was generated on **Thu May 14 20:38:23 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:22 WEST 2026** using +This report was generated on **Fri May 15 15:58:24 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5976,7 +5976,7 @@ This report was generated on **Thu May 14 20:38:22 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:22 WEST 2026** using +This report was generated on **Fri May 15 15:58:24 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6602,7 +6602,7 @@ This report was generated on **Thu May 14 20:38:22 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:21 WEST 2026** using +This report was generated on **Fri May 15 15:58:24 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7170,7 +7170,7 @@ This report was generated on **Thu May 14 20:38:21 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:22 WEST 2026** using +This report was generated on **Fri May 15 15:58:24 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7781,7 +7781,7 @@ This report was generated on **Thu May 14 20:38:22 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:22 WEST 2026** using +This report was generated on **Fri May 15 15:58:24 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8526,7 +8526,7 @@ This report was generated on **Thu May 14 20:38:22 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:22 WEST 2026** using +This report was generated on **Fri May 15 15:58:24 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8766,7 +8766,7 @@ This report was generated on **Thu May 14 20:38:22 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:21 WEST 2026** using +This report was generated on **Fri May 15 15:58:24 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9116,6 +9116,6 @@ This report was generated on **Thu May 14 20:38:21 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 14 20:38:21 WEST 2026** using +This report was generated on **Fri May 15 15:58:23 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/docs/dependencies/pom.xml b/docs/dependencies/pom.xml index 133b9969ac..1155b67fdf 100644 --- a/docs/dependencies/pom.xml +++ b/docs/dependencies/pom.xml @@ -269,7 +269,7 @@ all modules and does not describe the project structure per-subproject. io.spine.tools core-jvm-plugins - 2.0.0-SNAPSHOT.063 + 2.0.0-SNAPSHOT.064 io.spine.tools @@ -284,7 +284,7 @@ all modules and does not describe the project structure per-subproject. io.spine.tools time-validation - 2.0.0-SNAPSHOT.236 + 2.0.0-SNAPSHOT.240 io.spine.tools From 6091ed88c97033bfc591cf6d8391c483d67b2877 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 16:25:10 +0100 Subject: [PATCH 03/36] Suppress false duplicate depenencies warning --- tests/consumer/build.gradle.kts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/consumer/build.gradle.kts b/tests/consumer/build.gradle.kts index 87ce879e5f..694c18ced0 100644 --- a/tests/consumer/build.gradle.kts +++ b/tests/consumer/build.gradle.kts @@ -49,8 +49,12 @@ spine { dependencies { spineCompiler(project(":java")) - spineCompiler(project(":tests:extensions")) - implementation(project(":tests:extensions")) + @Suppress("AvoidDuplicateDependencies") // The subproject is used in different configurations. + run { + val testsExtensions = project(":tests:extensions") + spineCompiler(testsExtensions) + implementation(testsExtensions) + } implementation(project(":tests:consumer-dependency")) implementation(Time.lib) testImplementation(TestLib.lib) From 2df5d38881ea9c4b22d692c31f6cf03339f2bd1f Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 16:31:22 +0100 Subject: [PATCH 04/36] Bump Time -> `2.0.0-SNAPSHOT.240` --- buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt index 4e285fa9d2..e6c184c9cb 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt @@ -40,7 +40,7 @@ import io.spine.dependency.Dependency ) object Time : Dependency() { override val group = Spine.group - override val version = "2.0.0-SNAPSHOT.238" + override val version = "2.0.0-SNAPSHOT.240" private const val infix = "spine-time" fun lib(version: String): String = "$group:$infix:$version" From af4d05794a42b1158ebc00bc5b7bfe49ed953a1f Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 16:31:42 +0100 Subject: [PATCH 05/36] Update dependency reports --- docs/dependencies/dependencies.md | 30 +++++++++++++++--------------- docs/dependencies/pom.xml | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/dependencies/dependencies.md b/docs/dependencies/dependencies.md index 51b03e9459..e9ecad1239 100644 --- a/docs/dependencies/dependencies.md +++ b/docs/dependencies/dependencies.md @@ -1090,7 +1090,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:25 WEST 2026** using +This report was generated on **Fri May 15 16:29:50 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1791,7 +1791,7 @@ This report was generated on **Fri May 15 15:58:25 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:24 WEST 2026** using +This report was generated on **Fri May 15 16:29:49 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1805,7 +1805,7 @@ This report was generated on **Fri May 15 15:58:24 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:21 WEST 2026** using +This report was generated on **Fri May 15 16:29:48 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2864,7 +2864,7 @@ This report was generated on **Fri May 15 15:58:21 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:25 WEST 2026** using +This report was generated on **Fri May 15 16:29:50 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3961,7 +3961,7 @@ This report was generated on **Fri May 15 15:58:25 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:25 WEST 2026** using +This report was generated on **Fri May 15 16:29:50 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4015,7 +4015,7 @@ This report was generated on **Fri May 15 15:58:25 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:21 WEST 2026** using +This report was generated on **Fri May 15 16:29:48 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4822,7 +4822,7 @@ This report was generated on **Fri May 15 15:58:21 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:25 WEST 2026** using +This report was generated on **Fri May 15 16:29:50 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5511,7 +5511,7 @@ This report was generated on **Fri May 15 15:58:25 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:24 WEST 2026** using +This report was generated on **Fri May 15 16:29:49 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5976,7 +5976,7 @@ This report was generated on **Fri May 15 15:58:24 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:24 WEST 2026** using +This report was generated on **Fri May 15 16:29:49 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6602,7 +6602,7 @@ This report was generated on **Fri May 15 15:58:24 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:24 WEST 2026** using +This report was generated on **Fri May 15 16:29:49 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7170,7 +7170,7 @@ This report was generated on **Fri May 15 15:58:24 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:24 WEST 2026** using +This report was generated on **Fri May 15 16:29:49 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7781,7 +7781,7 @@ This report was generated on **Fri May 15 15:58:24 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:24 WEST 2026** using +This report was generated on **Fri May 15 16:29:49 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8526,7 +8526,7 @@ This report was generated on **Fri May 15 15:58:24 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:24 WEST 2026** using +This report was generated on **Fri May 15 16:29:49 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8766,7 +8766,7 @@ This report was generated on **Fri May 15 15:58:24 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:24 WEST 2026** using +This report was generated on **Fri May 15 16:29:48 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9116,6 +9116,6 @@ This report was generated on **Fri May 15 15:58:24 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 15:58:23 WEST 2026** using +This report was generated on **Fri May 15 16:29:48 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/docs/dependencies/pom.xml b/docs/dependencies/pom.xml index 1155b67fdf..2b08e160e6 100644 --- a/docs/dependencies/pom.xml +++ b/docs/dependencies/pom.xml @@ -56,7 +56,7 @@ all modules and does not describe the project structure per-subproject. io.spine spine-time - 2.0.0-SNAPSHOT.238 + 2.0.0-SNAPSHOT.240 compile From 9b43f9af1b77a79489b0719909912f098c9c89ab Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 18:02:18 +0100 Subject: [PATCH 06/36] Rename `error_message.proto` to `template_string.proto` --- .../validation/{error_message.proto => template_string.proto} | 2 +- .../src/main/proto/spine/validation/validation_error.proto | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename jvm-runtime/src/main/proto/spine/validation/{error_message.proto => template_string.proto} (98%) diff --git a/jvm-runtime/src/main/proto/spine/validation/error_message.proto b/jvm-runtime/src/main/proto/spine/validation/template_string.proto similarity index 98% rename from jvm-runtime/src/main/proto/spine/validation/error_message.proto rename to jvm-runtime/src/main/proto/spine/validation/template_string.proto index 9521073f8c..25fb9ab2c2 100644 --- a/jvm-runtime/src/main/proto/spine/validation/error_message.proto +++ b/jvm-runtime/src/main/proto/spine/validation/template_string.proto @@ -31,7 +31,7 @@ import "spine/options.proto"; option (type_url_prefix) = "type.spine.io"; option java_multiple_files = true; -option java_outer_classname = "ErrorMessageProto"; +option java_outer_classname = "TemplateStringProto"; option java_package = "io.spine.validation"; // Represents a template string with placeholders and a map for further substituting diff --git a/jvm-runtime/src/main/proto/spine/validation/validation_error.proto b/jvm-runtime/src/main/proto/spine/validation/validation_error.proto index c9562d093e..b24ed173f4 100644 --- a/jvm-runtime/src/main/proto/spine/validation/validation_error.proto +++ b/jvm-runtime/src/main/proto/spine/validation/validation_error.proto @@ -36,7 +36,7 @@ option java_package = "io.spine.validation"; import "google/protobuf/any.proto"; -import "spine/validation/error_message.proto"; +import "spine/validation/template_string.proto"; import "spine/base/field_path.proto"; // An error indicating that a message did not pass validation. From f255455d5a25607a8909ffd8e52c8583adf4bf69 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 18:02:37 +0100 Subject: [PATCH 07/36] Remove deprecated `ErrorPlaceholder` --- .../tools/validation/ErrorPlaceholder.kt | 78 ------------------- .../java/expression/TemplateStrings.kt | 26 ------- 2 files changed, 104 deletions(-) delete mode 100644 context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholder.kt diff --git a/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholder.kt b/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholder.kt deleted file mode 100644 index 5044d74ae1..0000000000 --- a/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholder.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2026, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.tools.validation - -/** - * A template placeholder that can be used in error messages. - * - * Enumerates placeholder names that can be used within Protobuf definitions. - * Each validation option declares the supported placeholders. Take a look at - * `options.proto` for examples. - * - * The enum is used by the compiler model and Java renderer when validating and rendering - * built-in option error messages. - */ -@Deprecated( - message = "Please use `io.spine.validation.ErrorPlaceholder` instead.", - replaceWith = ReplaceWith("ErrorPlaceholder", "io.spine.validation.ErrorPlaceholder") -) -public enum class ErrorPlaceholder(public val value: String) { - - // Common placeholders. - FIELD_PATH("field.path"), - FIELD_VALUE("field.value"), - FIELD_TYPE("field.type"), - MESSAGE_TYPE("message.type"), - PARENT_TYPE("parent.type"), - - // Placeholders for the field options. - REGEX_PATTERN("regex.pattern"), - REGEX_MODIFIERS("regex.modifiers"), - GOES_COMPANION("goes.companion"), - FIELD_PROPOSED_VALUE("field.proposed_value"), - FIELD_DUPLICATES("field.duplicates"), - RANGE_VALUE("range.value"), - MAX_VALUE("max.value"), - MAX_OPERATOR("max.operator"), - MIN_VALUE("min.value"), - MIN_OPERATOR("min.operator"), - WHEN_IN("when.in"), - - // Placeholders for the `oneof` options. - GROUP_PATH("group.path"), - - // Placeholder for the message options. - REQUIRE_FIELDS("require.fields"); - - /** - * Converts this placeholder to its runtime counterpart. - */ - public fun toRuntime(): io.spine.validation.ErrorPlaceholder = - io.spine.validation.ErrorPlaceholder.valueOf(name) - - override fun toString(): String = value -} diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt b/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt index 3314aa9de0..c5f06d3964 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt @@ -55,32 +55,6 @@ public fun templateString( ): Expression = withStringPlaceholders(template, placeholders.mapKeys { it.key.value }, optionName) -/** - * Yields an expression that creates a new instance of [TemplateString]. - * - * This overload accepts the deprecated placeholders from the former - * `io.spine.tools.validation` package. - * - * @param placeholders The supported placeholders and their values. - * @param optionName The name of the option, which declared the provided [placeholders]. - */ -@Suppress("DEPRECATION") -@Deprecated( - message = "Please use the overload accepting `io.spine.validation.ErrorPlaceholder`." -) -public fun templateString( - template: String, - placeholders: Map>, - optionName: String -): Expression { - val runtimePlaceholders = placeholders.mapKeys { it.key.toRuntime() } - return withStringPlaceholders( - template, - runtimePlaceholders.mapKeys { it.key.value }, - optionName - ) -} - /** * Yields an expression that creates a new instance of [TemplateString]. * From 70d0811e105160a094b00347d7c826c56a1ad29c Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 18:04:06 +0100 Subject: [PATCH 08/36] Add integration tests for the `(when)` constraint compilation --- docs/dependencies/pom.xml | 6 ++ settings.gradle.kts | 1 + tests/time/build.gradle.kts | 71 ++++++++++++++ .../spine/test/validation/time/Assertions.kt | 39 ++++++++ .../io/spine/test/validation/time/Fixtures.kt | 73 +++++++++++++++ .../test/validation/time/TemporalWhenSpec.kt | 89 ++++++++++++++++++ .../test/validation/time/TimestampWhenSpec.kt | 93 +++++++++++++++++++ .../spine/test/validation/time/when.proto | 70 ++++++++++++++ 8 files changed, 442 insertions(+) create mode 100644 tests/time/build.gradle.kts create mode 100644 tests/time/src/test/kotlin/io/spine/test/validation/time/Assertions.kt create mode 100644 tests/time/src/test/kotlin/io/spine/test/validation/time/Fixtures.kt create mode 100644 tests/time/src/test/kotlin/io/spine/test/validation/time/TemporalWhenSpec.kt create mode 100644 tests/time/src/test/kotlin/io/spine/test/validation/time/TimestampWhenSpec.kt create mode 100644 tests/time/src/test/proto/spine/test/validation/time/when.proto diff --git a/docs/dependencies/pom.xml b/docs/dependencies/pom.xml index 2b08e160e6..edd2c353e0 100644 --- a/docs/dependencies/pom.xml +++ b/docs/dependencies/pom.xml @@ -59,6 +59,12 @@ all modules and does not describe the project structure per-subproject. 2.0.0-SNAPSHOT.240 compile + + io.spine + spine-time-java + 2.0.0-SNAPSHOT.240 + compile + io.spine spine-validation-jvm-runtime diff --git a/settings.gradle.kts b/settings.gradle.kts index 95030fa624..84726e8fde 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -45,6 +45,7 @@ include( ":tests:consumer", ":tests:consumer-dependency", ":tests:runtime", + ":tests:time", ":tests:vanilla", ":tests:validating", ":tests:validator", diff --git a/tests/time/build.gradle.kts b/tests/time/build.gradle.kts new file mode 100644 index 0000000000..a3f37588ad --- /dev/null +++ b/tests/time/build.gradle.kts @@ -0,0 +1,71 @@ +/* + * Copyright 2026, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import io.spine.dependency.boms.BomsPlugin +import io.spine.dependency.local.Logging +import io.spine.dependency.local.TestLib +import io.spine.dependency.local.Time +import io.spine.gradle.report.license.LicenseReporter + +buildscript { + standardSpineSdkRepositories() + dependencies { + classpath(io.spine.dependency.local.Time.gradlePlugin) + } +} + +plugins { + java + `java-library` + kotlin("jvm") + id("module-testing") +} +apply(plugin = "io.spine.time") +apply() +LicenseReporter.generateReportIn(project) + +spine { + compiler { + plugins( + // Suppress warnings in the generated code. + "io.spine.tools.compiler.jvm.annotation.SuppressWarningsAnnotation\$Plugin", + "io.spine.validation.java.JavaValidationPlugin", + ) + } +} + +dependencies { + spineCompiler(project(":java")) + spineCompiler(Time.validation) + + implementation(Time.lib) + implementation(Time.javaExtensions) + + testImplementation(Logging.lib) + testImplementation(TestLib.lib) +} + +configureTaskDependencies() diff --git a/tests/time/src/test/kotlin/io/spine/test/validation/time/Assertions.kt b/tests/time/src/test/kotlin/io/spine/test/validation/time/Assertions.kt new file mode 100644 index 0000000000..a379e73d22 --- /dev/null +++ b/tests/time/src/test/kotlin/io/spine/test/validation/time/Assertions.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2026, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.test.validation.time + +import io.spine.validation.ValidationException +import org.junit.jupiter.api.assertDoesNotThrow +import org.junit.jupiter.api.assertThrows + +internal fun assertValidationFails(executable: () -> Unit) { + assertThrows { executable() } +} + +internal fun assertValidationPasses(executable: () -> Unit) { + assertDoesNotThrow(executable) +} diff --git a/tests/time/src/test/kotlin/io/spine/test/validation/time/Fixtures.kt b/tests/time/src/test/kotlin/io/spine/test/validation/time/Fixtures.kt new file mode 100644 index 0000000000..adb7a5bfbe --- /dev/null +++ b/tests/time/src/test/kotlin/io/spine/test/validation/time/Fixtures.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2026, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.test.validation.time + +import com.google.protobuf.Timestamp +import com.google.protobuf.util.Durations.fromMillis +import com.google.protobuf.util.Timestamps +import io.spine.time.LocalDateTime +import io.spine.time.LocalDateTimes +import java.time.Instant +import java.time.LocalDateTime.ofInstant +import java.time.ZoneOffset.UTC + +/** + * Five hundred milliseconds. + * + * To shift the time into the past or future, we add or subtract a difference of this amount. + * + * There are two reasons for choosing 500 milliseconds: + * + * 1. The generated code uses `io.spine.base.Time.currentTime()` to get the current timestamp + * for comparison. In turn, this method relies on `io.spine.base.Time.SystemTimeProvider` + * by default, which has millisecond precision. + * 2. Adding too small an amount of time to make the stamp denote "future" might be unreliable. + * As it could catch up `now` by the time `Time.currentTime()` is invoked. + */ +private const val HALF_OF_SECOND: Long = 500 + +internal object TemporalFixtures { + + fun pastTime(): LocalDateTime { + val current = Instant.now() // It is a UTC stamp. + return LocalDateTimes.of(ofInstant(current.minusMillis(HALF_OF_SECOND), UTC)) + } + + fun futureTime(): LocalDateTime { + val current = Instant.now() // It is a UTC stamp. + return LocalDateTimes.of(ofInstant(current.plusMillis(HALF_OF_SECOND), UTC)) + } +} + +internal object TimestampFixtures { + + fun pastTime(): Timestamp = + Timestamps.subtract(Timestamps.now(), fromMillis(HALF_OF_SECOND)) + + fun futureTime(): Timestamp = + Timestamps.add(Timestamps.now(), fromMillis(HALF_OF_SECOND)) +} diff --git a/tests/time/src/test/kotlin/io/spine/test/validation/time/TemporalWhenSpec.kt b/tests/time/src/test/kotlin/io/spine/test/validation/time/TemporalWhenSpec.kt new file mode 100644 index 0000000000..5abe4eaec9 --- /dev/null +++ b/tests/time/src/test/kotlin/io/spine/test/validation/time/TemporalWhenSpec.kt @@ -0,0 +1,89 @@ +/* + * Copyright 2026, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.test.validation.time + +import io.spine.test.validation.time.TemporalFixtures.futureTime +import io.spine.test.validation.time.TemporalFixtures.pastTime +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test + +@DisplayName("If used with `Temporal`, `(when)` constraint should") +@Disabled("Until Spine Time migrates to the new Validation `Placeholder` API.") +internal class TemporalWhenSpec { + + @Nested inner class + `the past` { + + @Test + fun `throw, if restricted to be in future`() = assertValidationFails { + futureSpineTemporal { + value = pastTime() + } + } + + @Test + fun `pass, if restricted to be in past`() = assertValidationPasses { + pastSpineTemporal { + value = pastTime() + } + } + + @Test + fun `pass, if not restricted at all`() = assertValidationPasses { + anySpineTemporal { + value = pastTime() + } + } + } + + @Nested inner class + `the future` { + + @Test + fun `throw, if restricted to be in past`() = assertValidationFails { + pastSpineTemporal { + value = futureTime() + } + } + + @Test + fun `pass, if restricted to be in future`() = assertValidationPasses { + futureSpineTemporal { + value = futureTime() + } + } + + @Test + fun `pass, if not restricted at all`() = assertValidationPasses { + anySpineTemporal { + value = futureTime() + } + } + } +} diff --git a/tests/time/src/test/kotlin/io/spine/test/validation/time/TimestampWhenSpec.kt b/tests/time/src/test/kotlin/io/spine/test/validation/time/TimestampWhenSpec.kt new file mode 100644 index 0000000000..1a891b59eb --- /dev/null +++ b/tests/time/src/test/kotlin/io/spine/test/validation/time/TimestampWhenSpec.kt @@ -0,0 +1,93 @@ +/* + * Copyright 2026, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.test.validation.time + +import io.spine.test.validation.time.TimestampFixtures.futureTime +import io.spine.test.validation.time.TimestampFixtures.pastTime +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test + +@DisplayName("If used with Protobuf `Timestamp`, `(when)` constraint should") +@Disabled("Until Spine Time migrates to the new Validation `Placeholder` API.") +internal class TimestampWhenSpec { + + @Nested inner class + `when given a timestamp denoting` { + + @Nested inner class + `the past` { + + @Test + fun `throw, if restricted to be in future`() = assertValidationFails { + futureProtoTimestamp { + value = pastTime() + } + } + + @Test + fun `pass, if restricted to be in past`() = assertValidationPasses { + pastProtoTimestamp { + value = pastTime() + } + } + + @Test + fun `pass, if not restricted at all`() = assertValidationPasses { + anyProtoTimestamp { + value = pastTime() + } + } + } + + @Nested inner class + `the future` { + + @Test + fun `throw, if restricted to be in past`() = assertValidationFails { + pastProtoTimestamp { + value = futureTime() + } + } + + @Test + fun `pass, if restricted to be in future`() = assertValidationPasses { + futureProtoTimestamp { + value = futureTime() + } + } + + @Test + fun `pass, if not restricted at all`() = assertValidationPasses { + anyProtoTimestamp { + value = futureTime() + } + } + } + } +} diff --git a/tests/time/src/test/proto/spine/test/validation/time/when.proto b/tests/time/src/test/proto/spine/test/validation/time/when.proto new file mode 100644 index 0000000000..5136412a43 --- /dev/null +++ b/tests/time/src/test/proto/spine/test/validation/time/when.proto @@ -0,0 +1,70 @@ +/* + * Copyright 2026, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +syntax = "proto3"; + +package spine.test.validation.time; + +import "spine/options.proto"; +import "spine/time_options.proto"; + +option (type_url_prefix) = "type.spine.io"; +option java_package = "io.spine.test.validation.time"; +option java_outer_classname = "WhenProto"; +option java_multiple_files = true; + +import "google/protobuf/timestamp.proto"; +import "spine/time/time.proto"; + +// Tests `PAST` restriction with a Protobuf timestamp. +message PastProtoTimestamp { + google.protobuf.Timestamp value = 1 [(when).in = PAST]; +} + +// Tests `PAST` restriction with a Spine temporal. +message PastSpineTemporal { + spine.time.LocalDateTime value = 1 [(when).in = PAST]; +} + +// Tests `FUTURE` restriction with a Protobuf timestamp. +message FutureProtoTimestamp { + google.protobuf.Timestamp value = 1 [(when).in = FUTURE]; +} + +// Tests `FUTURE` restriction with a Spine temporal. +message FutureSpineTemporal { + spine.time.LocalDateTime value = 1 [(when).in = FUTURE]; +} + +// Tests that a Protobuf timestamp is not restricted when there's no option. +message AnyProtoTimestamp { + google.protobuf.Timestamp value = 1; +} + +// Tests that a Spine temporal is not restricted when there's no option. +message AnySpineTemporal { + spine.time.LocalDateTime value = 1; +} From 384a0420383f9039792cab16b3d59ed608e847f2 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 18:36:46 +0100 Subject: [PATCH 09/36] Introduce `Placeholder`, rename `ErrorPlaceholder` to `StandardPlaceholder` --- .../tools/validation/ErrorPlaceholders.kt | 12 +- .../spine/tools/validation/bound/MaxOption.kt | 12 +- .../spine/tools/validation/bound/MinOption.kt | 12 +- .../tools/validation/bound/RangeOption.kt | 10 +- .../tools/validation/option/ChoiceOption.kt | 4 +- .../tools/validation/option/DistinctOption.kt | 10 +- .../tools/validation/option/GoesOption.kt | 10 +- .../tools/validation/option/PatternOption.kt | 12 +- .../tools/validation/option/RequireOption.kt | 4 +- .../tools/validation/option/SetOnceOption.kt | 10 +- .../option/required/RequiredOption.kt | 6 +- .../developer/adding-a-built-in-option.md | 4 +- .../validation/developer/runtime-library.md | 6 +- .../validation/developer/validation-model.md | 6 +- docs/dependencies/dependencies.md | 457 +++++++++++++++++- .../java/expression/TemplateStrings.kt | 8 +- .../java/generate/option/ChoiceGenerator.kt | 8 +- .../java/generate/option/DistinctGenerator.kt | 14 +- .../java/generate/option/GoesGenerator.kt | 14 +- .../java/generate/option/PatternGenerator.kt | 16 +- .../generate/option/RequireOptionGenerator.kt | 8 +- .../java/generate/option/RequiredGenerator.kt | 10 +- .../option/bound/BoundedFieldGenerator.kt | 4 +- .../generate/option/bound/MaxGenerator.kt | 16 +- .../generate/option/bound/MinGenerator.kt | 16 +- .../generate/option/bound/RangeGenerator.kt | 14 +- .../setonce/SetOnceConstraintViolation.kt | 13 +- .../kotlin/io/spine/validation/Placeholder.kt | 43 ++ ...rPlaceholder.kt => StandardPlaceholder.kt} | 10 +- .../io/spine/validation/TemplateStringExts.kt | 10 +- .../io/spine/validation/TimestampValidator.kt | 4 +- .../test/options/goes/GoesViolationITest.kt | 10 +- .../options/setonce/SetOnceViolationITest.kt | 10 +- 33 files changed, 638 insertions(+), 165 deletions(-) create mode 100644 jvm-runtime/src/main/kotlin/io/spine/validation/Placeholder.kt rename jvm-runtime/src/main/kotlin/io/spine/validation/{ErrorPlaceholder.kt => StandardPlaceholder.kt} (88%) diff --git a/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt b/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt index ca01a6241f..579920ddd6 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt @@ -34,7 +34,7 @@ import io.spine.tools.compiler.ast.OneofGroup import io.spine.tools.compiler.ast.Span import io.spine.tools.compiler.ast.qualifiedName import io.spine.tools.compiler.check -import io.spine.validation.ErrorPlaceholder +import io.spine.validation.Placeholder import io.spine.validation.extractPlaceholders /** @@ -47,7 +47,7 @@ import io.spine.validation.extractPlaceholders * @param option The name of the option with which the message template was specified. */ internal fun String.checkPlaceholders( - supported: Set, + supported: Set, message: MessageType, file: File, option: String @@ -69,7 +69,7 @@ internal fun String.checkPlaceholders( * @param option The name of the option with which the message template was specified. */ internal fun String.checkPlaceholders( - supported: Set, + supported: Set, oneof: OneofGroup, file: File, option: String @@ -91,7 +91,7 @@ internal fun String.checkPlaceholders( * @param option The name of the option with which the message template was specified. */ public fun String.checkPlaceholders( - supported: Set, + supported: Set, field: Field, file: File, option: String @@ -108,7 +108,7 @@ public fun String.checkPlaceholders( * set of the [supported] placeholders, and reports a compilation error if so. */ private fun String.checkPlaceholders( - supported: Set, + supported: Set, declaration: String, span: Span, file: File, @@ -132,7 +132,7 @@ private fun String.checkPlaceholders( */ private fun missingPlaceholders( template: String, - placeholders: Set + placeholders: Set ): Set { val requested = extractPlaceholders(template) val provided = placeholders.map { it.value } diff --git a/context/src/main/kotlin/io/spine/tools/validation/bound/MaxOption.kt b/context/src/main/kotlin/io/spine/tools/validation/bound/MaxOption.kt index b13829ea21..8eb0702271 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/bound/MaxOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/bound/MaxOption.kt @@ -48,12 +48,12 @@ import io.spine.tools.validation.checkPlaceholders import io.spine.tools.validation.defaultMessage import io.spine.tools.validation.option.MAX import io.spine.tools.validation.option.RANGE -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.MAX_OPERATOR -import io.spine.validation.ErrorPlaceholder.MAX_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.MAX_OPERATOR +import io.spine.validation.StandardPlaceholder.MAX_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * A reaction to add a validation rule to a type whenever the `(max)` field option diff --git a/context/src/main/kotlin/io/spine/tools/validation/bound/MinOption.kt b/context/src/main/kotlin/io/spine/tools/validation/bound/MinOption.kt index 5cff14b387..09821c0e87 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/bound/MinOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/bound/MinOption.kt @@ -48,12 +48,12 @@ import io.spine.tools.validation.checkPlaceholders import io.spine.tools.validation.defaultMessage import io.spine.tools.validation.option.MIN import io.spine.tools.validation.option.RANGE -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.MIN_OPERATOR -import io.spine.validation.ErrorPlaceholder.MIN_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.MIN_OPERATOR +import io.spine.validation.StandardPlaceholder.MIN_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * A reaction to add a validation rule to a type whenever the `(min)` field option diff --git a/context/src/main/kotlin/io/spine/tools/validation/bound/RangeOption.kt b/context/src/main/kotlin/io/spine/tools/validation/bound/RangeOption.kt index 82e777a408..e4e0bcf4e2 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/bound/RangeOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/bound/RangeOption.kt @@ -51,11 +51,11 @@ import io.spine.tools.validation.bound.event.rangeFieldDiscovered import io.spine.tools.validation.checkPlaceholders import io.spine.tools.validation.defaultMessage import io.spine.tools.validation.option.RANGE -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE -import io.spine.validation.ErrorPlaceholder.RANGE_VALUE +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.RANGE_VALUE /** * Controls whether a field should be validated with the `(range)` option. diff --git a/context/src/main/kotlin/io/spine/tools/validation/option/ChoiceOption.kt b/context/src/main/kotlin/io/spine/tools/validation/option/ChoiceOption.kt index e07f4d3aca..9c5b113049 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/option/ChoiceOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/option/ChoiceOption.kt @@ -49,8 +49,8 @@ import io.spine.tools.validation.checkPlaceholders import io.spine.tools.validation.defaultMessage import io.spine.tools.validation.event.ChoiceOneofDiscovered import io.spine.tools.validation.event.choiceOneofDiscovered -import io.spine.validation.ErrorPlaceholder.GROUP_PATH -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.GROUP_PATH +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * Controls whether a `oneof` group should be validated with the `(choice)` option. diff --git a/context/src/main/kotlin/io/spine/tools/validation/option/DistinctOption.kt b/context/src/main/kotlin/io/spine/tools/validation/option/DistinctOption.kt index 32e44c5013..3f27180ce1 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/option/DistinctOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/option/DistinctOption.kt @@ -63,11 +63,11 @@ import io.spine.tools.validation.event.DistinctFieldDiscovered import io.spine.tools.validation.event.IfHasDuplicatesOptionDiscovered import io.spine.tools.validation.event.distinctFieldDiscovered import io.spine.tools.validation.event.ifHasDuplicatesOptionDiscovered -import io.spine.validation.ErrorPlaceholder.FIELD_DUPLICATES -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_DUPLICATES +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * Controls whether a field should be validated as `(distinct)`. diff --git a/context/src/main/kotlin/io/spine/tools/validation/option/GoesOption.kt b/context/src/main/kotlin/io/spine/tools/validation/option/GoesOption.kt index 8bb4f9f3fd..6c6295c352 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/option/GoesOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/option/GoesOption.kt @@ -59,11 +59,11 @@ import io.spine.tools.validation.checkPlaceholders import io.spine.tools.validation.defaultMessage import io.spine.tools.validation.event.GoesFieldDiscovered import io.spine.tools.validation.event.goesFieldDiscovered -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.GOES_COMPANION -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.GOES_COMPANION +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * Controls whether a field should be validated with the `(goes)` option. diff --git a/context/src/main/kotlin/io/spine/tools/validation/option/PatternOption.kt b/context/src/main/kotlin/io/spine/tools/validation/option/PatternOption.kt index ad99421af6..38e6729b79 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/option/PatternOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/option/PatternOption.kt @@ -54,12 +54,12 @@ import io.spine.tools.validation.checkPlaceholders import io.spine.tools.validation.defaultMessage import io.spine.tools.validation.event.PatternFieldDiscovered import io.spine.tools.validation.event.patternFieldDiscovered -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE -import io.spine.validation.ErrorPlaceholder.REGEX_MODIFIERS -import io.spine.validation.ErrorPlaceholder.REGEX_PATTERN +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.REGEX_MODIFIERS +import io.spine.validation.StandardPlaceholder.REGEX_PATTERN /** * Controls whether a field should be validated with the `(pattern)` option. diff --git a/context/src/main/kotlin/io/spine/tools/validation/option/RequireOption.kt b/context/src/main/kotlin/io/spine/tools/validation/option/RequireOption.kt index 96e6893d4d..9f656062e0 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/option/RequireOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/option/RequireOption.kt @@ -46,8 +46,8 @@ import io.spine.tools.validation.defaultMessage import io.spine.tools.validation.event.RequireMessageDiscovered import io.spine.tools.validation.event.requireMessageDiscovered import io.spine.tools.validation.option.required.ParseFieldGroups -import io.spine.validation.ErrorPlaceholder.MESSAGE_TYPE -import io.spine.validation.ErrorPlaceholder.REQUIRE_FIELDS +import io.spine.validation.StandardPlaceholder.MESSAGE_TYPE +import io.spine.validation.StandardPlaceholder.REQUIRE_FIELDS /** * Controls whether a message should be validated with the `(require)` option. diff --git a/context/src/main/kotlin/io/spine/tools/validation/option/SetOnceOption.kt b/context/src/main/kotlin/io/spine/tools/validation/option/SetOnceOption.kt index f65b07ff79..34e6069b1c 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/option/SetOnceOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/option/SetOnceOption.kt @@ -63,11 +63,11 @@ import io.spine.tools.validation.event.IfSetAgainOptionDiscovered import io.spine.tools.validation.event.SetOnceFieldDiscovered import io.spine.tools.validation.event.ifSetAgainOptionDiscovered import io.spine.tools.validation.event.setOnceFieldDiscovered -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_PROPOSED_VALUE -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_PROPOSED_VALUE +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * Controls whether a field should be validated with the `(set_once)` option. diff --git a/context/src/main/kotlin/io/spine/tools/validation/option/required/RequiredOption.kt b/context/src/main/kotlin/io/spine/tools/validation/option/required/RequiredOption.kt index 82ebf8e7f1..8093568144 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/option/required/RequiredOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/option/required/RequiredOption.kt @@ -64,9 +64,9 @@ import io.spine.tools.validation.option.IF_MISSING import io.spine.tools.validation.option.REQUIRED import io.spine.tools.validation.option.checkPrimaryApplied import io.spine.tools.validation.option.required.RequiredFieldSupport.isSupported -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * Controls whether a field should be validated as `(required)`. diff --git a/docs/content/docs/validation/developer/adding-a-built-in-option.md b/docs/content/docs/validation/developer/adding-a-built-in-option.md index 832858c8ef..263ba30b0c 100644 --- a/docs/content/docs/validation/developer/adding-a-built-in-option.md +++ b/docs/content/docs/validation/developer/adding-a-built-in-option.md @@ -403,7 +403,7 @@ runtime change is required for the average new option. A new option needs runtime work in three cases: - **It introduces a new error placeholder.** Add the placeholder to - [`ErrorPlaceholder`][error-placeholder] in `:jvm-runtime`, then use it from the reaction + [`StandardPlaceholder`][standard-placeholder] in `:jvm-runtime`, then use it from the reaction and generator. This shared enum update is required, but no additional runtime logic or `TemplateString` schema change is needed because the runtime stores placeholder keys as strings. - **It needs a shared runtime helper.** If the option's generated code would otherwise @@ -530,7 +530,7 @@ too. [views-proto]: https://github.com/SpineEventEngine/validation/blob/master/context/src/main/proto/spine/validation/views.proto [validation-plugin]: https://github.com/SpineEventEngine/validation/blob/master/context/src/main/kotlin/io/spine/tools/validation/ValidationPlugin.kt [default-message]: https://github.com/SpineEventEngine/validation/blob/master/context/src/main/kotlin/io/spine/tools/validation/DefaultErrorMessage.kt -[error-placeholder]: https://github.com/SpineEventEngine/validation/blob/master/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholder.kt +[standard-placeholder]: https://github.com/SpineEventEngine/validation/blob/master/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt [option-generator-pkg]: https://github.com/SpineEventEngine/validation/tree/master/java/src/main/kotlin/io/spine/tools/validation/java/generate/option [java-validation-renderer]: https://github.com/SpineEventEngine/validation/blob/master/java/src/main/kotlin/io/spine/tools/validation/java/JavaValidationRenderer.kt [set-once-renderer]: https://github.com/SpineEventEngine/validation/blob/master/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceRenderer.kt diff --git a/docs/content/docs/validation/developer/runtime-library.md b/docs/content/docs/validation/developer/runtime-library.md index b3a19e088b..bd5fff7c54 100644 --- a/docs/content/docs/validation/developer/runtime-library.md +++ b/docs/content/docs/validation/developer/runtime-library.md @@ -27,7 +27,7 @@ Five groups of types live in the runtime library: | Violation Protobuf | `ValidationError`, `ConstraintViolation`, `TemplateString` | The structured shape of a violation report. | | Exception | `ValidationException` | Thrown by `Builder.build()` when validation fails. | | Markers | `@Validated`, `@NonValidated` | Documentary annotations placed on `build()` and `buildPartial()` return types; not retained at runtime. | -| Validator extension | `MessageValidator`, `ValidatorRegistry`, `DetectedViolation`, `ErrorPlaceholder` | Runtime SPI for attaching custom checks to a message type, including third-party messages. | +| Validator extension | `MessageValidator`, `ValidatorRegistry`, `DetectedViolation`, `Placeholder` | Runtime SPI for attaching custom checks to a message type, including third-party messages. | Two utility entry points round the surface out: the static method `Validate.check(message)` and the Kotlin extensions `M.checkValid()` and `M.copy { … }` in @@ -189,7 +189,7 @@ every problem in one pass. generator emits and every reader resolves. Substitution happens via `TemplateString.format()` (in Kotlin, [`TemplateStringExts.kt`][template-string-exts]) or the static `TemplateStrings.format(...)` (in Java). The placeholder names the runtime -itself fills in are enumerated by [`ErrorPlaceholder`][error-placeholder] +itself fills in are enumerated by [`StandardPlaceholder`][standard-placeholder] — `field.path`, `field.value`, `field.type`, `message.type`, `parent.type`, plus option-specific entries such as `regex.pattern` and `range.value`. @@ -385,5 +385,5 @@ in `:context` and `:java`: anything that *can* be decided at build time *should* [exception-factory]: https://github.com/SpineEventEngine/validation/blob/master/jvm-runtime/src/main/java/io/spine/validation/ExceptionFactory.java [message-extensions]: https://github.com/SpineEventEngine/validation/blob/master/jvm-runtime/src/main/kotlin/io/spine/validation/MessageExtensions.kt [template-string-exts]: https://github.com/SpineEventEngine/validation/blob/master/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt -[error-placeholder]: https://github.com/SpineEventEngine/validation/blob/master/jvm-runtime/src/main/kotlin/io/spine/validation/ErrorPlaceholder.kt +[standard-placeholder]: https://github.com/SpineEventEngine/validation/blob/master/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt [timestamp-validator]: https://github.com/SpineEventEngine/validation/blob/master/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt diff --git a/docs/content/docs/validation/developer/validation-model.md b/docs/content/docs/validation/developer/validation-model.md index cd4418c41b..e5ad33780b 100644 --- a/docs/content/docs/validation/developer/validation-model.md +++ b/docs/content/docs/validation/developer/validation-model.md @@ -304,7 +304,7 @@ validates the template before the event is emitted: ```kotlin private fun String.checkPlaceholders( - supported: Set, + supported: Set, declaration: String, span: Span, file: File, @@ -323,7 +323,7 @@ private fun String.checkPlaceholders( Catching unknown placeholders here, in the model, is what allows the renderer to assume that every placeholder it sees in the projection state has a known meaning. The full list of placeholders for generated validation code is enumerated in -[`ErrorPlaceholder.kt`][error-placeholder]. At runtime, `TemplateString` carries +[`StandardPlaceholder.kt`][standard-placeholder]. At runtime, `TemplateString` carries placeholder keys as strings; the runtime library does not keep a second placeholder enum. When no custom message is provided, the reaction falls back to the option's @@ -378,6 +378,6 @@ consumer-facing version of the same SPI is covered by [option-name]: https://github.com/SpineEventEngine/validation/blob/master/context/src/main/kotlin/io/spine/tools/validation/OptionName.kt [option-names]: https://github.com/SpineEventEngine/validation/blob/master/context/src/main/kotlin/io/spine/tools/validation/option/OptionNames.kt [bound-pkg]: https://github.com/SpineEventEngine/validation/tree/master/context/src/main/kotlin/io/spine/tools/validation/bound -[error-placeholder]: https://github.com/SpineEventEngine/validation/blob/master/jvm-runtime/src/main/kotlin/io/spine/validation/ErrorPlaceholder.kt +[standard-placeholder]: https://github.com/SpineEventEngine/validation/blob/master/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt [default-message]: https://github.com/SpineEventEngine/validation/blob/master/context/src/main/kotlin/io/spine/tools/validation/DefaultErrorMessage.kt [validation-option-spi]: https://github.com/SpineEventEngine/validation/blob/master/java/src/main/kotlin/io/spine/tools/validation/java/ValidationOption.kt diff --git a/docs/dependencies/dependencies.md b/docs/dependencies/dependencies.md index e9ecad1239..21375c6c4d 100644 --- a/docs/dependencies/dependencies.md +++ b/docs/dependencies/dependencies.md @@ -1090,7 +1090,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:50 WEST 2026** using +This report was generated on **Fri May 15 18:33:48 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1791,7 +1791,7 @@ This report was generated on **Fri May 15 16:29:50 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:49 WEST 2026** using +This report was generated on **Fri May 15 18:33:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2864,7 +2864,7 @@ This report was generated on **Fri May 15 16:29:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:50 WEST 2026** using +This report was generated on **Fri May 15 18:33:48 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3961,7 +3961,7 @@ This report was generated on **Fri May 15 16:29:50 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:50 WEST 2026** using +This report was generated on **Fri May 15 18:33:48 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4015,7 +4015,7 @@ This report was generated on **Fri May 15 16:29:50 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:48 WEST 2026** using +This report was generated on **Fri May 15 18:33:45 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4822,7 +4822,7 @@ This report was generated on **Fri May 15 16:29:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:50 WEST 2026** using +This report was generated on **Fri May 15 18:33:48 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5511,7 +5511,7 @@ This report was generated on **Fri May 15 16:29:50 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:49 WEST 2026** using +This report was generated on **Fri May 15 18:33:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5976,7 +5976,7 @@ This report was generated on **Fri May 15 16:29:49 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:49 WEST 2026** using +This report was generated on **Fri May 15 18:33:46 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6602,7 +6602,7 @@ This report was generated on **Fri May 15 16:29:49 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:49 WEST 2026** using +This report was generated on **Fri May 15 18:33:46 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7170,7 +7170,436 @@ This report was generated on **Fri May 15 16:29:49 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:49 WEST 2026** using +This report was generated on **Fri May 15 18:33:47 WEST 2026** using +[Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under +[Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). + + + + +# Dependencies of `io.spine.tools:validation-time:2.0.0-SNAPSHOT.421` + +## Runtime +1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. + * **Project URL:** [http://findbugs.sourceforge.net/](http://findbugs.sourceforge.net/) + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.code.gson. **Name** : gson. **Version** : 2.8.9. + * **Project URL:** [https://github.com/google/gson/gson](https://github.com/google/gson/gson) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.errorprone. **Name** : error_prone_annotations. **Version** : 2.41.0. + * **Project URL:** [https://errorprone.info/error_prone_annotations](https://errorprone.info/error_prone_annotations) + * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.guava. **Name** : failureaccess. **Version** : 1.0.3. + * **Project URL:** [https://github.com/google/guava/](https://github.com/google/guava/) + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.guava. **Name** : guava. **Version** : 33.5.0-jre. + * **Project URL:** [https://github.com/google/guava](https://github.com/google/guava) + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.guava. **Name** : listenablefuture. **Version** : 9999.0-empty-to-avoid-conflict-with-guava. + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.j2objc. **Name** : j2objc-annotations. **Version** : 3.1. + * **Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.protobuf. **Name** : protobuf-java. **Version** : 4.34.1. + * **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + +1. **Group** : com.google.protobuf. **Name** : protobuf-java-util. **Version** : 4.34.1. + * **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + +1. **Group** : com.google.protobuf. **Name** : protobuf-kotlin. **Version** : 4.34.1. + * **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + +1. **Group** : org.jetbrains. **Name** : annotations. **Version** : 13.0. + * **Project URL:** [http://www.jetbrains.org](http://www.jetbrains.org) + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-bom. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-reflect. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-stdlib. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-coroutines-bom. **Version** : 1.10.2. + * **Project URL:** [https://github.com/Kotlin/kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jspecify. **Name** : jspecify. **Version** : 1.0.0. + * **Project URL:** [http://jspecify.org/](http://jspecify.org/) + * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +## Compile, tests, and tooling +1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. + * **Project URL:** [https://github.com/FasterXML/jackson-bom](https://github.com/FasterXML/jackson-bom) + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.fasterxml.jackson.core. **Name** : jackson-annotations. **Version** : 2.20. + * **Project URL:** [https://github.com/FasterXML/jackson](https://github.com/FasterXML/jackson) + * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.fasterxml.jackson.core. **Name** : jackson-core. **Version** : 2.20.0. + * **Project URL:** [https://github.com/FasterXML/jackson-core](https://github.com/FasterXML/jackson-core) + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.fasterxml.jackson.core. **Name** : jackson-databind. **Version** : 2.20.0. + * **Project URL:** [https://github.com/FasterXML/jackson](https://github.com/FasterXML/jackson) + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.fasterxml.jackson.datatype. **Name** : jackson-datatype-guava. **Version** : 2.20.0. + * **Project URL:** [https://github.com/FasterXML/jackson-datatypes-collections](https://github.com/FasterXML/jackson-datatypes-collections) + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.fasterxml.jackson.datatype. **Name** : jackson-datatype-jdk8. **Version** : 2.20.0. + * **Project URL:** [https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8](https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8) + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.fasterxml.jackson.module. **Name** : jackson-module-parameter-names. **Version** : 2.20.0. + * **Project URL:** [https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names](https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names) + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.auto.value. **Name** : auto-value-annotations. **Version** : 1.11.0. + * **Project URL:** [https://github.com/google/auto/tree/main/value](https://github.com/google/auto/tree/main/value) + * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. + * **Project URL:** [http://findbugs.sourceforge.net/](http://findbugs.sourceforge.net/) + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.code.gson. **Name** : gson. **Version** : 2.8.9. + * **Project URL:** [https://github.com/google/gson/gson](https://github.com/google/gson/gson) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.errorprone. **Name** : error_prone_annotations. **Version** : 2.41.0. + * **Project URL:** [https://errorprone.info/error_prone_annotations](https://errorprone.info/error_prone_annotations) + * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.errorprone. **Name** : error_prone_type_annotations. **Version** : 2.36.0. + * **Project URL:** [https://errorprone.info/error_prone_type_annotations](https://errorprone.info/error_prone_type_annotations) + * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.flogger. **Name** : flogger. **Version** : 0.7.4. + * **Project URL:** [https://github.com/google/flogger](https://github.com/google/flogger) + * **License:** [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.flogger. **Name** : flogger-system-backend. **Version** : 0.7.4. + * **Project URL:** [https://github.com/google/flogger](https://github.com/google/flogger) + * **License:** [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.guava. **Name** : failureaccess. **Version** : 1.0.3. + * **Project URL:** [https://github.com/google/guava/](https://github.com/google/guava/) + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.guava. **Name** : guava. **Version** : 33.5.0-jre. + * **Project URL:** [https://github.com/google/guava](https://github.com/google/guava) + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.guava. **Name** : guava-testlib. **Version** : 33.5.0-jre. + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.guava. **Name** : listenablefuture. **Version** : 9999.0-empty-to-avoid-conflict-with-guava. + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.j2objc. **Name** : j2objc-annotations. **Version** : 3.1. + * **Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) + * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.protobuf. **Name** : protobuf-java. **Version** : 4.34.1. + * **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + +1. **Group** : com.google.protobuf. **Name** : protobuf-java-util. **Version** : 4.34.1. + * **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + +1. **Group** : com.google.protobuf. **Name** : protobuf-kotlin. **Version** : 4.34.1. + * **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + +1. **Group** : com.google.protobuf. **Name** : protoc. **Version** : 4.34.1. + * **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.truth. **Name** : truth. **Version** : 1.4.4. + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.truth.extensions. **Name** : truth-java8-extension. **Version** : 1.4.4. + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.truth.extensions. **Name** : truth-liteproto-extension. **Version** : 1.4.4. + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.google.truth.extensions. **Name** : truth-proto-extension. **Version** : 1.4.4. + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : com.palantir.javaformat. **Name** : palantir-java-format. **Version** : 2.75.0. + * **Project URL:** [https://github.com/palantir/palantir-java-format](https://github.com/palantir/palantir-java-format) + * **License:** [The Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) + +1. **Group** : com.palantir.javaformat. **Name** : palantir-java-format-spi. **Version** : 2.75.0. + * **Project URL:** [https://github.com/palantir/palantir-java-format](https://github.com/palantir/palantir-java-format) + * **License:** [The Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) + +1. **Group** : io.github.java-diff-utils. **Name** : java-diff-utils. **Version** : 4.12. + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : io.github.java-diff-utils. **Name** : java-diff-utils. **Version** : 4.16. + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : io.kotest. **Name** : kotest-assertions-core. **Version** : 6.1.11. + * **Project URL:** [https://github.com/kotest/kotest](https://github.com/kotest/kotest) + * **License:** [Apache-2.0](https://opensource.org/licenses/Apache-2.0) + +1. **Group** : io.kotest. **Name** : kotest-assertions-core-jvm. **Version** : 6.1.11. + * **Project URL:** [https://github.com/kotest/kotest](https://github.com/kotest/kotest) + * **License:** [Apache-2.0](https://opensource.org/licenses/Apache-2.0) + +1. **Group** : io.kotest. **Name** : kotest-assertions-shared. **Version** : 6.1.11. + * **Project URL:** [https://github.com/kotest/kotest](https://github.com/kotest/kotest) + * **License:** [Apache-2.0](https://opensource.org/licenses/Apache-2.0) + +1. **Group** : io.kotest. **Name** : kotest-assertions-shared-jvm. **Version** : 6.1.11. + * **Project URL:** [https://github.com/kotest/kotest](https://github.com/kotest/kotest) + * **License:** [Apache-2.0](https://opensource.org/licenses/Apache-2.0) + +1. **Group** : io.kotest. **Name** : kotest-common. **Version** : 6.1.11. + * **Project URL:** [https://github.com/kotest/kotest](https://github.com/kotest/kotest) + * **License:** [Apache-2.0](https://opensource.org/licenses/Apache-2.0) + +1. **Group** : io.kotest. **Name** : kotest-common-jvm. **Version** : 6.1.11. + * **Project URL:** [https://github.com/kotest/kotest](https://github.com/kotest/kotest) + * **License:** [Apache-2.0](https://opensource.org/licenses/Apache-2.0) + +1. **Group** : junit. **Name** : junit. **Version** : 4.13.2. + * **Project URL:** [http://junit.org](http://junit.org) + * **License:** [Eclipse Public License 1.0](http://www.eclipse.org/legal/epl-v10.html) + +1. **Group** : org.apiguardian. **Name** : apiguardian-api. **Version** : 1.1.2. + * **Project URL:** [https://github.com/apiguardian-team/apiguardian](https://github.com/apiguardian-team/apiguardian) + * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.checkerframework. **Name** : checker-compat-qual. **Version** : 2.5.3. + * **Project URL:** [https://checkerframework.org](https://checkerframework.org) + * **License:** [GNU General Public License, version 2 (GPL2), with the classpath exception](http://www.gnu.org/software/classpath/license.html) + * **License:** [The MIT License](http://opensource.org/licenses/MIT) + +1. **Group** : org.checkerframework. **Name** : checker-qual. **Version** : 3.40.0. + * **Project URL:** [https://checkerframework.org/](https://checkerframework.org/) + * **License:** [The MIT License](http://opensource.org/licenses/MIT) + +1. **Group** : org.functionaljava. **Name** : functionaljava. **Version** : 4.8. + * **Project URL:** [http://functionaljava.org/](http://functionaljava.org/) + * **License:** [The BSD3 License](https://github.com/functionaljava/functionaljava/blob/master/etc/LICENCE) + +1. **Group** : org.hamcrest. **Name** : hamcrest-core. **Version** : 1.3. + * **License:** [New BSD License](http://www.opensource.org/licenses/bsd-license.php) + +1. **Group** : org.jetbrains. **Name** : annotations. **Version** : 13.0. + * **Project URL:** [http://www.jetbrains.org](http://www.jetbrains.org) + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains. **Name** : annotations. **Version** : 23.0.0. + * **Project URL:** [https://github.com/JetBrains/java-annotations](https://github.com/JetBrains/java-annotations) + * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : abi-tools. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : abi-tools-api. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-bom. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-build-tools-api. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-build-tools-compat. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-build-tools-cri-impl. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-build-tools-impl. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-compiler-embeddable. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-compiler-runner. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-daemon-client. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-daemon-embeddable. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-klib-abi-reader. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-klib-commonizer-embeddable. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-metadata-jvm. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-reflect. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-script-runtime. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-scripting-common. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-scripting-compiler-embeddable. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-scripting-compiler-impl-embeddable. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-scripting-jvm. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-stdlib. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-tooling-core. **Version** : 2.3.20. + * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) + * **License:** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlinx. **Name** : atomicfu. **Version** : 0.29.0. + * **Project URL:** [https://github.com/Kotlin/kotlinx.atomicfu](https://github.com/Kotlin/kotlinx.atomicfu) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlinx. **Name** : atomicfu-jvm. **Version** : 0.29.0. + * **Project URL:** [https://github.com/Kotlin/kotlinx.atomicfu](https://github.com/Kotlin/kotlinx.atomicfu) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-coroutines-bom. **Version** : 1.10.2. + * **Project URL:** [https://github.com/Kotlin/kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-coroutines-core. **Version** : 1.10.2. + * **Project URL:** [https://github.com/Kotlin/kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-coroutines-core-jvm. **Version** : 1.10.2. + * **Project URL:** [https://github.com/Kotlin/kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-coroutines-jdk8. **Version** : 1.10.2. + * **Project URL:** [https://github.com/Kotlin/kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-coroutines-test. **Version** : 1.10.2. + * **Project URL:** [https://github.com/Kotlin/kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-coroutines-test-jvm. **Version** : 1.10.2. + * **Project URL:** [https://github.com/Kotlin/kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-datetime. **Version** : 0.7.1. + * **Project URL:** [https://github.com/Kotlin/kotlinx-datetime](https://github.com/Kotlin/kotlinx-datetime) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-datetime-jvm. **Version** : 0.7.1. + * **Project URL:** [https://github.com/Kotlin/kotlinx-datetime](https://github.com/Kotlin/kotlinx-datetime) + * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.jspecify. **Name** : jspecify. **Version** : 1.0.0. + * **Project URL:** [http://jspecify.org/](http://jspecify.org/) + * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.junit. **Name** : junit-bom. **Version** : 6.0.3. + * **Project URL:** [https://junit.org/](https://junit.org/) + * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group** : org.junit-pioneer. **Name** : junit-pioneer. **Version** : 2.3.0. + * **Project URL:** [https://junit-pioneer.org/](https://junit-pioneer.org/) + * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-api. **Version** : 6.0.3. + * **Project URL:** [https://junit.org/](https://junit.org/) + * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-engine. **Version** : 6.0.3. + * **Project URL:** [https://junit.org/](https://junit.org/) + * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-params. **Version** : 6.0.3. + * **Project URL:** [https://junit.org/](https://junit.org/) + * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group** : org.junit.platform. **Name** : junit-platform-commons. **Version** : 6.0.3. + * **Project URL:** [https://junit.org/](https://junit.org/) + * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group** : org.junit.platform. **Name** : junit-platform-engine. **Version** : 6.0.3. + * **Project URL:** [https://junit.org/](https://junit.org/) + * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group** : org.junit.platform. **Name** : junit-platform-launcher. **Version** : 6.0.3. + * **Project URL:** [https://junit.org/](https://junit.org/) + * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group** : org.opentest4j. **Name** : opentest4j. **Version** : 1.3.0. + * **Project URL:** [https://github.com/ota4j-team/opentest4j](https://github.com/ota4j-team/opentest4j) + * **License:** [The Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group** : org.ow2.asm. **Name** : asm. **Version** : 9.7. + * **Project URL:** [http://asm.ow2.io/](http://asm.ow2.io/) + * **License:** [BSD-3-Clause](https://asm.ow2.io/license.html) + * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) + + +The dependencies distributed under several licenses, are used according their commercial-use-friendly license. + +This report was generated on **Fri May 15 18:33:46 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7781,7 +8210,7 @@ This report was generated on **Fri May 15 16:29:49 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:49 WEST 2026** using +This report was generated on **Fri May 15 18:33:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8526,7 +8955,7 @@ This report was generated on **Fri May 15 16:29:49 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:49 WEST 2026** using +This report was generated on **Fri May 15 18:33:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8766,7 +9195,7 @@ This report was generated on **Fri May 15 16:29:49 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:48 WEST 2026** using +This report was generated on **Fri May 15 18:33:46 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9116,6 +9545,6 @@ This report was generated on **Fri May 15 16:29:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:48 WEST 2026** using +This report was generated on **Fri May 15 18:33:46 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt b/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt index c5f06d3964..afb62951f9 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt @@ -33,7 +33,7 @@ import io.spine.tools.compiler.jvm.Expression import io.spine.tools.compiler.jvm.StringLiteral import io.spine.tools.compiler.jvm.mapExpression import io.spine.tools.compiler.jvm.newBuilder -import io.spine.validation.ErrorPlaceholder +import io.spine.validation.Placeholder import io.spine.validation.TemplateString import io.spine.validation.checkPlaceholdersHasValue @@ -41,8 +41,8 @@ import io.spine.validation.checkPlaceholdersHasValue * Yields an expression that creates a new instance of [TemplateString]. * * Note that this method differs from the one provided by the API module - * in that it accepts placeholder keys as [ErrorPlaceholder]. This enum - * contains placeholder keys for built-in options. + * in that it accepts placeholder keys as [Placeholder]. The standard + * placeholder keys for built-in options are provided by [io.spine.validation.StandardPlaceholder]. * * @param placeholders The supported placeholders and their values. * @param optionName The name of the option, which declared the provided [placeholders]. @@ -50,7 +50,7 @@ import io.spine.validation.checkPlaceholdersHasValue @JvmName("templateStringExp") public fun templateString( template: String, - placeholders: Map>, + placeholders: Map>, optionName: String ): Expression = withStringPlaceholders(template, placeholders.mapKeys { it.key.value }, optionName) diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/ChoiceGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/ChoiceGenerator.kt index d25faf42b8..3d43fa67e0 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/ChoiceGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/ChoiceGenerator.kt @@ -47,9 +47,9 @@ import io.spine.tools.validation.java.generate.ValidateScope.parentPath import io.spine.tools.validation.java.generate.ValidateScope.violations import io.spine.tools.validation.option.CHOICE import io.spine.validation.ConstraintViolation -import io.spine.validation.ErrorPlaceholder -import io.spine.validation.ErrorPlaceholder.GROUP_PATH -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.Placeholder +import io.spine.validation.StandardPlaceholder.GROUP_PATH +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * The generator for the `(choice)` option. @@ -110,7 +110,7 @@ private class GenerateChoice(private val view: ChoiceOneof) { private fun supportedPlaceholders( groupPath: Expression, typeName: Expression, - ): Map> = mapOf( + ): Map> = mapOf( GROUP_PATH to groupPath.joinToString(), PARENT_TYPE to typeName ) diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/DistinctGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/DistinctGenerator.kt index 7b98976c54..338a53106c 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/DistinctGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/DistinctGenerator.kt @@ -61,12 +61,12 @@ import io.spine.tools.validation.java.generate.ValidateScope.parentPath import io.spine.tools.validation.java.generate.ValidateScope.violations import io.spine.tools.validation.option.PATTERN import io.spine.validation.ConstraintViolation -import io.spine.validation.ErrorPlaceholder -import io.spine.validation.ErrorPlaceholder.FIELD_DUPLICATES -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.Placeholder +import io.spine.validation.StandardPlaceholder.FIELD_DUPLICATES +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * The generator for the `(distinct)` option. @@ -179,7 +179,7 @@ private class GenerateDistinct(private val view: DistinctField) { typeName: Expression, fieldValue: Expression<*>, duplicates: Expression<*> - ): Map> = mapOf( + ): Map> = mapOf( FIELD_PATH to fieldPath.joinToString(), FIELD_VALUE to fieldType.stringValueOf(fieldValue), FIELD_TYPE to StringLiteral(fieldType.name), diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/GoesGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/GoesGenerator.kt index 6f60ffed40..745f4ca366 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/GoesGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/GoesGenerator.kt @@ -53,12 +53,12 @@ import io.spine.tools.validation.java.generate.ValidateScope.parentPath import io.spine.tools.validation.java.generate.ValidateScope.violations import io.spine.tools.validation.option.GOES import io.spine.validation.ConstraintViolation -import io.spine.validation.ErrorPlaceholder -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.GOES_COMPANION -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.Placeholder +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.GOES_COMPANION +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * The generator for the `(goes)` option. @@ -126,7 +126,7 @@ private class GenerateGoes( fieldPath: Expression, typeName: Expression, fieldValue: Expression<*>, - ): Map> = mapOf( + ): Map> = mapOf( FIELD_PATH to fieldPath.joinToString(), FIELD_VALUE to fieldType.stringValueOf(fieldValue), FIELD_TYPE to StringLiteral(fieldType.name), diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/PatternGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/PatternGenerator.kt index 08efd5ede4..d02e05c1f8 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/PatternGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/PatternGenerator.kt @@ -67,13 +67,13 @@ import io.spine.tools.validation.option.PATTERN import io.spine.tools.validation.option.isRepeatedString import io.spine.tools.validation.option.isSingularString import io.spine.validation.ConstraintViolation -import io.spine.validation.ErrorPlaceholder -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE -import io.spine.validation.ErrorPlaceholder.REGEX_MODIFIERS -import io.spine.validation.ErrorPlaceholder.REGEX_PATTERN +import io.spine.validation.Placeholder +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.REGEX_MODIFIERS +import io.spine.validation.StandardPlaceholder.REGEX_PATTERN import java.util.regex.Matcher import java.util.regex.Pattern @@ -250,7 +250,7 @@ private class GeneratePattern(private val view: PatternField) { fieldPath: Expression, typeName: Expression, fieldValue: Expression, - ): Map> = mapOf( + ): Map> = mapOf( FIELD_PATH to fieldPath.joinToString(), FIELD_VALUE to fieldValue, FIELD_TYPE to StringLiteral(fieldType.name), diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequireOptionGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequireOptionGenerator.kt index 2c2e29310d..17b48a0b20 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequireOptionGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequireOptionGenerator.kt @@ -50,9 +50,9 @@ import io.spine.tools.validation.java.generate.ValidateScope.violations import io.spine.tools.validation.java.generate.mangled import io.spine.tools.validation.option.REQUIRE import io.spine.validation.ConstraintViolation -import io.spine.validation.ErrorPlaceholder -import io.spine.validation.ErrorPlaceholder.MESSAGE_TYPE -import io.spine.validation.ErrorPlaceholder.REQUIRE_FIELDS +import io.spine.validation.Placeholder +import io.spine.validation.StandardPlaceholder.MESSAGE_TYPE +import io.spine.validation.StandardPlaceholder.REQUIRE_FIELDS /** * The generator for the `(require)` option. @@ -141,7 +141,7 @@ private class GenerateRequire( return constraintViolation(errorMessage, typeNameStr, fieldPath = null, fieldValue = null) } - private fun supportedPlaceholders(): Map> = mapOf( + private fun supportedPlaceholders(): Map> = mapOf( MESSAGE_TYPE to StringLiteral(view.id.qualifiedName), REQUIRE_FIELDS to StringLiteral(view.specifiedGroups) ) diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequiredGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequiredGenerator.kt index 6e80f8a85f..916359a554 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequiredGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequiredGenerator.kt @@ -50,10 +50,10 @@ import io.spine.tools.validation.java.generate.ValidateScope.parentPath import io.spine.tools.validation.java.generate.ValidateScope.violations import io.spine.tools.validation.option.IF_MISSING import io.spine.validation.ConstraintViolation -import io.spine.validation.ErrorPlaceholder -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.Placeholder +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * The generator for `(required)` option. @@ -116,7 +116,7 @@ private class GenerateRequired( private fun supportedPlaceholders( fieldPath: Expression, typeName: Expression, - ): Map> = mapOf( + ): Map> = mapOf( FIELD_PATH to fieldPath.joinToString(), FIELD_TYPE to StringLiteral(field.type.name), PARENT_TYPE to typeName diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/BoundedFieldGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/BoundedFieldGenerator.kt index e630732e1c..6f98fc6d12 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/BoundedFieldGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/BoundedFieldGenerator.kt @@ -68,7 +68,7 @@ import io.spine.tools.validation.java.generate.option.bound.Docs.SCALAR_TYPES import io.spine.tools.validation.java.generate.option.bound.Docs.UNSIGNED_API import io.spine.type.TypeName import io.spine.validation.ConstraintViolation -import io.spine.validation.ErrorPlaceholder +import io.spine.validation.Placeholder /** * An abstract base for field generators that restrict the range of numeric fields. @@ -170,7 +170,7 @@ internal abstract class BoundedFieldGenerator( fieldPath: Expression, typeName: Expression, fieldValue: Expression<*>, - ): Map> + ): Map> /** * Returns a number expression for this [NumericBound]. diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MaxGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MaxGenerator.kt index f460c48716..569c1fff71 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MaxGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MaxGenerator.kt @@ -44,13 +44,13 @@ import io.spine.tools.validation.java.expression.joinToString import io.spine.tools.validation.java.generate.OptionGenerator import io.spine.tools.validation.java.generate.SingleOptionCode import io.spine.tools.validation.option.MAX -import io.spine.validation.ErrorPlaceholder -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.MAX_OPERATOR -import io.spine.validation.ErrorPlaceholder.MAX_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.Placeholder +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.MAX_OPERATOR +import io.spine.validation.StandardPlaceholder.MAX_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * The generator for the `(max)` option. @@ -101,7 +101,7 @@ private class GenerateMax(private val view: MaxField) : BoundedFieldGenerator(vi fieldPath: Expression, typeName: Expression, fieldValue: Expression<*>, - ): Map> = mapOf( + ): Map> = mapOf( FIELD_PATH to fieldPath.joinToString(), FIELD_VALUE to StringClass.call("valueOf", fieldValue), FIELD_TYPE to StringLiteral(fieldType.name), diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MinGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MinGenerator.kt index 5d52805601..70fb10ef73 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MinGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MinGenerator.kt @@ -44,13 +44,13 @@ import io.spine.tools.validation.java.expression.joinToString import io.spine.tools.validation.java.generate.OptionGenerator import io.spine.tools.validation.java.generate.SingleOptionCode import io.spine.tools.validation.option.MIN -import io.spine.validation.ErrorPlaceholder -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.MIN_OPERATOR -import io.spine.validation.ErrorPlaceholder.MIN_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.Placeholder +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.MIN_OPERATOR +import io.spine.validation.StandardPlaceholder.MIN_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * The generator for `(min)` option. @@ -101,7 +101,7 @@ private class GenerateMin(private val view: MinField) : BoundedFieldGenerator(vi fieldPath: Expression, typeName: Expression, fieldValue: Expression<*>, - ): Map> = mapOf( + ): Map> = mapOf( FIELD_PATH to fieldPath.joinToString(), FIELD_VALUE to StringClass.call("valueOf", fieldValue), FIELD_TYPE to StringLiteral(fieldType.name), diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/RangeGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/RangeGenerator.kt index 72d257cc9f..c670158f8a 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/RangeGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/RangeGenerator.kt @@ -45,12 +45,12 @@ import io.spine.tools.validation.java.expression.joinToString import io.spine.tools.validation.java.generate.OptionGenerator import io.spine.tools.validation.java.generate.SingleOptionCode import io.spine.tools.validation.option.RANGE -import io.spine.validation.ErrorPlaceholder -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE -import io.spine.validation.ErrorPlaceholder.RANGE_VALUE +import io.spine.validation.Placeholder +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.RANGE_VALUE /** * The generator for `(range)` option. @@ -113,7 +113,7 @@ private class GenerateRange( fieldPath: Expression, typeName: Expression, fieldValue: Expression<*>, - ): Map> = mapOf( + ): Map> = mapOf( FIELD_PATH to fieldPath.joinToString(), FIELD_VALUE to StringClass.call("valueOf", fieldValue), FIELD_TYPE to StringLiteral(fieldType.name), diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceConstraintViolation.kt b/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceConstraintViolation.kt index b3edb1b465..4732782c94 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceConstraintViolation.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceConstraintViolation.kt @@ -38,11 +38,12 @@ import io.spine.tools.validation.java.expression.constraintViolation import io.spine.tools.validation.java.expression.templateString import io.spine.tools.validation.option.IF_SET_AGAIN import io.spine.validation.ConstraintViolation -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_PROPOSED_VALUE -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.Placeholder +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_PROPOSED_VALUE +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * Builds a [ConstraintViolation] instance for the given field. @@ -88,7 +89,7 @@ internal class SetOnceConstraintViolation( private fun supportedPlaceholders( currentValue: Expression, newValue: Expression - ) = mapOf( + ): Map> = mapOf( FIELD_PATH to StringLiteral(fieldName), FIELD_TYPE to StringLiteral(fieldType), FIELD_VALUE to currentValue, diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/Placeholder.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/Placeholder.kt new file mode 100644 index 0000000000..2899856d9c --- /dev/null +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/Placeholder.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2026, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.validation + +/** + * A template placeholder that can be referenced from error messages. + * + * Implementations enumerate placeholder names that can be used within Protobuf definitions. + * The standard set of placeholders is provided by [StandardPlaceholder]. Additional + * placeholders may be contributed by extensions (e.g., Spine Time) by introducing + * their own enums implementing this interface. + */ +public interface Placeholder { + + /** + * The placeholder name as it appears in a template string (e.g., `field.path`). + */ + public val value: String +} diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/ErrorPlaceholder.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt similarity index 88% rename from jvm-runtime/src/main/kotlin/io/spine/validation/ErrorPlaceholder.kt rename to jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt index f2a6bd5ad9..aa99f8feff 100644 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/ErrorPlaceholder.kt +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt @@ -27,7 +27,7 @@ package io.spine.validation /** - * A template placeholder that can be used in error messages. + * The standard set of [Placeholder]s that can be used in error messages. * * Enumerates placeholder names that can be used within Protobuf definitions. * Each validation option declares the supported placeholders. Take a look at @@ -36,7 +36,7 @@ package io.spine.validation * The enum is used by the compiler model and Java renderer when validating and rendering * built-in option error messages. */ -public enum class ErrorPlaceholder(public val value: String) { +public enum class StandardPlaceholder(override val value: String) : Placeholder { // Common placeholders. FIELD_PATH("field.path"), @@ -70,7 +70,7 @@ public enum class ErrorPlaceholder(public val value: String) { } @Deprecated( - message = "Please use `ErrorPlaceholder` instead.", - replaceWith = ReplaceWith("ErrorPlaceholder") + message = "Please use `StandardPlaceholder` instead.", + replaceWith = ReplaceWith("StandardPlaceholder") ) -public typealias RuntimeErrorPlaceholder = ErrorPlaceholder +public typealias RuntimeErrorPlaceholder = StandardPlaceholder diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt index d44d5335b8..0be5bfe949 100644 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt @@ -29,11 +29,11 @@ package io.spine.validation import io.spine.code.proto.FieldDeclaration -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.GOES_COMPANION -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE -import io.spine.validation.ErrorPlaceholder.REGEX_PATTERN +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.GOES_COMPANION +import io.spine.validation.StandardPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.REGEX_PATTERN import kotlin.collections.iterator /** diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt index b88a0ee4df..956ba481e1 100644 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt @@ -32,8 +32,8 @@ import com.google.protobuf.util.Timestamps import com.google.protobuf.util.Timestamps.MAX_VALUE import com.google.protobuf.util.Timestamps.MIN_VALUE import io.spine.base.fieldPath -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.RANGE_VALUE +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.RANGE_VALUE /** * Validates [Timestamp] messages. diff --git a/tests/validating/src/test/kotlin/io/spine/test/options/goes/GoesViolationITest.kt b/tests/validating/src/test/kotlin/io/spine/test/options/goes/GoesViolationITest.kt index 1653fe678e..0dbc00c7df 100644 --- a/tests/validating/src/test/kotlin/io/spine/test/options/goes/GoesViolationITest.kt +++ b/tests/validating/src/test/kotlin/io/spine/test/options/goes/GoesViolationITest.kt @@ -36,11 +36,11 @@ import io.spine.test.options.set import io.spine.test.options.asPlaceholderValue import io.spine.test.tools.validate.GoesCustomMessage import io.spine.test.tools.validate.GoesDefaultMessage -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.GOES_COMPANION -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.GOES_COMPANION +import io.spine.validation.StandardPlaceholder.PARENT_TYPE import io.spine.validation.ValidationException import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.assertThrows diff --git a/tests/validating/src/test/kotlin/io/spine/test/options/setonce/SetOnceViolationITest.kt b/tests/validating/src/test/kotlin/io/spine/test/options/setonce/SetOnceViolationITest.kt index 0b13cc33eb..b5f984a69c 100644 --- a/tests/validating/src/test/kotlin/io/spine/test/options/setonce/SetOnceViolationITest.kt +++ b/tests/validating/src/test/kotlin/io/spine/test/options/setonce/SetOnceViolationITest.kt @@ -41,11 +41,11 @@ import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.assertThrows import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource -import io.spine.validation.ErrorPlaceholder.FIELD_PATH -import io.spine.validation.ErrorPlaceholder.FIELD_PROPOSED_VALUE -import io.spine.validation.ErrorPlaceholder.FIELD_TYPE -import io.spine.validation.ErrorPlaceholder.FIELD_VALUE -import io.spine.validation.ErrorPlaceholder.PARENT_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_PATH +import io.spine.validation.StandardPlaceholder.FIELD_PROPOSED_VALUE +import io.spine.validation.StandardPlaceholder.FIELD_TYPE +import io.spine.validation.StandardPlaceholder.FIELD_VALUE +import io.spine.validation.StandardPlaceholder.PARENT_TYPE /** * Tests [ConstraintViolation][io.spine.validation.ConstraintViolation]s created by `(set_once)`. From e83dd687342d49182b52d99ec343b8b64469ea4c Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 19:01:18 +0100 Subject: [PATCH 10/36] Bump base version -> `2.0.0-SNAPSHOT.388` --- buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt index 463cbf2b1f..531fe788ac 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt @@ -33,8 +33,8 @@ package io.spine.dependency.local */ @Suppress("ConstPropertyName", "unused") object Base { - const val version = "2.0.0-SNAPSHOT.387" - const val versionForBuildScript = "2.0.0-SNAPSHOT.387" + const val version = "2.0.0-SNAPSHOT.388" + const val versionForBuildScript = "2.0.0-SNAPSHOT.388" const val group = Spine.group private const val prefix = "spine" const val libModule = "$prefix-base" From 51ffaaf5a8cc5a6d6dee747e39381f43cec31ef5 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 19:01:43 +0100 Subject: [PATCH 11/36] Move `TemplateString` and `Placeholder` to `base` Migrate `TemplateString` Protobuf message, the `Placeholder` interface, and the general-purpose template string extensions from `jvm-runtime` to the `io.spine.string` package in the `base` module. Validation-specific extensions (`withField`, `withCompanion`, `withRegex`) stay here. Follow-up: the upstream `core-jvm-compiler-plugin` still emits `io.spine.validation.TemplateString.newBuilder()` into generated Java for `:context`'s own option messages. Republishing the compiler plugin against the new base is required to unblock `:context:compileJava`. --- .../tools/validation/ErrorPlaceholders.kt | 4 +- .../validation/java/expression/ClassNames.kt | 2 +- .../java/expression/ConstraintViolations.kt | 2 +- .../java/expression/TemplateStrings.kt | 6 +- .../java/generate/ValidatorGenerator.kt | 2 +- .../java/generate/option/ChoiceGenerator.kt | 2 +- .../java/generate/option/DistinctGenerator.kt | 2 +- .../java/generate/option/GoesGenerator.kt | 2 +- .../java/generate/option/PatternGenerator.kt | 2 +- .../generate/option/RequireOptionGenerator.kt | 2 +- .../java/generate/option/RequiredGenerator.kt | 2 +- .../option/bound/BoundedFieldGenerator.kt | 2 +- .../generate/option/bound/MaxGenerator.kt | 2 +- .../generate/option/bound/MinGenerator.kt | 2 +- .../generate/option/bound/RangeGenerator.kt | 2 +- .../setonce/SetOnceConstraintViolation.kt | 2 +- .../io/spine/validation/ViolationText.java | 2 +- .../io/spine/validation/DetectedViolation.kt | 1 + .../kotlin/io/spine/validation/Placeholder.kt | 43 ------- .../spine/validation/StandardPlaceholder.kt | 2 + .../io/spine/validation/TemplateStringExts.kt | 103 +--------------- .../io/spine/validation/TimestampValidator.kt | 1 + .../io/spine/validation/ValidatorRegistry.kt | 1 + .../spine/validation/template_string.proto | 70 ----------- .../spine/validation/validation_error.proto | 6 +- .../validation/TemplateStringExtsSpec.kt | 111 ------------------ .../spine/validation/ValidatorRegistrySpec.kt | 1 + .../spine/validation/given/TemplateStrings.kt | 4 +- .../spine/validation/test/ErrorMessageSpec.kt | 2 +- .../io/spine/validation/test/MinRuleITest.kt | 2 +- .../spine/validation/test/PatternRuleITest.kt | 2 +- .../validation/test/RequiredRuleITest.kt | 4 +- .../validation/test/ValidateRuleITest.kt | 2 +- .../io/spine/validation/option/ChoiceSpec.kt | 2 +- .../io/spine/test/options/ChoiceITest.kt | 2 +- .../test/options/NumberConstraintsITest.kt | 2 +- .../test/options/required/RequireITest.kt | 2 +- .../tools/validation/assertions/Assertions.kt | 2 +- .../validation/test/EarphonesValidator.kt | 4 +- .../tools/validation/test/TheOnlyTimeValid.kt | 4 +- .../spine/validation/java/IsRequiredSpec.kt | 2 +- 41 files changed, 48 insertions(+), 367 deletions(-) delete mode 100644 jvm-runtime/src/main/kotlin/io/spine/validation/Placeholder.kt delete mode 100644 jvm-runtime/src/main/proto/spine/validation/template_string.proto delete mode 100644 jvm-runtime/src/test/kotlin/io/spine/validation/TemplateStringExtsSpec.kt diff --git a/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt b/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt index 579920ddd6..ea4ebe7c20 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt @@ -34,8 +34,8 @@ import io.spine.tools.compiler.ast.OneofGroup import io.spine.tools.compiler.ast.Span import io.spine.tools.compiler.ast.qualifiedName import io.spine.tools.compiler.check -import io.spine.validation.Placeholder -import io.spine.validation.extractPlaceholders +import io.spine.string.Placeholder +import io.spine.string.extractPlaceholders /** * Checks if this [String] contains placeholders that are not present in the given diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/expression/ClassNames.kt b/java/src/main/kotlin/io/spine/tools/validation/java/expression/ClassNames.kt index 895c86bedb..19da1c4b4c 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/expression/ClassNames.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/expression/ClassNames.kt @@ -43,7 +43,7 @@ import io.spine.type.KnownTypes import io.spine.type.TypeName import io.spine.type.TypeUrl import io.spine.validation.ConstraintViolation -import io.spine.validation.TemplateString +import io.spine.string.TemplateString import io.spine.validation.ValidatableMessage import io.spine.validation.ValidationError import java.util.* diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/expression/ConstraintViolations.kt b/java/src/main/kotlin/io/spine/tools/validation/java/expression/ConstraintViolations.kt index 223f4031e0..71613781fe 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/expression/ConstraintViolations.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/expression/ConstraintViolations.kt @@ -34,7 +34,7 @@ import io.spine.tools.compiler.jvm.Expression import io.spine.tools.compiler.jvm.newBuilder import io.spine.tools.compiler.jvm.packToAny import io.spine.validation.ConstraintViolation -import io.spine.validation.TemplateString +import io.spine.string.TemplateString /** * Yields an expression that creates a new instance of [ConstraintViolation] diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt b/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt index afb62951f9..c76da3907a 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt @@ -33,9 +33,9 @@ import io.spine.tools.compiler.jvm.Expression import io.spine.tools.compiler.jvm.StringLiteral import io.spine.tools.compiler.jvm.mapExpression import io.spine.tools.compiler.jvm.newBuilder -import io.spine.validation.Placeholder -import io.spine.validation.TemplateString -import io.spine.validation.checkPlaceholdersHasValue +import io.spine.string.Placeholder +import io.spine.string.TemplateString +import io.spine.string.checkPlaceholdersHasValue /** * Yields an expression that creates a new instance of [TemplateString]. diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/ValidatorGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/ValidatorGenerator.kt index a612304fc6..49fe678efe 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/ValidatorGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/ValidatorGenerator.kt @@ -57,7 +57,7 @@ import io.spine.tools.validation.java.generate.ValidateScope.parentPath import io.spine.tools.validation.java.generate.ValidateScope.violations import io.spine.validation.ConstraintViolation import io.spine.validation.DetectedViolation -import io.spine.validation.TemplateString +import io.spine.string.TemplateString /** * A fully qualified Java class name of a validator class. diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/ChoiceGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/ChoiceGenerator.kt index 3d43fa67e0..5e600260a1 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/ChoiceGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/ChoiceGenerator.kt @@ -47,7 +47,7 @@ import io.spine.tools.validation.java.generate.ValidateScope.parentPath import io.spine.tools.validation.java.generate.ValidateScope.violations import io.spine.tools.validation.option.CHOICE import io.spine.validation.ConstraintViolation -import io.spine.validation.Placeholder +import io.spine.string.Placeholder import io.spine.validation.StandardPlaceholder.GROUP_PATH import io.spine.validation.StandardPlaceholder.PARENT_TYPE diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/DistinctGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/DistinctGenerator.kt index 338a53106c..cc7dfb47b0 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/DistinctGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/DistinctGenerator.kt @@ -61,7 +61,7 @@ import io.spine.tools.validation.java.generate.ValidateScope.parentPath import io.spine.tools.validation.java.generate.ValidateScope.violations import io.spine.tools.validation.option.PATTERN import io.spine.validation.ConstraintViolation -import io.spine.validation.Placeholder +import io.spine.string.Placeholder import io.spine.validation.StandardPlaceholder.FIELD_DUPLICATES import io.spine.validation.StandardPlaceholder.FIELD_PATH import io.spine.validation.StandardPlaceholder.FIELD_TYPE diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/GoesGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/GoesGenerator.kt index 745f4ca366..f227fe2558 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/GoesGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/GoesGenerator.kt @@ -53,7 +53,7 @@ import io.spine.tools.validation.java.generate.ValidateScope.parentPath import io.spine.tools.validation.java.generate.ValidateScope.violations import io.spine.tools.validation.option.GOES import io.spine.validation.ConstraintViolation -import io.spine.validation.Placeholder +import io.spine.string.Placeholder import io.spine.validation.StandardPlaceholder.FIELD_PATH import io.spine.validation.StandardPlaceholder.FIELD_TYPE import io.spine.validation.StandardPlaceholder.FIELD_VALUE diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/PatternGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/PatternGenerator.kt index d02e05c1f8..6def7a7971 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/PatternGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/PatternGenerator.kt @@ -67,7 +67,7 @@ import io.spine.tools.validation.option.PATTERN import io.spine.tools.validation.option.isRepeatedString import io.spine.tools.validation.option.isSingularString import io.spine.validation.ConstraintViolation -import io.spine.validation.Placeholder +import io.spine.string.Placeholder import io.spine.validation.StandardPlaceholder.FIELD_PATH import io.spine.validation.StandardPlaceholder.FIELD_TYPE import io.spine.validation.StandardPlaceholder.FIELD_VALUE diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequireOptionGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequireOptionGenerator.kt index 17b48a0b20..2bedf53aad 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequireOptionGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequireOptionGenerator.kt @@ -50,7 +50,7 @@ import io.spine.tools.validation.java.generate.ValidateScope.violations import io.spine.tools.validation.java.generate.mangled import io.spine.tools.validation.option.REQUIRE import io.spine.validation.ConstraintViolation -import io.spine.validation.Placeholder +import io.spine.string.Placeholder import io.spine.validation.StandardPlaceholder.MESSAGE_TYPE import io.spine.validation.StandardPlaceholder.REQUIRE_FIELDS diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequiredGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequiredGenerator.kt index 916359a554..84ea65f044 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequiredGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequiredGenerator.kt @@ -50,7 +50,7 @@ import io.spine.tools.validation.java.generate.ValidateScope.parentPath import io.spine.tools.validation.java.generate.ValidateScope.violations import io.spine.tools.validation.option.IF_MISSING import io.spine.validation.ConstraintViolation -import io.spine.validation.Placeholder +import io.spine.string.Placeholder import io.spine.validation.StandardPlaceholder.FIELD_PATH import io.spine.validation.StandardPlaceholder.FIELD_TYPE import io.spine.validation.StandardPlaceholder.PARENT_TYPE diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/BoundedFieldGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/BoundedFieldGenerator.kt index 6f98fc6d12..8b0b5b0f11 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/BoundedFieldGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/BoundedFieldGenerator.kt @@ -68,7 +68,7 @@ import io.spine.tools.validation.java.generate.option.bound.Docs.SCALAR_TYPES import io.spine.tools.validation.java.generate.option.bound.Docs.UNSIGNED_API import io.spine.type.TypeName import io.spine.validation.ConstraintViolation -import io.spine.validation.Placeholder +import io.spine.string.Placeholder /** * An abstract base for field generators that restrict the range of numeric fields. diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MaxGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MaxGenerator.kt index 569c1fff71..c66f4cf0bf 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MaxGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MaxGenerator.kt @@ -44,7 +44,7 @@ import io.spine.tools.validation.java.expression.joinToString import io.spine.tools.validation.java.generate.OptionGenerator import io.spine.tools.validation.java.generate.SingleOptionCode import io.spine.tools.validation.option.MAX -import io.spine.validation.Placeholder +import io.spine.string.Placeholder import io.spine.validation.StandardPlaceholder.FIELD_PATH import io.spine.validation.StandardPlaceholder.FIELD_TYPE import io.spine.validation.StandardPlaceholder.FIELD_VALUE diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MinGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MinGenerator.kt index 70fb10ef73..43efcf5768 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MinGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MinGenerator.kt @@ -44,7 +44,7 @@ import io.spine.tools.validation.java.expression.joinToString import io.spine.tools.validation.java.generate.OptionGenerator import io.spine.tools.validation.java.generate.SingleOptionCode import io.spine.tools.validation.option.MIN -import io.spine.validation.Placeholder +import io.spine.string.Placeholder import io.spine.validation.StandardPlaceholder.FIELD_PATH import io.spine.validation.StandardPlaceholder.FIELD_TYPE import io.spine.validation.StandardPlaceholder.FIELD_VALUE diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/RangeGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/RangeGenerator.kt index c670158f8a..981249c2dd 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/RangeGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/RangeGenerator.kt @@ -45,7 +45,7 @@ import io.spine.tools.validation.java.expression.joinToString import io.spine.tools.validation.java.generate.OptionGenerator import io.spine.tools.validation.java.generate.SingleOptionCode import io.spine.tools.validation.option.RANGE -import io.spine.validation.Placeholder +import io.spine.string.Placeholder import io.spine.validation.StandardPlaceholder.FIELD_PATH import io.spine.validation.StandardPlaceholder.FIELD_TYPE import io.spine.validation.StandardPlaceholder.FIELD_VALUE diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceConstraintViolation.kt b/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceConstraintViolation.kt index 4732782c94..2a588ebfe1 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceConstraintViolation.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceConstraintViolation.kt @@ -38,7 +38,7 @@ import io.spine.tools.validation.java.expression.constraintViolation import io.spine.tools.validation.java.expression.templateString import io.spine.tools.validation.option.IF_SET_AGAIN import io.spine.validation.ConstraintViolation -import io.spine.validation.Placeholder +import io.spine.string.Placeholder import io.spine.validation.StandardPlaceholder.FIELD_PATH import io.spine.validation.StandardPlaceholder.FIELD_PROPOSED_VALUE import io.spine.validation.StandardPlaceholder.FIELD_TYPE diff --git a/jvm-runtime/src/main/java/io/spine/validation/ViolationText.java b/jvm-runtime/src/main/java/io/spine/validation/ViolationText.java index 9c2e30e091..e9a4877d65 100644 --- a/jvm-runtime/src/main/java/io/spine/validation/ViolationText.java +++ b/jvm-runtime/src/main/java/io/spine/validation/ViolationText.java @@ -35,7 +35,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static io.spine.string.Diags.backtick; -import static io.spine.validation.TemplateStrings.format; +import static io.spine.string.TemplateStrings.format; import static java.lang.System.lineSeparator; import static java.util.stream.Collectors.joining; diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/DetectedViolation.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/DetectedViolation.kt index 42629f82fe..ba6dc9846b 100644 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/DetectedViolation.kt +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/DetectedViolation.kt @@ -27,6 +27,7 @@ package io.spine.validation import io.spine.base.FieldPath +import io.spine.string.TemplateString /** * Abstract base for violations detected by [MessageValidator]s. diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/Placeholder.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/Placeholder.kt deleted file mode 100644 index 2899856d9c..0000000000 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/Placeholder.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2026, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.validation - -/** - * A template placeholder that can be referenced from error messages. - * - * Implementations enumerate placeholder names that can be used within Protobuf definitions. - * The standard set of placeholders is provided by [StandardPlaceholder]. Additional - * placeholders may be contributed by extensions (e.g., Spine Time) by introducing - * their own enums implementing this interface. - */ -public interface Placeholder { - - /** - * The placeholder name as it appears in a template string (e.g., `field.path`). - */ - public val value: String -} diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt index aa99f8feff..521fa94a30 100644 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt @@ -26,6 +26,8 @@ package io.spine.validation +import io.spine.string.Placeholder + /** * The standard set of [Placeholder]s that can be used in error messages. * diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt index 0be5bfe949..1298e7f7c0 100644 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt @@ -24,106 +24,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -@file:JvmName("TemplateStrings") - package io.spine.validation import io.spine.code.proto.FieldDeclaration +import io.spine.string.TemplateString import io.spine.validation.StandardPlaceholder.FIELD_PATH import io.spine.validation.StandardPlaceholder.FIELD_TYPE import io.spine.validation.StandardPlaceholder.GOES_COMPANION import io.spine.validation.StandardPlaceholder.PARENT_TYPE import io.spine.validation.StandardPlaceholder.REGEX_PATTERN -import kotlin.collections.iterator - -/** - * Returns a template string with all placeholders substituted with - * their actual values. - * - * For example, for a template string with the following values: - * - * ``` - * with_placeholders = "My dog's name is ${dog.name}." - * placeholder_value = { "dog.name": "Fido" } - * ``` - * - * This method will return "My dog's name is Fido." - */ -public fun TemplateString.format(): String { - checkPlaceholdersHasValue(withPlaceholders, placeholderValueMap) { - "Cannot format the given `TemplateString`: `$withPlaceholders`. " + - "Missing value for the following placeholders: `$it`." - } - return formatUnsafe() -} - -/** - * Returns a template string with all placeholders substituted with - * their actual values, without validating that all placeholders have - * corresponding values. - * - * This method does not check whether every placeholder in the template has a matching value - * in the placeholder map. Any placeholders without a corresponding value will remain - * unchanged in the resulting string. - * - * For example, for a template string with the following values: - * - * ``` - * withPlaceholders = "My dog's name is ${dog.name} and its breed is ${dog.breed}." - * placeholderValue = { "dog.name": "Fido" } - * ``` - * - * This method will return "My dog's name is Fido and its breed is ${dog.breed}.". - */ -public fun TemplateString.formatUnsafe(): String { - var result = withPlaceholders - for ((key, value) in placeholderValueMap) { - result = result.replace("\${$key}", value) - } - return result -} - -/** - * Makes sure that each placeholder within the [template] string is present - * in the [placeholders] set. - * - * @param template The template with placeholders like `${something}`. - * @param placeholders The list with placeholder values. - * @param lazyMessage The message to use in [IllegalArgumentException] if the check fails. - */ -public fun checkPlaceholdersHasValue( - template: String, - placeholders: Set, - lazyMessage: (List) -> String = - { "Missing value for the following template placeholders: `$it`." } -) { - val neededPlaceholders = extractPlaceholders(template) - val missing = mutableListOf() - for (placeholder in neededPlaceholders) { - if (!placeholders.contains(placeholder)) { - missing.add(placeholder) - } - } - if (missing.isNotEmpty()) { - throw IllegalArgumentException(lazyMessage(missing)) - } -} - -/** - * Makes sure that each placeholder within the [template] string has a value - * in [placeholders] map. - * - * @param template The template with placeholders like `${something}`. - * @param placeholders The map containing placeholders (without curly braces and the dollar sign) - * and their values. - * @param lazyMessage The message to use in [IllegalArgumentException] if the check fails. - */ -public fun checkPlaceholdersHasValue( - template: String, - placeholders: Map, - lazyMessage: (List) -> String = - { "Missing value for the following template placeholders: `$it`." } -): Unit = checkPlaceholdersHasValue(template, placeholders.keys, lazyMessage) /** * Fills in the fields-related placeholders from the given [field] declaration. @@ -150,13 +59,3 @@ public fun TemplateString.Builder.withCompanion(field: FieldDeclaration): Templa */ public fun TemplateString.Builder.withRegex(regex: String): TemplateString.Builder = putPlaceholderValue(REGEX_PATTERN.value, regex) - -/** - * Extracts all placeholders used within this [template] string. - */ -public fun extractPlaceholders(template: String): Set = - PLACEHOLDERS.findAll(template) - .map { it.groupValues[1] } - .toSet() - -private val PLACEHOLDERS = Regex("\\$\\{([^}]+)}") diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt index 956ba481e1..72d51f41a5 100644 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt @@ -32,6 +32,7 @@ import com.google.protobuf.util.Timestamps import com.google.protobuf.util.Timestamps.MAX_VALUE import com.google.protobuf.util.Timestamps.MIN_VALUE import io.spine.base.fieldPath +import io.spine.string.templateString import io.spine.validation.StandardPlaceholder.FIELD_PATH import io.spine.validation.StandardPlaceholder.RANGE_VALUE diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/ValidatorRegistry.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/ValidatorRegistry.kt index a7460bd348..02a114b292 100644 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/ValidatorRegistry.kt +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/ValidatorRegistry.kt @@ -33,6 +33,7 @@ import com.google.protobuf.Message import io.spine.annotation.VisibleForTesting import io.spine.base.FieldPath import io.spine.protobuf.TypeConverter +import io.spine.string.TemplateString import io.spine.type.TypeName import java.lang.reflect.ParameterizedType import java.util.* diff --git a/jvm-runtime/src/main/proto/spine/validation/template_string.proto b/jvm-runtime/src/main/proto/spine/validation/template_string.proto deleted file mode 100644 index 25fb9ab2c2..0000000000 --- a/jvm-runtime/src/main/proto/spine/validation/template_string.proto +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2023, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -syntax = "proto3"; - -package spine.validation; - -import "spine/options.proto"; - -option (type_url_prefix) = "type.spine.io"; -option java_multiple_files = true; -option java_outer_classname = "TemplateStringProto"; -option java_package = "io.spine.validation"; - -// Represents a template string with placeholders and a map for further substituting -// those placeholders with the actual values. -// -// Placeholders are specified using the format `${key}`, where `key` is the identifier -// for the value to be substituted from the `placeholder_value` map. There are no -// expectations about the identifier format. It can be `myKey`, `my.key`, `my_key`, etc. -// -// Example usage: -// template_string = "My dog's name is ${dog.name}." -// placeholder_values = { "dog.name": "Fido" } -// -// After substitution, the final output would be: -// "My dog's name is Fido." -// -// Each placeholder `key` referenced in the template string must have a corresponding entry -// in the `placeholder_value` map. However, the `placeholder_value` map is not restricted to -// containing only the placeholders used in the template. Additional entries in the map -// that do not correspond to placeholders in the template string are permitted. -// -message TemplateString { - - // The template string that may contain one or more placeholders. - string with_placeholders = 1; - - // A map that provides values for placeholders referenced in `with_placeholders`. - // - // The keys in this map should match the placeholder keys inside `with_placeholders` - // excluding the `${}` placeholder markers. - // - // All placeholders present in `with_placeholders` must have corresponding entries - // in this map. Otherwise, the template is considered invalid. - // - map placeholder_value = 2; -} diff --git a/jvm-runtime/src/main/proto/spine/validation/validation_error.proto b/jvm-runtime/src/main/proto/spine/validation/validation_error.proto index b24ed173f4..cf0cb56e0b 100644 --- a/jvm-runtime/src/main/proto/spine/validation/validation_error.proto +++ b/jvm-runtime/src/main/proto/spine/validation/validation_error.proto @@ -36,7 +36,7 @@ option java_package = "io.spine.validation"; import "google/protobuf/any.proto"; -import "spine/validation/template_string.proto"; +import "spine/string/template_string.proto"; import "spine/base/field_path.proto"; // An error indicating that a message did not pass validation. @@ -60,9 +60,9 @@ message ConstraintViolation { // The returned message can be formatted using one of the following approaches: // // 1. In Kotlin, use the `TemplateString.format()` extension. - // 2. In Java, use the `io.spine.validate.TemplateStrings.format()` static method. + // 2. In Java, use the `io.spine.string.TemplateStrings.format()` static method. // - TemplateString message = 8; + spine.string.TemplateString message = 8; // The name of the validated message type. // diff --git a/jvm-runtime/src/test/kotlin/io/spine/validation/TemplateStringExtsSpec.kt b/jvm-runtime/src/test/kotlin/io/spine/validation/TemplateStringExtsSpec.kt deleted file mode 100644 index 9336eb3b94..0000000000 --- a/jvm-runtime/src/test/kotlin/io/spine/validation/TemplateStringExtsSpec.kt +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2024, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.validation - -import io.kotest.matchers.shouldBe -import org.junit.jupiter.api.DisplayName -import org.junit.jupiter.api.Nested -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertDoesNotThrow -import org.junit.jupiter.api.assertThrows - -@DisplayName("`TemplateString` extensions should") -internal class TemplateStringExtsSpec { - - @Nested inner class - `format the template string` { - - @Test - fun `returning the correct result`() { - val template = templateString { - withPlaceholders = "My dog's name is \${dog.name}." - placeholderValue["dog.name"] = "Fido" - } - template.format() shouldBe "My dog's name is Fido." - } - - @Test - fun `returning an empty string if given an empty template`() { - TemplateString.getDefaultInstance().format() shouldBe "" - } - - @Test - fun `throwing when a placeholder has no value`() { - assertThrows { - val template = templateString { - withPlaceholders = "My dog's name is \${dog.name}." - } - template.format() - } - } - - @Test - fun `ignore when a placeholder with a value is not used`() { - assertDoesNotThrow { - val template = templateString { - withPlaceholders = "My dog's name is Fido." - placeholderValue["dog.name"] = "Fido" - } - template.format() - } - } - } - - @Nested inner class - `validate the template against placeholders` { - - private val message = { missingPlaceholders: List -> "$missingPlaceholders" } - private val template = "\${val1}, \${val2}, \${val3}, \${val4}, \${val5}" - private val fooPlaceholders = mapOf("val1" to "Foo", "val2" to "Foo", "val3" to "Foo") - private val barPlaceholders = mapOf("val4" to "Bar", "val5" to "Bar") - - @Test - fun `failing if the template has non-presentable placeholder`() { - val exception = assertThrows { - checkPlaceholdersHasValue(template, fooPlaceholders, message) - } - exception.message shouldBe message(listOf("val4", "val5")) - } - - @Test - fun `bypassing the template if all placeholders are present`() { - val placeholders = fooPlaceholders + barPlaceholders - assertDoesNotThrow { - checkPlaceholdersHasValue(template, placeholders, message) - } - } - } - - @Test - fun `format with missing placeholders`() { - val template = templateString { - withPlaceholders = "My dog's name is \${dog.name} and its breed is \${dog.breed}." - placeholderValue["dog.name"] = "Fido" - } - template.formatUnsafe() shouldBe "My dog's name is Fido and its breed is \${dog.breed}." - } -} diff --git a/jvm-runtime/src/test/kotlin/io/spine/validation/ValidatorRegistrySpec.kt b/jvm-runtime/src/test/kotlin/io/spine/validation/ValidatorRegistrySpec.kt index 8c9a2da8e1..a30319ba2a 100644 --- a/jvm-runtime/src/test/kotlin/io/spine/validation/ValidatorRegistrySpec.kt +++ b/jvm-runtime/src/test/kotlin/io/spine/validation/ValidatorRegistrySpec.kt @@ -32,6 +32,7 @@ import io.kotest.matchers.collections.shouldBeEmpty import io.kotest.matchers.collections.shouldContainExactly import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.shouldBe +import io.spine.string.templateString import java.util.ServiceLoader import java.util.concurrent.Executors import java.util.concurrent.TimeUnit diff --git a/jvm-runtime/src/test/kotlin/io/spine/validation/given/TemplateStrings.kt b/jvm-runtime/src/test/kotlin/io/spine/validation/given/TemplateStrings.kt index 24cc44202b..bd4bde29e2 100644 --- a/jvm-runtime/src/test/kotlin/io/spine/validation/given/TemplateStrings.kt +++ b/jvm-runtime/src/test/kotlin/io/spine/validation/given/TemplateStrings.kt @@ -26,8 +26,8 @@ package io.spine.validation.given -import io.spine.validation.TemplateString -import io.spine.validation.templateString +import io.spine.string.TemplateString +import io.spine.string.templateString /** * Creates a new [TemplateString] with the given [value], which does not diff --git a/tests/consumer/src/test/kotlin/io/spine/validation/test/ErrorMessageSpec.kt b/tests/consumer/src/test/kotlin/io/spine/validation/test/ErrorMessageSpec.kt index 4172952c22..632480d81f 100644 --- a/tests/consumer/src/test/kotlin/io/spine/validation/test/ErrorMessageSpec.kt +++ b/tests/consumer/src/test/kotlin/io/spine/validation/test/ErrorMessageSpec.kt @@ -28,7 +28,7 @@ package io.spine.validation.test import io.kotest.matchers.shouldBe import io.spine.validation.ValidationException -import io.spine.validation.format +import io.spine.string.format import io.spine.tools.validation.test.money.Usd import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test diff --git a/tests/consumer/src/test/kotlin/io/spine/validation/test/MinRuleITest.kt b/tests/consumer/src/test/kotlin/io/spine/validation/test/MinRuleITest.kt index 55b04367e6..5537411398 100644 --- a/tests/consumer/src/test/kotlin/io/spine/validation/test/MinRuleITest.kt +++ b/tests/consumer/src/test/kotlin/io/spine/validation/test/MinRuleITest.kt @@ -27,7 +27,7 @@ package io.spine.validation.test import io.kotest.matchers.string.shouldContain -import io.spine.validation.format +import io.spine.string.format import io.spine.tools.validation.test.time.LocalTime import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test diff --git a/tests/consumer/src/test/kotlin/io/spine/validation/test/PatternRuleITest.kt b/tests/consumer/src/test/kotlin/io/spine/validation/test/PatternRuleITest.kt index bcd5bfe84c..eb1ecdd580 100644 --- a/tests/consumer/src/test/kotlin/io/spine/validation/test/PatternRuleITest.kt +++ b/tests/consumer/src/test/kotlin/io/spine/validation/test/PatternRuleITest.kt @@ -28,7 +28,7 @@ package io.spine.validation.test import com.google.common.truth.Truth.assertThat import io.kotest.matchers.shouldBe -import io.spine.validation.format +import io.spine.string.format import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test diff --git a/tests/consumer/src/test/kotlin/io/spine/validation/test/RequiredRuleITest.kt b/tests/consumer/src/test/kotlin/io/spine/validation/test/RequiredRuleITest.kt index 6545bac665..15ac03493a 100644 --- a/tests/consumer/src/test/kotlin/io/spine/validation/test/RequiredRuleITest.kt +++ b/tests/consumer/src/test/kotlin/io/spine/validation/test/RequiredRuleITest.kt @@ -28,8 +28,8 @@ package io.spine.validation.test import io.kotest.matchers.shouldBe import io.kotest.matchers.string.shouldContain -import io.spine.validation.format -import io.spine.validation.formatUnsafe +import io.spine.string.format +import io.spine.string.formatUnsafe import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test diff --git a/tests/consumer/src/test/kotlin/io/spine/validation/test/ValidateRuleITest.kt b/tests/consumer/src/test/kotlin/io/spine/validation/test/ValidateRuleITest.kt index 17caa2f166..023e8ea147 100644 --- a/tests/consumer/src/test/kotlin/io/spine/validation/test/ValidateRuleITest.kt +++ b/tests/consumer/src/test/kotlin/io/spine/validation/test/ValidateRuleITest.kt @@ -30,7 +30,7 @@ import com.google.protobuf.Message import io.kotest.matchers.string.shouldContain import io.spine.protobuf.AnyPacker import io.spine.protobuf.pack -import io.spine.validation.formatUnsafe +import io.spine.string.formatUnsafe import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test diff --git a/tests/runtime/src/test/kotlin/io/spine/validation/option/ChoiceSpec.kt b/tests/runtime/src/test/kotlin/io/spine/validation/option/ChoiceSpec.kt index 4e4116f1c3..293fdb65b5 100644 --- a/tests/runtime/src/test/kotlin/io/spine/validation/option/ChoiceSpec.kt +++ b/tests/runtime/src/test/kotlin/io/spine/validation/option/ChoiceSpec.kt @@ -37,7 +37,7 @@ import io.spine.testing.TestValues.randomString import io.spine.validation.ValidationException import io.spine.validation.ValidationOfConstraintTest import io.spine.validation.ValidationOfConstraintTest.Companion.VALIDATION_SHOULD -import io.spine.validation.format +import io.spine.string.format import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows diff --git a/tests/validating/src/test/kotlin/io/spine/test/options/ChoiceITest.kt b/tests/validating/src/test/kotlin/io/spine/test/options/ChoiceITest.kt index a9f3713ad0..d45f4f4687 100644 --- a/tests/validating/src/test/kotlin/io/spine/test/options/ChoiceITest.kt +++ b/tests/validating/src/test/kotlin/io/spine/test/options/ChoiceITest.kt @@ -38,7 +38,7 @@ import io.spine.test.tools.validate.Sauce import io.spine.test.tools.validate.fish import io.spine.testing.TestValues.randomString import io.spine.validation.Validate.violationsOf -import io.spine.validation.format +import io.spine.string.format import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test diff --git a/tests/validating/src/test/kotlin/io/spine/test/options/NumberConstraintsITest.kt b/tests/validating/src/test/kotlin/io/spine/test/options/NumberConstraintsITest.kt index a9cf13ec4c..d97089968c 100644 --- a/tests/validating/src/test/kotlin/io/spine/test/options/NumberConstraintsITest.kt +++ b/tests/validating/src/test/kotlin/io/spine/test/options/NumberConstraintsITest.kt @@ -35,7 +35,7 @@ import io.spine.test.tools.validate.Probability import io.spine.test.tools.validate.SchoolClass import io.spine.test.tools.validate.Year import io.spine.test.tools.validate.targetMetrics -import io.spine.validation.format +import io.spine.string.format import io.spine.tools.validation.RangeFieldExtrema import io.spine.tools.validation.assertions.assertInvalid import io.spine.tools.validation.assertions.assertValid diff --git a/tests/validating/src/test/kotlin/io/spine/test/options/required/RequireITest.kt b/tests/validating/src/test/kotlin/io/spine/test/options/required/RequireITest.kt index a71065bc6e..7e46af73c9 100644 --- a/tests/validating/src/test/kotlin/io/spine/test/options/required/RequireITest.kt +++ b/tests/validating/src/test/kotlin/io/spine/test/options/required/RequireITest.kt @@ -34,7 +34,7 @@ import io.spine.test.tools.validate.Citizen import io.spine.test.tools.validate.Due import io.spine.test.tools.validate.FieldGroup import io.spine.type.TypeName -import io.spine.validation.format +import io.spine.string.format import io.spine.tools.validation.assertions.assertInvalid import io.spine.tools.validation.assertions.assertValid import java.nio.charset.StandardCharsets.UTF_16 diff --git a/tests/validating/src/testFixtures/kotlin/io/spine/tools/validation/assertions/Assertions.kt b/tests/validating/src/testFixtures/kotlin/io/spine/tools/validation/assertions/Assertions.kt index d3b142aaf2..7f44830cb3 100644 --- a/tests/validating/src/testFixtures/kotlin/io/spine/tools/validation/assertions/Assertions.kt +++ b/tests/validating/src/testFixtures/kotlin/io/spine/tools/validation/assertions/Assertions.kt @@ -37,7 +37,7 @@ import io.kotest.matchers.string.shouldContain import io.spine.type.toJson import io.spine.validation.ConstraintViolation import io.spine.validation.ValidationException -import io.spine.validation.formatUnsafe +import io.spine.string.formatUnsafe import org.junit.jupiter.api.Assertions.assertDoesNotThrow import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.Assertions.fail diff --git a/tests/validator/src/main/kotlin/io/spine/tools/validation/test/EarphonesValidator.kt b/tests/validator/src/main/kotlin/io/spine/tools/validation/test/EarphonesValidator.kt index f275101f53..9168bb5a45 100644 --- a/tests/validator/src/main/kotlin/io/spine/tools/validation/test/EarphonesValidator.kt +++ b/tests/validator/src/main/kotlin/io/spine/tools/validation/test/EarphonesValidator.kt @@ -34,9 +34,9 @@ import io.spine.tools.validation.test.EarphonesValidator.Companion.ValidEarphone import io.spine.validation.DetectedViolation import io.spine.validation.FieldViolation import io.spine.validation.MessageValidator -import io.spine.validation.TemplateString +import io.spine.string.TemplateString import io.spine.validation.ValidatorRegistry -import io.spine.validation.templateString +import io.spine.string.templateString /** * Validates [Earphones] messages, treating all instances as invalid diff --git a/tests/validator/src/main/kotlin/io/spine/tools/validation/test/TheOnlyTimeValid.kt b/tests/validator/src/main/kotlin/io/spine/tools/validation/test/TheOnlyTimeValid.kt index 21921a2312..e5b4a0ee1d 100644 --- a/tests/validator/src/main/kotlin/io/spine/tools/validation/test/TheOnlyTimeValid.kt +++ b/tests/validator/src/main/kotlin/io/spine/tools/validation/test/TheOnlyTimeValid.kt @@ -35,9 +35,9 @@ import io.spine.base.fieldPath import io.spine.validation.DetectedViolation import io.spine.validation.FieldViolation import io.spine.validation.MessageValidator -import io.spine.validation.TemplateString +import io.spine.string.TemplateString import io.spine.validation.ValidatorRegistry -import io.spine.validation.templateString +import io.spine.string.templateString /** * Validates [com.google.protobuf.Timestamp] messages, treating all instances as invalid diff --git a/tests/vanilla/src/test/kotlin/io/spine/validation/java/IsRequiredSpec.kt b/tests/vanilla/src/test/kotlin/io/spine/validation/java/IsRequiredSpec.kt index 52dcda71b5..35e87a06aa 100644 --- a/tests/vanilla/src/test/kotlin/io/spine/validation/java/IsRequiredSpec.kt +++ b/tests/vanilla/src/test/kotlin/io/spine/validation/java/IsRequiredSpec.kt @@ -31,7 +31,7 @@ import com.google.protobuf.Message import io.spine.testing.TestValues.randomString import io.spine.validation.NonValidated import io.spine.validation.Validate.violationsOf -import io.spine.validation.format +import io.spine.string.format import io.spine.tools.validation.java.given.Fish import io.spine.tools.validation.java.given.Meal import io.spine.tools.validation.java.given.Sauce From ba82d5448a3bffda90cb4001935022ae155bbf73 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 19:01:47 +0100 Subject: [PATCH 12/36] Update dependency reports --- docs/dependencies/dependencies.md | 32 +++++++++++++++---------------- docs/dependencies/pom.xml | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/dependencies/dependencies.md b/docs/dependencies/dependencies.md index 21375c6c4d..7b3a5eafa1 100644 --- a/docs/dependencies/dependencies.md +++ b/docs/dependencies/dependencies.md @@ -1090,7 +1090,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:48 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1791,7 +1791,7 @@ This report was generated on **Fri May 15 18:33:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:47 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1805,7 +1805,7 @@ This report was generated on **Fri May 15 18:33:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 16:29:48 WEST 2026** using +This report was generated on **Fri May 15 18:54:25 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2864,7 +2864,7 @@ This report was generated on **Fri May 15 16:29:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:48 WEST 2026** using +This report was generated on **Fri May 15 18:55:49 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3961,7 +3961,7 @@ This report was generated on **Fri May 15 18:33:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:48 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4015,7 +4015,7 @@ This report was generated on **Fri May 15 18:33:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:45 WEST 2026** using +This report was generated on **Fri May 15 18:55:46 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4822,7 +4822,7 @@ This report was generated on **Fri May 15 18:33:45 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:48 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5511,7 +5511,7 @@ This report was generated on **Fri May 15 18:33:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:47 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5976,7 +5976,7 @@ This report was generated on **Fri May 15 18:33:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:46 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6602,7 +6602,7 @@ This report was generated on **Fri May 15 18:33:46 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:46 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7170,7 +7170,7 @@ This report was generated on **Fri May 15 18:33:46 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:47 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7599,7 +7599,7 @@ This report was generated on **Fri May 15 18:33:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:46 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8210,7 +8210,7 @@ This report was generated on **Fri May 15 18:33:46 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:47 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8955,7 +8955,7 @@ This report was generated on **Fri May 15 18:33:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:47 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9195,7 +9195,7 @@ This report was generated on **Fri May 15 18:33:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:46 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9545,6 +9545,6 @@ This report was generated on **Fri May 15 18:33:46 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:33:46 WEST 2026** using +This report was generated on **Fri May 15 18:55:47 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/docs/dependencies/pom.xml b/docs/dependencies/pom.xml index edd2c353e0..d9342afb37 100644 --- a/docs/dependencies/pom.xml +++ b/docs/dependencies/pom.xml @@ -50,7 +50,7 @@ all modules and does not describe the project structure per-subproject. io.spine spine-base - 2.0.0-SNAPSHOT.387 + 2.0.0-SNAPSHOT.388 compile From 87e403e5ae73a9ae30c190d22fe637d31dfe01f0 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 19:09:59 +0100 Subject: [PATCH 13/36] Bump version -> `2.0.0-SNAPSHOT.430` --- version.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.gradle.kts b/version.gradle.kts index 82a46bd6ca..335c9b3ba9 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -27,4 +27,4 @@ /** * The version of the Validation library to publish. */ -val validationVersion by extra("2.0.0-SNAPSHOT.421") +val validationVersion by extra("2.0.0-SNAPSHOT.430") From b7e1044fd17ef3e2b205e4474f9ba548008cf715 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 19:11:05 +0100 Subject: [PATCH 14/36] Update dependency reports --- docs/dependencies/dependencies.md | 60 +++++++++++++++---------------- docs/dependencies/pom.xml | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/dependencies/dependencies.md b/docs/dependencies/dependencies.md index 7b3a5eafa1..f2ae738bab 100644 --- a/docs/dependencies/dependencies.md +++ b/docs/dependencies/dependencies.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine.tools:validation-context:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-context:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -1090,14 +1090,14 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:18 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-context-tests:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-context-tests:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -1791,7 +1791,7 @@ This report was generated on **Fri May 15 18:55:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:18 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1812,7 +1812,7 @@ This report was generated on **Fri May 15 18:54:25 WEST 2026** using -# Dependencies of `io.spine.tools:validation-gradle-plugin:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-gradle-plugin:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -2864,14 +2864,14 @@ This report was generated on **Fri May 15 18:54:25 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:49 WEST 2026** using +This report was generated on **Fri May 15 19:10:18 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-java:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-java:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -3961,14 +3961,14 @@ This report was generated on **Fri May 15 18:55:49 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:18 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-java-bundle:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-java-bundle:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : org.jetbrains. **Name** : annotations. **Version** : 13.0. @@ -4015,14 +4015,14 @@ This report was generated on **Fri May 15 18:55:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:46 WEST 2026** using +This report was generated on **Fri May 15 19:10:17 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-validation-jvm-runtime:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine:spine-validation-jvm-runtime:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -4822,14 +4822,14 @@ This report was generated on **Fri May 15 18:55:46 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:18 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-consumer:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-consumer:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -5511,14 +5511,14 @@ This report was generated on **Fri May 15 18:55:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:18 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-consumer-dependency:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-consumer-dependency:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -5976,14 +5976,14 @@ This report was generated on **Fri May 15 18:55:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:18 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-extensions:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-extensions:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -6602,14 +6602,14 @@ This report was generated on **Fri May 15 18:55:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-runtime:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-runtime:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -7170,14 +7170,14 @@ This report was generated on **Fri May 15 18:55:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:18 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-time:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-time:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -7599,14 +7599,14 @@ This report was generated on **Fri May 15 18:55:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:18 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-validating:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-validating:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -8210,14 +8210,14 @@ This report was generated on **Fri May 15 18:55:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:18 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-validator:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-validator:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -8955,14 +8955,14 @@ This report was generated on **Fri May 15 18:55:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:18 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-validator-dependency:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-validator-dependency:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -9195,14 +9195,14 @@ This report was generated on **Fri May 15 18:55:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:17 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-vanilla:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-vanilla:2.0.0-SNAPSHOT.430` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -9545,6 +9545,6 @@ This report was generated on **Fri May 15 18:55:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:55:47 WEST 2026** using +This report was generated on **Fri May 15 19:10:17 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/docs/dependencies/pom.xml b/docs/dependencies/pom.xml index d9342afb37..aefd66f406 100644 --- a/docs/dependencies/pom.xml +++ b/docs/dependencies/pom.xml @@ -10,7 +10,7 @@ all modules and does not describe the project structure per-subproject. --> io.spine.tools validation -2.0.0-SNAPSHOT.421 +2.0.0-SNAPSHOT.430 2015 From 6607211a13fbacd5593c0dbbc83d7dd35a19f67c Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 21:03:32 +0100 Subject: [PATCH 15/36] Adopt new `Placeholder` API --- .../tools/validation/ErrorPlaceholders.kt | 9 ++-- .../spine/tools/validation/bound/MaxOption.kt | 12 ++--- .../spine/tools/validation/bound/MinOption.kt | 12 ++--- .../tools/validation/bound/RangeOption.kt | 10 ++-- .../tools/validation/option/ChoiceOption.kt | 4 +- .../tools/validation/option/DistinctOption.kt | 10 ++-- .../tools/validation/option/GoesOption.kt | 10 ++-- .../tools/validation/option/PatternOption.kt | 12 ++--- .../tools/validation/option/RequireOption.kt | 4 +- .../tools/validation/option/SetOnceOption.kt | 10 ++-- .../option/required/RequiredOption.kt | 6 +-- docs/dependencies/dependencies.md | 30 ++++++------ .../java/expression/TemplateStrings.kt | 2 +- .../java/generate/option/ChoiceGenerator.kt | 4 +- .../java/generate/option/DistinctGenerator.kt | 10 ++-- .../java/generate/option/GoesGenerator.kt | 10 ++-- .../java/generate/option/PatternGenerator.kt | 12 ++--- .../generate/option/RequireOptionGenerator.kt | 4 +- .../java/generate/option/RequiredGenerator.kt | 6 +-- .../generate/option/bound/MaxGenerator.kt | 12 ++--- .../generate/option/bound/MinGenerator.kt | 12 ++--- .../generate/option/bound/RangeGenerator.kt | 10 ++-- .../setonce/SetOnceConstraintViolation.kt | 10 ++-- .../spine/validation/StandardPlaceholder.kt | 46 ++++++++----------- .../io/spine/validation/TemplateStringExts.kt | 10 ++-- .../io/spine/validation/TimestampValidator.kt | 16 +++---- .../test/options/goes/GoesViolationITest.kt | 10 ++-- .../options/setonce/SetOnceViolationITest.kt | 10 ++-- 28 files changed, 152 insertions(+), 161 deletions(-) diff --git a/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt b/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt index ea4ebe7c20..2a4838e58b 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt @@ -119,7 +119,7 @@ private fun String.checkPlaceholders( Compilation.check(missing.isEmpty(), file, span) { "The $declaration specifies an error message for the `($option)` option using unsupported" + " placeholders: `$missing`. Supported placeholders are the following:" + - " `${supported.map { it.value }}`." + " `${supported.map { it.name }}`." } } @@ -133,12 +133,11 @@ private fun String.checkPlaceholders( private fun missingPlaceholders( template: String, placeholders: Set -): Set { +): Set { val requested = extractPlaceholders(template) - val provided = placeholders.map { it.value } - val missing = mutableSetOf() + val missing = mutableSetOf() for (placeholder in requested) { - if (!provided.contains(placeholder)) { + if (!placeholders.contains(placeholder)) { missing.add(placeholder) } } diff --git a/context/src/main/kotlin/io/spine/tools/validation/bound/MaxOption.kt b/context/src/main/kotlin/io/spine/tools/validation/bound/MaxOption.kt index 8eb0702271..7360264422 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/bound/MaxOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/bound/MaxOption.kt @@ -107,10 +107,10 @@ internal class MaxFieldView : View() { } private val SUPPORTED_PLACEHOLDERS = setOf( - FIELD_PATH, - FIELD_TYPE, - FIELD_VALUE, - MAX_OPERATOR, - MAX_VALUE, - PARENT_TYPE, + FIELD_PATH.value, + FIELD_TYPE.value, + FIELD_VALUE.value, + MAX_OPERATOR.value, + MAX_VALUE.value, + PARENT_TYPE.value, ) diff --git a/context/src/main/kotlin/io/spine/tools/validation/bound/MinOption.kt b/context/src/main/kotlin/io/spine/tools/validation/bound/MinOption.kt index 09821c0e87..2d1dc76939 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/bound/MinOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/bound/MinOption.kt @@ -107,10 +107,10 @@ internal class MinFieldView : View() { } private val SUPPORTED_PLACEHOLDERS = setOf( - FIELD_PATH, - FIELD_TYPE, - FIELD_VALUE, - MIN_OPERATOR, - MIN_VALUE, - PARENT_TYPE, + FIELD_PATH.value, + FIELD_TYPE.value, + FIELD_VALUE.value, + MIN_OPERATOR.value, + MIN_VALUE.value, + PARENT_TYPE.value, ) diff --git a/context/src/main/kotlin/io/spine/tools/validation/bound/RangeOption.kt b/context/src/main/kotlin/io/spine/tools/validation/bound/RangeOption.kt index e4e0bcf4e2..c514bb2a61 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/bound/RangeOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/bound/RangeOption.kt @@ -226,9 +226,9 @@ private fun RangeOptionMetadata.checkRelation(lower: KNumericBound, upper: KNume private val DELIMITER = Regex("""(?<=[\p{Alnum}_])\s?\.\.\s?(?=[\p{Alnum}-+_])""") private val SUPPORTED_PLACEHOLDERS = setOf( - FIELD_PATH, - FIELD_TYPE, - FIELD_VALUE, - PARENT_TYPE, - RANGE_VALUE, + FIELD_PATH.value, + FIELD_TYPE.value, + FIELD_VALUE.value, + PARENT_TYPE.value, + RANGE_VALUE.value, ) diff --git a/context/src/main/kotlin/io/spine/tools/validation/option/ChoiceOption.kt b/context/src/main/kotlin/io/spine/tools/validation/option/ChoiceOption.kt index 9c5b113049..a9d9241e32 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/option/ChoiceOption.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/option/ChoiceOption.kt @@ -128,6 +128,6 @@ internal class ChoiceGroupView : View>, optionName: String ): Expression = - withStringPlaceholders(template, placeholders.mapKeys { it.key.value }, optionName) + withStringPlaceholders(template, placeholders.mapKeys { it.key.name }, optionName) /** * Yields an expression that creates a new instance of [TemplateString]. diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/ChoiceGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/ChoiceGenerator.kt index 5e600260a1..1e0caaa859 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/ChoiceGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/ChoiceGenerator.kt @@ -111,7 +111,7 @@ private class GenerateChoice(private val view: ChoiceOneof) { groupPath: Expression, typeName: Expression, ): Map> = mapOf( - GROUP_PATH to groupPath.joinToString(), - PARENT_TYPE to typeName + GROUP_PATH.value to groupPath.joinToString(), + PARENT_TYPE.value to typeName ) } diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/DistinctGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/DistinctGenerator.kt index cc7dfb47b0..0107572201 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/DistinctGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/DistinctGenerator.kt @@ -180,10 +180,10 @@ private class GenerateDistinct(private val view: DistinctField) { fieldValue: Expression<*>, duplicates: Expression<*> ): Map> = mapOf( - FIELD_PATH to fieldPath.joinToString(), - FIELD_VALUE to fieldType.stringValueOf(fieldValue), - FIELD_TYPE to StringLiteral(fieldType.name), - PARENT_TYPE to typeName, - FIELD_DUPLICATES to fieldType.stringValueOf(duplicates) + FIELD_PATH.value to fieldPath.joinToString(), + FIELD_VALUE.value to fieldType.stringValueOf(fieldValue), + FIELD_TYPE.value to StringLiteral(fieldType.name), + PARENT_TYPE.value to typeName, + FIELD_DUPLICATES.value to fieldType.stringValueOf(duplicates) ) } diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/GoesGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/GoesGenerator.kt index f227fe2558..ffb046d3ac 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/GoesGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/GoesGenerator.kt @@ -127,10 +127,10 @@ private class GenerateGoes( typeName: Expression, fieldValue: Expression<*>, ): Map> = mapOf( - FIELD_PATH to fieldPath.joinToString(), - FIELD_VALUE to fieldType.stringValueOf(fieldValue), - FIELD_TYPE to StringLiteral(fieldType.name), - PARENT_TYPE to typeName, - GOES_COMPANION to StringLiteral(view.companion.name.value) + FIELD_PATH.value to fieldPath.joinToString(), + FIELD_VALUE.value to fieldType.stringValueOf(fieldValue), + FIELD_TYPE.value to StringLiteral(fieldType.name), + PARENT_TYPE.value to typeName, + GOES_COMPANION.value to StringLiteral(view.companion.name.value) ) } diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/PatternGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/PatternGenerator.kt index 6def7a7971..c247eeafb8 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/PatternGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/PatternGenerator.kt @@ -251,12 +251,12 @@ private class GeneratePattern(private val view: PatternField) { typeName: Expression, fieldValue: Expression, ): Map> = mapOf( - FIELD_PATH to fieldPath.joinToString(), - FIELD_VALUE to fieldValue, - FIELD_TYPE to StringLiteral(fieldType.name), - PARENT_TYPE to typeName, - REGEX_PATTERN to StringLiteral(restoreProtobufEscapes(view.pattern)), - REGEX_MODIFIERS to StringLiteral(restoreProtobufEscapes("${view.modifier}")), + FIELD_PATH.value to fieldPath.joinToString(), + FIELD_VALUE.value to fieldValue, + FIELD_TYPE.value to StringLiteral(fieldType.name), + PARENT_TYPE.value to typeName, + REGEX_PATTERN.value to StringLiteral(restoreProtobufEscapes(view.pattern)), + REGEX_MODIFIERS.value to StringLiteral(restoreProtobufEscapes("${view.modifier}")), ) } diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequireOptionGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequireOptionGenerator.kt index 2bedf53aad..0a31930e9b 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequireOptionGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequireOptionGenerator.kt @@ -142,8 +142,8 @@ private class GenerateRequire( } private fun supportedPlaceholders(): Map> = mapOf( - MESSAGE_TYPE to StringLiteral(view.id.qualifiedName), - REQUIRE_FIELDS to StringLiteral(view.specifiedGroups) + MESSAGE_TYPE.value to StringLiteral(view.id.qualifiedName), + REQUIRE_FIELDS.value to StringLiteral(view.specifiedGroups) ) private companion object { diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequiredGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequiredGenerator.kt index 84ea65f044..478059be7b 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequiredGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/RequiredGenerator.kt @@ -117,8 +117,8 @@ private class GenerateRequired( fieldPath: Expression, typeName: Expression, ): Map> = mapOf( - FIELD_PATH to fieldPath.joinToString(), - FIELD_TYPE to StringLiteral(field.type.name), - PARENT_TYPE to typeName + FIELD_PATH.value to fieldPath.joinToString(), + FIELD_TYPE.value to StringLiteral(field.type.name), + PARENT_TYPE.value to typeName ) } diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MaxGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MaxGenerator.kt index c66f4cf0bf..de7f80b43c 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MaxGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MaxGenerator.kt @@ -102,11 +102,11 @@ private class GenerateMax(private val view: MaxField) : BoundedFieldGenerator(vi typeName: Expression, fieldValue: Expression<*>, ): Map> = mapOf( - FIELD_PATH to fieldPath.joinToString(), - FIELD_VALUE to StringClass.call("valueOf", fieldValue), - FIELD_TYPE to StringLiteral(fieldType.name), - PARENT_TYPE to typeName, - MAX_VALUE to view.max.withFieldValue(bound), - MAX_OPERATOR to StringLiteral(if (isExclusive) "<" else "<=") + FIELD_PATH.value to fieldPath.joinToString(), + FIELD_VALUE.value to StringClass.call("valueOf", fieldValue), + FIELD_TYPE.value to StringLiteral(fieldType.name), + PARENT_TYPE.value to typeName, + MAX_VALUE.value to view.max.withFieldValue(bound), + MAX_OPERATOR.value to StringLiteral(if (isExclusive) "<" else "<=") ) } diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MinGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MinGenerator.kt index 43efcf5768..069b558e59 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MinGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/MinGenerator.kt @@ -102,11 +102,11 @@ private class GenerateMin(private val view: MinField) : BoundedFieldGenerator(vi typeName: Expression, fieldValue: Expression<*>, ): Map> = mapOf( - FIELD_PATH to fieldPath.joinToString(), - FIELD_VALUE to StringClass.call("valueOf", fieldValue), - FIELD_TYPE to StringLiteral(fieldType.name), - PARENT_TYPE to typeName, - MIN_VALUE to view.min.withFieldValue(bound), - MIN_OPERATOR to StringLiteral(if (isExclusive) ">" else ">=") + FIELD_PATH.value to fieldPath.joinToString(), + FIELD_VALUE.value to StringClass.call("valueOf", fieldValue), + FIELD_TYPE.value to StringLiteral(fieldType.name), + PARENT_TYPE.value to typeName, + MIN_VALUE.value to view.min.withFieldValue(bound), + MIN_OPERATOR.value to StringLiteral(if (isExclusive) ">" else ">=") ) } diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/RangeGenerator.kt b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/RangeGenerator.kt index 981249c2dd..96daca17e3 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/RangeGenerator.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/generate/option/bound/RangeGenerator.kt @@ -114,11 +114,11 @@ private class GenerateRange( typeName: Expression, fieldValue: Expression<*>, ): Map> = mapOf( - FIELD_PATH to fieldPath.joinToString(), - FIELD_VALUE to StringClass.call("valueOf", fieldValue), - FIELD_TYPE to StringLiteral(fieldType.name), - PARENT_TYPE to typeName, - RANGE_VALUE to withFieldValue() + FIELD_PATH.value to fieldPath.joinToString(), + FIELD_VALUE.value to StringClass.call("valueOf", fieldValue), + FIELD_TYPE.value to StringLiteral(fieldType.name), + PARENT_TYPE.value to typeName, + RANGE_VALUE.value to withFieldValue() ) /** diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceConstraintViolation.kt b/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceConstraintViolation.kt index 2a588ebfe1..2f33ed8d18 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceConstraintViolation.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/setonce/SetOnceConstraintViolation.kt @@ -90,10 +90,10 @@ internal class SetOnceConstraintViolation( currentValue: Expression, newValue: Expression ): Map> = mapOf( - FIELD_PATH to StringLiteral(fieldName), - FIELD_TYPE to StringLiteral(fieldType), - FIELD_VALUE to currentValue, - FIELD_PROPOSED_VALUE to newValue, - PARENT_TYPE to declaringType + FIELD_PATH.value to StringLiteral(fieldName), + FIELD_TYPE.value to StringLiteral(fieldType), + FIELD_VALUE.value to currentValue, + FIELD_PROPOSED_VALUE.value to newValue, + PARENT_TYPE.value to declaringType ) } diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt index 521fa94a30..4a72f8fe7a 100644 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt @@ -38,41 +38,33 @@ import io.spine.string.Placeholder * The enum is used by the compiler model and Java renderer when validating and rendering * built-in option error messages. */ -public enum class StandardPlaceholder(override val value: String) : Placeholder { +public enum class StandardPlaceholder(public val value: Placeholder) { // Common placeholders. - FIELD_PATH("field.path"), - FIELD_VALUE("field.value"), - FIELD_TYPE("field.type"), - MESSAGE_TYPE("message.type"), - PARENT_TYPE("parent.type"), + FIELD_PATH(Placeholder("field.path")), + FIELD_VALUE(Placeholder("field.value")), + FIELD_TYPE(Placeholder("field.type")), + MESSAGE_TYPE(Placeholder("message.type")), + PARENT_TYPE(Placeholder("parent.type")), // Placeholders for the field options. - REGEX_PATTERN("regex.pattern"), - REGEX_MODIFIERS("regex.modifiers"), - GOES_COMPANION("goes.companion"), - FIELD_PROPOSED_VALUE("field.proposed_value"), - FIELD_DUPLICATES("field.duplicates"), - RANGE_VALUE("range.value"), - MAX_VALUE("max.value"), - MAX_OPERATOR("max.operator"), - MIN_VALUE("min.value"), - MIN_OPERATOR("min.operator"), + REGEX_PATTERN(Placeholder("regex.pattern")), + REGEX_MODIFIERS(Placeholder("regex.modifiers")), + GOES_COMPANION(Placeholder("goes.companion")), + FIELD_PROPOSED_VALUE(Placeholder("field.proposed_value")), + FIELD_DUPLICATES(Placeholder("field.duplicates")), + RANGE_VALUE(Placeholder("range.value")), + MAX_VALUE(Placeholder("max.value")), + MAX_OPERATOR(Placeholder("max.operator")), + MIN_VALUE(Placeholder("min.value")), + MIN_OPERATOR(Placeholder("min.operator")), @Deprecated(message = "Use the placeholder reference from Spine Time instead.") - WHEN_IN("when.in"), + WHEN_IN(Placeholder("when.in")), // Placeholders for the `oneof` options. - GROUP_PATH("group.path"), + GROUP_PATH(Placeholder("group.path")), // Placeholder for the message options. - REQUIRE_FIELDS("require.fields"); - - override fun toString(): String = value + REQUIRE_FIELDS(Placeholder("require.fields")); } - -@Deprecated( - message = "Please use `StandardPlaceholder` instead.", - replaceWith = ReplaceWith("StandardPlaceholder") -) -public typealias RuntimeErrorPlaceholder = StandardPlaceholder diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt index 1298e7f7c0..3d9b79dc8f 100644 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/TemplateStringExts.kt @@ -44,18 +44,18 @@ import io.spine.validation.StandardPlaceholder.REGEX_PATTERN * 3. [PARENT_TYPE]. */ public fun TemplateString.Builder.withField(field: FieldDeclaration): TemplateString.Builder = - putPlaceholderValue(FIELD_PATH.value, field.name().value) - .putPlaceholderValue(FIELD_TYPE.value, field.javaTypeName()) - .putPlaceholderValue(PARENT_TYPE.value, field.declaringType().name().value) + putPlaceholderValue(FIELD_PATH.value.name, field.name().value) + .putPlaceholderValue(FIELD_TYPE.value.name, field.javaTypeName()) + .putPlaceholderValue(PARENT_TYPE.value.name, field.declaringType().name().value) /** * Fills in the value for [GOES_COMPANION] placeholder. */ public fun TemplateString.Builder.withCompanion(field: FieldDeclaration): TemplateString.Builder = - putPlaceholderValue(GOES_COMPANION.value, field.name().value) + putPlaceholderValue(GOES_COMPANION.value.name, field.name().value) /** * Fills in the value for [REGEX_PATTERN] placeholder. */ public fun TemplateString.Builder.withRegex(regex: String): TemplateString.Builder = - putPlaceholderValue(REGEX_PATTERN.value, regex) + putPlaceholderValue(REGEX_PATTERN.value.name, regex) diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt index 72d51f41a5..cfaf4b7141 100644 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/TimestampValidator.kt @@ -67,10 +67,10 @@ public class TimestampValidator : MessageValidator { private fun invalidSeconds(seconds: Long): FieldViolation = FieldViolation( message = templateString { withPlaceholders = - "The ${FIELD_PATH.value} value is out of range" + - " (${RANGE_VALUE.value}): $seconds." - placeholderValue.put(FIELD_PATH.value, "seconds") - placeholderValue.put(RANGE_VALUE.value, + "The ${FIELD_PATH.value.name} value is out of range" + + " (${RANGE_VALUE.value.name}): $seconds." + placeholderValue.put(FIELD_PATH.value.name, "seconds") + placeholderValue.put(RANGE_VALUE.value.name, "${MIN_VALUE.seconds}..${MAX_VALUE.seconds}") }, @@ -85,10 +85,10 @@ private fun invalidSeconds(seconds: Long): FieldViolation = FieldViolation( */ private fun invalidNanos(nanos: Int): FieldViolation = FieldViolation( message = templateString { - withPlaceholders = "The ${FIELD_PATH.value} value is out of range" + - ": (${RANGE_VALUE.value})$nanos." - placeholderValue.put(FIELD_PATH.value, "nanos") - placeholderValue.put(RANGE_VALUE.value, "0..${MAX_VALUE.nanos}") + withPlaceholders = "The ${FIELD_PATH.value.name} value is out of range" + + ": (${RANGE_VALUE.value.name})$nanos." + placeholderValue.put(FIELD_PATH.value.name, "nanos") + placeholderValue.put(RANGE_VALUE.value.name, "0..${MAX_VALUE.nanos}") }, fieldPath = fieldPath { fieldName.add("nanos") diff --git a/tests/validating/src/test/kotlin/io/spine/test/options/goes/GoesViolationITest.kt b/tests/validating/src/test/kotlin/io/spine/test/options/goes/GoesViolationITest.kt index 0dbc00c7df..720a7c62e4 100644 --- a/tests/validating/src/test/kotlin/io/spine/test/options/goes/GoesViolationITest.kt +++ b/tests/validating/src/test/kotlin/io/spine/test/options/goes/GoesViolationITest.kt @@ -94,11 +94,11 @@ private fun Builder.assertConstraintViolation( with(violation) { message.withPlaceholders shouldBe template(field.index + 1) message.placeholderValueMap shouldContainExactly mapOf( - FIELD_PATH to fieldName, - FIELD_VALUE to value.asPlaceholderValue(), - FIELD_TYPE to fieldType, - PARENT_TYPE to parentType, - GOES_COMPANION to COMPANION_FIELD, + FIELD_PATH.value to fieldName, + FIELD_VALUE.value to value.asPlaceholderValue(), + FIELD_TYPE.value to fieldType, + PARENT_TYPE.value to parentType, + GOES_COMPANION.value to COMPANION_FIELD, ).mapKeys { it.key.toString() } typeName shouldBe parentType diff --git a/tests/validating/src/test/kotlin/io/spine/test/options/setonce/SetOnceViolationITest.kt b/tests/validating/src/test/kotlin/io/spine/test/options/setonce/SetOnceViolationITest.kt index b5f984a69c..0794b08bed 100644 --- a/tests/validating/src/test/kotlin/io/spine/test/options/setonce/SetOnceViolationITest.kt +++ b/tests/validating/src/test/kotlin/io/spine/test/options/setonce/SetOnceViolationITest.kt @@ -100,11 +100,11 @@ private fun Builder.assertConstraintViolation( with(violation) { message.withPlaceholders shouldBe template(field.index + 1) message.placeholderValueMap shouldContainExactly mapOf( - FIELD_PATH to fieldName, - FIELD_TYPE to fieldType, - FIELD_VALUE to fieldValue1.asPlaceholderValue(), - FIELD_PROPOSED_VALUE to fieldValue2.asPlaceholderValue(), - PARENT_TYPE to parentType + FIELD_PATH.value to fieldName, + FIELD_TYPE.value to fieldType, + FIELD_VALUE.value to fieldValue1.asPlaceholderValue(), + FIELD_PROPOSED_VALUE.value to fieldValue2.asPlaceholderValue(), + PARENT_TYPE.value to parentType ).mapKeys { it.key.toString() } typeName shouldBe parentType From 0853ce6f1328a821c26562db94bfc191c85d5777 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 21:05:30 +0100 Subject: [PATCH 16/36] Bump Validation -> `2.0.0-SNAPSHOT.419` --- .../src/main/kotlin/io/spine/dependency/local/Validation.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/Validation.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Validation.kt index 600deeda75..8e39d6aef4 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/Validation.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Validation.kt @@ -36,7 +36,7 @@ object Validation { /** * The version of the Validation library artifacts. */ - const val version = "2.0.0-SNAPSHOT.415" + const val version = "2.0.0-SNAPSHOT.419" /** * The last version of Validation compatible with ProtoData. From ab3a9de8bd89268ba1b4706934791e749e991437 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 21:05:41 +0100 Subject: [PATCH 17/36] Update dependency reports --- docs/dependencies/dependencies.md | 34 +++++++++++++++---------------- docs/dependencies/pom.xml | 4 ++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/dependencies/dependencies.md b/docs/dependencies/dependencies.md index fcd7ef6ac3..c80fab105d 100644 --- a/docs/dependencies/dependencies.md +++ b/docs/dependencies/dependencies.md @@ -1090,7 +1090,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:55 WEST 2026** using +This report was generated on **Fri May 15 21:05:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1791,21 +1791,21 @@ This report was generated on **Fri May 15 19:11:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:55 WEST 2026** using +This report was generated on **Fri May 15 21:05:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-docs:2.0.0-SNAPSHOT.421` +# Dependencies of `io.spine.tools:validation-docs:2.0.0-SNAPSHOT.430` ## Runtime ## Compile, tests, and tooling The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 18:54:25 WEST 2026** using +This report was generated on **Fri May 15 21:03:53 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2864,7 +2864,7 @@ This report was generated on **Fri May 15 18:54:25 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:55 WEST 2026** using +This report was generated on **Fri May 15 21:05:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3961,7 +3961,7 @@ This report was generated on **Fri May 15 19:11:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:55 WEST 2026** using +This report was generated on **Fri May 15 21:05:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4015,7 +4015,7 @@ This report was generated on **Fri May 15 19:11:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:53 WEST 2026** using +This report was generated on **Fri May 15 21:05:19 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4822,7 +4822,7 @@ This report was generated on **Fri May 15 19:11:53 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:55 WEST 2026** using +This report was generated on **Fri May 15 21:05:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5511,7 +5511,7 @@ This report was generated on **Fri May 15 19:11:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:55 WEST 2026** using +This report was generated on **Fri May 15 21:05:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5976,7 +5976,7 @@ This report was generated on **Fri May 15 19:11:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:54 WEST 2026** using +This report was generated on **Fri May 15 21:05:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6602,7 +6602,7 @@ This report was generated on **Fri May 15 19:11:54 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:57 WEST 2026** using +This report was generated on **Fri May 15 21:05:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7170,7 +7170,7 @@ This report was generated on **Fri May 15 19:11:57 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:55 WEST 2026** using +This report was generated on **Fri May 15 21:05:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7599,7 +7599,7 @@ This report was generated on **Fri May 15 19:11:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:54 WEST 2026** using +This report was generated on **Fri May 15 21:05:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8210,7 +8210,7 @@ This report was generated on **Fri May 15 19:11:54 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:55 WEST 2026** using +This report was generated on **Fri May 15 21:05:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8955,7 +8955,7 @@ This report was generated on **Fri May 15 19:11:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:55 WEST 2026** using +This report was generated on **Fri May 15 21:05:20 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9195,7 +9195,7 @@ This report was generated on **Fri May 15 19:11:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:54 WEST 2026** using +This report was generated on **Fri May 15 21:05:19 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9545,6 +9545,6 @@ This report was generated on **Fri May 15 19:11:54 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 19:11:54 WEST 2026** using +This report was generated on **Fri May 15 21:05:19 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/docs/dependencies/pom.xml b/docs/dependencies/pom.xml index aefd66f406..735dfb89a6 100644 --- a/docs/dependencies/pom.xml +++ b/docs/dependencies/pom.xml @@ -68,7 +68,7 @@ all modules and does not describe the project structure per-subproject. io.spine spine-validation-jvm-runtime - 2.0.0-SNAPSHOT.415 + 2.0.0-SNAPSHOT.419 compile @@ -295,7 +295,7 @@ all modules and does not describe the project structure per-subproject. io.spine.tools validation-java-bundle - 2.0.0-SNAPSHOT.415 + 2.0.0-SNAPSHOT.419 net.sourceforge.pmd From 0253ce8d6c70699b7b8a3ebf1762e9062e6f4924 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 21:19:19 +0100 Subject: [PATCH 18/36] Add the `StandardPlaceholder.placed` property --- .../kotlin/io/spine/validation/StandardPlaceholder.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt b/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt index 4a72f8fe7a..4696aea075 100644 --- a/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt +++ b/jvm-runtime/src/main/kotlin/io/spine/validation/StandardPlaceholder.kt @@ -67,4 +67,12 @@ public enum class StandardPlaceholder(public val value: Placeholder) { // Placeholder for the message options. REQUIRE_FIELDS(Placeholder("require.fields")); + + /** + * The placeholder text as it appears in a template string (e.g., `${field.path}`). + * + * Shortcut for [value].[placed][Placeholder.placed]. + */ + public val placed: String + get() = value.placed } From 1f3ff276dea893daf07df87049ea9781360ad3a9 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 21:23:46 +0100 Subject: [PATCH 19/36] Improve file name --- .../tools/validation/{ErrorPlaceholders.kt => Placeholders.kt} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename context/src/main/kotlin/io/spine/tools/validation/{ErrorPlaceholders.kt => Placeholders.kt} (98%) diff --git a/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt b/context/src/main/kotlin/io/spine/tools/validation/Placeholders.kt similarity index 98% rename from context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt rename to context/src/main/kotlin/io/spine/tools/validation/Placeholders.kt index 2a4838e58b..865ad0e6bf 100644 --- a/context/src/main/kotlin/io/spine/tools/validation/ErrorPlaceholders.kt +++ b/context/src/main/kotlin/io/spine/tools/validation/Placeholders.kt @@ -35,7 +35,7 @@ import io.spine.tools.compiler.ast.Span import io.spine.tools.compiler.ast.qualifiedName import io.spine.tools.compiler.check import io.spine.string.Placeholder -import io.spine.string.extractPlaceholders +import io.spine.string.Placeholder.Companion.extractPlaceholders /** * Checks if this [String] contains placeholders that are not present in the given From 84d4927f8f59f927bab6511aaf7ed668b3a2702b Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 22:19:15 +0100 Subject: [PATCH 20/36] Replace class names in the generated code --- .../kotlin/PatchGeneratedTemplateString.kt | 83 +++++++++++++++++++ context/build.gradle.kts | 2 + jvm-runtime/build.gradle.kts | 2 + 3 files changed, 87 insertions(+) create mode 100644 buildSrc/src/main/kotlin/PatchGeneratedTemplateString.kt diff --git a/buildSrc/src/main/kotlin/PatchGeneratedTemplateString.kt b/buildSrc/src/main/kotlin/PatchGeneratedTemplateString.kt new file mode 100644 index 0000000000..537f33133d --- /dev/null +++ b/buildSrc/src/main/kotlin/PatchGeneratedTemplateString.kt @@ -0,0 +1,83 @@ +/* + * Copyright 2026, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.tasks.TaskProvider +import org.gradle.kotlin.dsl.named +import org.gradle.kotlin.dsl.register + +/** + * Registers a `patchGeneratedTemplateString` task in the project, which replaces + * references to the legacy `io.spine.validation.TemplateString` class (and its + * proto FQN `.spine.validation.TemplateString`) with `io.spine.string.TemplateString` + * in the `generated/` sources. + * + * The task is wired to run after [upstreamTask] (the task that produces the sources + * to be patched) and before `compileJava` and `kspKotlin`. + * + * @param upstreamTask the name of the task whose output should be patched + * (e.g., `generateProto` or `launchSpineCompiler`). + */ +fun Project.patchGeneratedTemplateString(upstreamTask: String): TaskProvider { + val patchTask = tasks.register("patchGeneratedTemplateString") { + dependsOn(upstreamTask) + + val generatedDir = layout.projectDirectory.dir("generated") + inputs.dir(generatedDir).withPropertyName("generatedSources") + outputs.dir(generatedDir).withPropertyName("patchedSources") + + doLast { + val oldClassRef = "io.spine.validation.TemplateString" + val newClassRef = "io.spine.string.TemplateString" + val oldProtoRef = ".spine.validation.TemplateString" + val newProtoRef = ".spine.string.TemplateString" + generatedDir.asFile.walkTopDown() + .filter { it.isFile && (it.extension == "java" || it.extension == "kt") } + .forEach { file -> + val original = file.readText() + if (original.contains(oldClassRef) || original.contains(oldProtoRef)) { + val patched = original + .replace(oldClassRef, newClassRef) + .replace(oldProtoRef, newProtoRef) + file.writeText(patched) + } + } + } + } + + tasks.named("compileJava") { + dependsOn(patchTask) + } + + afterEvaluate { + tasks.named("kspKotlin") { + dependsOn(patchTask) + } + } + + return patchTask +} diff --git a/context/build.gradle.kts b/context/build.gradle.kts index 6006bb1c10..ace9fdf86d 100644 --- a/context/build.gradle.kts +++ b/context/build.gradle.kts @@ -65,3 +65,5 @@ afterEvaluate { val launchSpineCompiler by tasks.getting kspKotlin.dependsOn(launchSpineCompiler) } + +patchGeneratedTemplateString(upstreamTask = "launchSpineCompiler") diff --git a/jvm-runtime/build.gradle.kts b/jvm-runtime/build.gradle.kts index 1b839a3a32..d5aa9b8f6e 100644 --- a/jvm-runtime/build.gradle.kts +++ b/jvm-runtime/build.gradle.kts @@ -74,3 +74,5 @@ dependencies { } forceSpineBase() + +patchGeneratedTemplateString(upstreamTask = "generateProto") From 5f7a20b5df614c004003224a04e8674a2dfbe2b8 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 22:19:42 +0100 Subject: [PATCH 21/36] Migrate to new `TemplateString` --- .../kotlin/io/spine/validation/EnclosedMessageValidationSpec.kt | 1 + .../src/test/kotlin/io/spine/validation/IfMissingErrorMsgSpec.kt | 1 + .../src/test/kotlin/io/spine/validation/NumberRangeSpec.kt | 1 + .../src/test/kotlin/io/spine/validation/ValidateUtilitySpec.kt | 1 + .../kotlin/io/spine/validation/ValidationOfConstraintTest.kt | 1 + 5 files changed, 5 insertions(+) diff --git a/tests/runtime/src/test/kotlin/io/spine/validation/EnclosedMessageValidationSpec.kt b/tests/runtime/src/test/kotlin/io/spine/validation/EnclosedMessageValidationSpec.kt index dd57e1138a..678ed42476 100644 --- a/tests/runtime/src/test/kotlin/io/spine/validation/EnclosedMessageValidationSpec.kt +++ b/tests/runtime/src/test/kotlin/io/spine/validation/EnclosedMessageValidationSpec.kt @@ -27,6 +27,7 @@ package io.spine.validation import io.kotest.matchers.string.shouldContain +import io.spine.string.format import io.spine.test.validate.PatternStringFieldValue import io.spine.test.validate.ValidateEnclosed import io.spine.test.validate.ValidateWithRequiredString diff --git a/tests/runtime/src/test/kotlin/io/spine/validation/IfMissingErrorMsgSpec.kt b/tests/runtime/src/test/kotlin/io/spine/validation/IfMissingErrorMsgSpec.kt index 062a0211ce..659a6d11c8 100644 --- a/tests/runtime/src/test/kotlin/io/spine/validation/IfMissingErrorMsgSpec.kt +++ b/tests/runtime/src/test/kotlin/io/spine/validation/IfMissingErrorMsgSpec.kt @@ -30,6 +30,7 @@ import com.google.protobuf.Descriptors.Descriptor import com.google.protobuf.Message import io.kotest.matchers.shouldBe import io.spine.option.OptionsProto +import io.spine.string.format import io.spine.test.validate.CustomMessageRequiredByteStringFieldValue import io.spine.test.validate.CustomMessageRequiredEnumFieldValue import io.spine.test.validate.CustomMessageRequiredMsgFieldValue diff --git a/tests/runtime/src/test/kotlin/io/spine/validation/NumberRangeSpec.kt b/tests/runtime/src/test/kotlin/io/spine/validation/NumberRangeSpec.kt index 7286f5b8ae..284db0328e 100644 --- a/tests/runtime/src/test/kotlin/io/spine/validation/NumberRangeSpec.kt +++ b/tests/runtime/src/test/kotlin/io/spine/validation/NumberRangeSpec.kt @@ -29,6 +29,7 @@ package io.spine.validation import com.google.protobuf.Message import com.google.protobuf.doubleValue import io.kotest.matchers.string.shouldContain +import io.spine.string.format import io.spine.test.validate.MaxExclusive import io.spine.test.validate.MaxInclusive import io.spine.test.validate.MinExclusive diff --git a/tests/runtime/src/test/kotlin/io/spine/validation/ValidateUtilitySpec.kt b/tests/runtime/src/test/kotlin/io/spine/validation/ValidateUtilitySpec.kt index 27c7efae1a..0763c55f07 100644 --- a/tests/runtime/src/test/kotlin/io/spine/validation/ValidateUtilitySpec.kt +++ b/tests/runtime/src/test/kotlin/io/spine/validation/ValidateUtilitySpec.kt @@ -31,6 +31,7 @@ import com.google.protobuf.Message import io.kotest.matchers.shouldBe import io.spine.base.Time import io.spine.code.proto.FieldContext +import io.spine.string.templateString import io.spine.testing.UtilityClassTest import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test diff --git a/tests/runtime/src/test/kotlin/io/spine/validation/ValidationOfConstraintTest.kt b/tests/runtime/src/test/kotlin/io/spine/validation/ValidationOfConstraintTest.kt index 44a8b1d57f..2a0549e059 100644 --- a/tests/runtime/src/test/kotlin/io/spine/validation/ValidationOfConstraintTest.kt +++ b/tests/runtime/src/test/kotlin/io/spine/validation/ValidationOfConstraintTest.kt @@ -31,6 +31,7 @@ import com.google.protobuf.Message import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.shouldBe import io.kotest.matchers.string.shouldNotBeEmpty +import io.spine.string.format import io.spine.validation.Validate.violationsOf import org.junit.jupiter.api.Assertions.assertDoesNotThrow import org.junit.jupiter.api.assertThrows From 40f03c824739cc749c1bc781cf450b1afa2f2ae5 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 22:20:23 +0100 Subject: [PATCH 22/36] Use older placeholders code, for now We want to avoid importing the function from the previous version of Validation runtime. --- .../java/expression/TemplateStrings.kt | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt b/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt index 4cc217f357..e96786fcfc 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt @@ -35,7 +35,6 @@ import io.spine.tools.compiler.jvm.mapExpression import io.spine.tools.compiler.jvm.newBuilder import io.spine.string.Placeholder import io.spine.string.TemplateString -import io.spine.string.checkPlaceholdersHasValue /** * Yields an expression that creates a new instance of [TemplateString]. @@ -82,3 +81,55 @@ public fun withStringPlaceholders( .chainPutAll("placeholderValue", placeholderEntries) .chainBuild() } + +/** + * Makes sure that each placeholder within the [template] string is present + * in the [placeholders] set. + * + * @param template The template with placeholders like `${something}`. + * @param placeholders The list with placeholder values. + * @param lazyMessage The message to use in [IllegalArgumentException] if the check fails. + */ +private fun checkPlaceholdersHasValue( + template: String, + placeholders: Set, + lazyMessage: (List) -> String = + { "Missing value for the following template placeholders: `$it`." } +) { + val neededPlaceholders = extractPlaceholders(template) + val missing = mutableListOf() + for (placeholder in neededPlaceholders) { + if (!placeholders.contains(placeholder)) { + missing.add(placeholder) + } + } + if (missing.isNotEmpty()) { + throw IllegalArgumentException(lazyMessage(missing)) + } +} + +/** + * Makes sure that each placeholder within the [template] string has a value + * in [placeholders] map. + * + * @param template The template with placeholders like `${something}`. + * @param placeholders The map containing placeholders (without curly braces and the dollar sign) + * and their values. + * @param lazyMessage The message to use in [IllegalArgumentException] if the check fails. + */ +private fun checkPlaceholdersHasValue( + template: String, + placeholders: Map, + lazyMessage: (List) -> String = + { "Missing value for the following template placeholders: `$it`." } +): Unit = checkPlaceholdersHasValue(template, placeholders.keys, lazyMessage) + +/** + * Extracts all placeholders used within this [template] string. + */ +private fun extractPlaceholders(template: String): Set = + PLACEHOLDERS.findAll(template) + .map { it.groupValues[1] } + .toSet() + +private val PLACEHOLDERS = Regex("\\$\\{([^}]+)}") From 6554acbe628d0a9c717deb1652f8e6fdb9dacefe Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 22:23:49 +0100 Subject: [PATCH 23/36] Remove redundant `@JvmName` --- .../io/spine/tools/validation/java/expression/TemplateStrings.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt b/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt index e96786fcfc..2e1911af64 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt @@ -46,7 +46,6 @@ import io.spine.string.TemplateString * @param placeholders The supported placeholders and their values. * @param optionName The name of the option, which declared the provided [placeholders]. */ -@JvmName("templateStringExp") public fun templateString( template: String, placeholders: Map>, From f356b62e11df45f8c4b9f28e06b91541dc899d78 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 22:42:36 +0100 Subject: [PATCH 24/36] Bump Base -> `2.0.0-SNAPSHOT.389` --- buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt index 531fe788ac..6a0a489cc7 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt @@ -33,8 +33,8 @@ package io.spine.dependency.local */ @Suppress("ConstPropertyName", "unused") object Base { - const val version = "2.0.0-SNAPSHOT.388" - const val versionForBuildScript = "2.0.0-SNAPSHOT.388" + const val version = "2.0.0-SNAPSHOT.389" + const val versionForBuildScript = "2.0.0-SNAPSHOT.389" const val group = Spine.group private const val prefix = "spine" const val libModule = "$prefix-base" From 95fa80072973ae9f858a6f371affbf955859cea1 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 22:49:50 +0100 Subject: [PATCH 25/36] Update dependency reports --- docs/dependencies/dependencies.md | 32 +++++++++++++++---------------- docs/dependencies/pom.xml | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/dependencies/dependencies.md b/docs/dependencies/dependencies.md index c80fab105d..c48b549f98 100644 --- a/docs/dependencies/dependencies.md +++ b/docs/dependencies/dependencies.md @@ -1090,7 +1090,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:20 WEST 2026** using +This report was generated on **Fri May 15 22:46:56 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1791,7 +1791,7 @@ This report was generated on **Fri May 15 21:05:20 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:20 WEST 2026** using +This report was generated on **Fri May 15 22:46:55 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1805,7 +1805,7 @@ This report was generated on **Fri May 15 21:05:20 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:03:53 WEST 2026** using +This report was generated on **Fri May 15 22:46:54 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2864,7 +2864,7 @@ This report was generated on **Fri May 15 21:03:53 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:20 WEST 2026** using +This report was generated on **Fri May 15 22:46:55 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3961,7 +3961,7 @@ This report was generated on **Fri May 15 21:05:20 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:20 WEST 2026** using +This report was generated on **Fri May 15 22:46:55 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4015,7 +4015,7 @@ This report was generated on **Fri May 15 21:05:20 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:19 WEST 2026** using +This report was generated on **Fri May 15 22:46:54 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4822,7 +4822,7 @@ This report was generated on **Fri May 15 21:05:19 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:20 WEST 2026** using +This report was generated on **Fri May 15 22:46:55 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5511,7 +5511,7 @@ This report was generated on **Fri May 15 21:05:20 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:20 WEST 2026** using +This report was generated on **Fri May 15 22:46:55 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5976,7 +5976,7 @@ This report was generated on **Fri May 15 21:05:20 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:20 WEST 2026** using +This report was generated on **Fri May 15 22:46:55 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6602,7 +6602,7 @@ This report was generated on **Fri May 15 21:05:20 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:20 WEST 2026** using +This report was generated on **Fri May 15 22:46:55 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7170,7 +7170,7 @@ This report was generated on **Fri May 15 21:05:20 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:20 WEST 2026** using +This report was generated on **Fri May 15 22:46:55 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7599,7 +7599,7 @@ This report was generated on **Fri May 15 21:05:20 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:20 WEST 2026** using +This report was generated on **Fri May 15 22:46:55 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8210,7 +8210,7 @@ This report was generated on **Fri May 15 21:05:20 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:20 WEST 2026** using +This report was generated on **Fri May 15 22:46:55 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8955,7 +8955,7 @@ This report was generated on **Fri May 15 21:05:20 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:20 WEST 2026** using +This report was generated on **Fri May 15 22:46:55 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9195,7 +9195,7 @@ This report was generated on **Fri May 15 21:05:20 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:19 WEST 2026** using +This report was generated on **Fri May 15 22:46:55 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9545,6 +9545,6 @@ This report was generated on **Fri May 15 21:05:19 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 21:05:19 WEST 2026** using +This report was generated on **Fri May 15 22:46:54 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/docs/dependencies/pom.xml b/docs/dependencies/pom.xml index 735dfb89a6..8ef187585d 100644 --- a/docs/dependencies/pom.xml +++ b/docs/dependencies/pom.xml @@ -50,7 +50,7 @@ all modules and does not describe the project structure per-subproject. io.spine spine-base - 2.0.0-SNAPSHOT.388 + 2.0.0-SNAPSHOT.389 compile From 3a08b4d7b95db0e62166b8482ce7a59d77e3de81 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 22:50:09 +0100 Subject: [PATCH 26/36] Migrate to `Placeholder` API --- .../java/expression/TemplateStrings.kt | 70 ++++--------------- .../validation/test/CurrencyGenerator.kt | 9 +-- 2 files changed, 18 insertions(+), 61 deletions(-) diff --git a/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt b/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt index 2e1911af64..56156c88e5 100644 --- a/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt +++ b/java/src/main/kotlin/io/spine/tools/validation/java/expression/TemplateStrings.kt @@ -35,6 +35,7 @@ import io.spine.tools.compiler.jvm.mapExpression import io.spine.tools.compiler.jvm.newBuilder import io.spine.string.Placeholder import io.spine.string.TemplateString +import io.spine.string.joinQuoted /** * Yields an expression that creates a new instance of [TemplateString]. @@ -50,29 +51,17 @@ public fun templateString( template: String, placeholders: Map>, optionName: String -): Expression = - withStringPlaceholders(template, placeholders.mapKeys { it.key.name }, optionName) - -/** - * Yields an expression that creates a new instance of [TemplateString]. - * - * @param placeholders The supported placeholders and their values. - * @param optionName The name of the option, which declared the provided [placeholders]. - */ -public fun withStringPlaceholders( - template: String, - placeholders: Map>, - optionName: String ): Expression { - checkPlaceholdersHasValue(template, placeholders) { missingKeys -> - "Unexpected error message placeholders `$missingKeys` specified for the `($optionName)`" + - " option. The available placeholders: `${placeholders.keys}`. Please make sure" + - " that the code that verifies the message placeholders and its code generator" + - " operate with the same set of placeholders." + checkPlaceholdersHasValue(template, placeholders.keys) { missing -> + "Unexpected error message placeholders ${missing.joinQuoted()} specified for" + + " the `($optionName)` option." + + " The available placeholders: ${placeholders.keys.joinQuoted()}." + + " Please make sure that the code that verifies the message placeholders and" + + " its code generator operate with the same set of placeholders." } val placeholderEntries = mapExpression( StringClass, StringClass, - placeholders.mapKeys { StringLiteral(it.key) } + placeholders.mapKeys { StringLiteral(it.key.name) } ) val escapedTemplate = restoreProtobufEscapes(template) return TemplateStringClass.newBuilder() @@ -86,49 +75,16 @@ public fun withStringPlaceholders( * in the [placeholders] set. * * @param template The template with placeholders like `${something}`. - * @param placeholders The list with placeholder values. - * @param lazyMessage The message to use in [IllegalArgumentException] if the check fails. + * @param placeholders The set of available placeholders. */ private fun checkPlaceholdersHasValue( template: String, - placeholders: Set, - lazyMessage: (List) -> String = - { "Missing value for the following template placeholders: `$it`." } + placeholders: Set, + lazyMessage: (List) -> String ) { - val neededPlaceholders = extractPlaceholders(template) - val missing = mutableListOf() - for (placeholder in neededPlaceholders) { - if (!placeholders.contains(placeholder)) { - missing.add(placeholder) - } - } + val needed = Placeholder.extractPlaceholders(template) + val missing = needed.filter { it !in placeholders } if (missing.isNotEmpty()) { throw IllegalArgumentException(lazyMessage(missing)) } } - -/** - * Makes sure that each placeholder within the [template] string has a value - * in [placeholders] map. - * - * @param template The template with placeholders like `${something}`. - * @param placeholders The map containing placeholders (without curly braces and the dollar sign) - * and their values. - * @param lazyMessage The message to use in [IllegalArgumentException] if the check fails. - */ -private fun checkPlaceholdersHasValue( - template: String, - placeholders: Map, - lazyMessage: (List) -> String = - { "Missing value for the following template placeholders: `$it`." } -): Unit = checkPlaceholdersHasValue(template, placeholders.keys, lazyMessage) - -/** - * Extracts all placeholders used within this [template] string. - */ -private fun extractPlaceholders(template: String): Set = - PLACEHOLDERS.findAll(template) - .map { it.groupValues[1] } - .toSet() - -private val PLACEHOLDERS = Regex("\\$\\{([^}]+)}") diff --git a/tests/extensions/src/main/kotlin/io/spine/tools/validation/test/CurrencyGenerator.kt b/tests/extensions/src/main/kotlin/io/spine/tools/validation/test/CurrencyGenerator.kt index 3bb66c66c2..ef1a2d4194 100644 --- a/tests/extensions/src/main/kotlin/io/spine/tools/validation/test/CurrencyGenerator.kt +++ b/tests/extensions/src/main/kotlin/io/spine/tools/validation/test/CurrencyGenerator.kt @@ -27,6 +27,7 @@ package io.spine.tools.validation.test import io.spine.server.query.select +import io.spine.string.Placeholder import io.spine.tools.compiler.ast.TypeName import io.spine.tools.compiler.jvm.CodeBlock import io.spine.tools.compiler.jvm.Expression @@ -36,7 +37,7 @@ import io.spine.tools.validation.java.expression.constraintViolation import io.spine.tools.validation.java.expression.orElse import io.spine.tools.validation.java.expression.stringValueOf import io.spine.tools.validation.java.expression.stringify -import io.spine.tools.validation.java.expression.withStringPlaceholders +import io.spine.tools.validation.java.expression.templateString import io.spine.tools.validation.java.generate.MessageScope.message import io.spine.tools.validation.java.generate.OptionGenerator import io.spine.tools.validation.java.generate.SingleOptionCode @@ -101,12 +102,12 @@ private class GenerateCurrency(private val view: CurrencyMessage) { ): Expression { val typeNameStr = typeName.stringify() val placeholders = supportedPlaceholders(minorValue) - val errorMessage = withStringPlaceholders(view.errorMessage, placeholders, CURRENCY) + val errorMessage = templateString(view.errorMessage, placeholders, CURRENCY) return constraintViolation(errorMessage, typeNameStr, fieldPath = null, fieldValue = null) } private fun supportedPlaceholders( minorValue: Expression - ): Map> = - mapOf("minor.value" to minorField.stringValueOf(minorValue)) + ): Map> = + mapOf(Placeholder("minor.value") to minorField.stringValueOf(minorValue)) } From 483781e099a5477595a80e5c6613b221213822e3 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 22:51:01 +0100 Subject: [PATCH 27/36] Update dependency reports --- docs/dependencies/dependencies.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/dependencies/dependencies.md b/docs/dependencies/dependencies.md index c48b549f98..05a51e9c5a 100644 --- a/docs/dependencies/dependencies.md +++ b/docs/dependencies/dependencies.md @@ -1090,7 +1090,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:56 WEST 2026** using +This report was generated on **Fri May 15 22:50:02 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1791,7 +1791,7 @@ This report was generated on **Fri May 15 22:46:56 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:55 WEST 2026** using +This report was generated on **Fri May 15 22:50:01 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2864,7 +2864,7 @@ This report was generated on **Fri May 15 22:46:54 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:55 WEST 2026** using +This report was generated on **Fri May 15 22:50:01 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3961,7 +3961,7 @@ This report was generated on **Fri May 15 22:46:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:55 WEST 2026** using +This report was generated on **Fri May 15 22:50:02 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4015,7 +4015,7 @@ This report was generated on **Fri May 15 22:46:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:54 WEST 2026** using +This report was generated on **Fri May 15 22:49:58 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4822,7 +4822,7 @@ This report was generated on **Fri May 15 22:46:54 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:55 WEST 2026** using +This report was generated on **Fri May 15 22:50:01 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5511,7 +5511,7 @@ This report was generated on **Fri May 15 22:46:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:55 WEST 2026** using +This report was generated on **Fri May 15 22:50:00 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5976,7 +5976,7 @@ This report was generated on **Fri May 15 22:46:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:55 WEST 2026** using +This report was generated on **Fri May 15 22:50:00 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6602,7 +6602,7 @@ This report was generated on **Fri May 15 22:46:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:55 WEST 2026** using +This report was generated on **Fri May 15 22:50:00 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7170,7 +7170,7 @@ This report was generated on **Fri May 15 22:46:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:55 WEST 2026** using +This report was generated on **Fri May 15 22:50:00 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7599,7 +7599,7 @@ This report was generated on **Fri May 15 22:46:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:55 WEST 2026** using +This report was generated on **Fri May 15 22:50:00 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8210,7 +8210,7 @@ This report was generated on **Fri May 15 22:46:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:55 WEST 2026** using +This report was generated on **Fri May 15 22:50:01 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8955,7 +8955,7 @@ This report was generated on **Fri May 15 22:46:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:55 WEST 2026** using +This report was generated on **Fri May 15 22:50:00 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9195,7 +9195,7 @@ This report was generated on **Fri May 15 22:46:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:55 WEST 2026** using +This report was generated on **Fri May 15 22:49:59 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9545,6 +9545,6 @@ This report was generated on **Fri May 15 22:46:55 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:54 WEST 2026** using +This report was generated on **Fri May 15 22:49:59 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file From 5780fa51637e6408e87779d6ed7655ad09566f31 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 23:37:18 +0100 Subject: [PATCH 28/36] Force Time runtime libraries --- build.gradle.kts | 1 + buildSrc/src/main/kotlin/module.gradle.kts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 983b380cd4..5c03c998e0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -129,6 +129,7 @@ allprojects { Roaster.jdt, Time.lib, Time.javaExtensions, + Time.kotlinExtensions, ToolBase.lib, ToolBase.pluginBase, Validation.javaBundle, diff --git a/buildSrc/src/main/kotlin/module.gradle.kts b/buildSrc/src/main/kotlin/module.gradle.kts index 4596634b75..ad96f75756 100644 --- a/buildSrc/src/main/kotlin/module.gradle.kts +++ b/buildSrc/src/main/kotlin/module.gradle.kts @@ -170,6 +170,8 @@ fun Module.forceConfigurations() { Base.environment, Protobuf.compiler, Time.lib, + Time.javaExtensions, + Time.kotlinExtensions, TestLib.lib, ToolBase.gradlePluginApi, ToolBase.jvmTools, From 5191bb1feac34ab9f3d8a5ed5a3f203675c61856 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 15 May 2026 23:38:38 +0100 Subject: [PATCH 29/36] Update build time --- docs/dependencies/dependencies.md | 32 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/dependencies/dependencies.md b/docs/dependencies/dependencies.md index 05a51e9c5a..4345f29f0a 100644 --- a/docs/dependencies/dependencies.md +++ b/docs/dependencies/dependencies.md @@ -1090,7 +1090,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:50:02 WEST 2026** using +This report was generated on **Fri May 15 23:37:33 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1791,7 +1791,7 @@ This report was generated on **Fri May 15 22:50:02 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:50:01 WEST 2026** using +This report was generated on **Fri May 15 23:37:33 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1805,7 +1805,7 @@ This report was generated on **Fri May 15 22:50:01 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:46:54 WEST 2026** using +This report was generated on **Fri May 15 23:37:32 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2864,7 +2864,7 @@ This report was generated on **Fri May 15 22:46:54 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:50:01 WEST 2026** using +This report was generated on **Fri May 15 23:37:33 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3961,7 +3961,7 @@ This report was generated on **Fri May 15 22:50:01 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:50:02 WEST 2026** using +This report was generated on **Fri May 15 23:37:33 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4015,7 +4015,7 @@ This report was generated on **Fri May 15 22:50:02 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:49:58 WEST 2026** using +This report was generated on **Fri May 15 23:37:32 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4822,7 +4822,7 @@ This report was generated on **Fri May 15 22:49:58 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:50:01 WEST 2026** using +This report was generated on **Fri May 15 23:37:33 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5511,7 +5511,7 @@ This report was generated on **Fri May 15 22:50:01 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:50:00 WEST 2026** using +This report was generated on **Fri May 15 23:37:33 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5976,7 +5976,7 @@ This report was generated on **Fri May 15 22:50:00 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:50:00 WEST 2026** using +This report was generated on **Fri May 15 23:37:33 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6602,7 +6602,7 @@ This report was generated on **Fri May 15 22:50:00 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:50:00 WEST 2026** using +This report was generated on **Fri May 15 23:37:33 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7170,7 +7170,7 @@ This report was generated on **Fri May 15 22:50:00 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:50:00 WEST 2026** using +This report was generated on **Fri May 15 23:37:33 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7599,7 +7599,7 @@ This report was generated on **Fri May 15 22:50:00 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:50:00 WEST 2026** using +This report was generated on **Fri May 15 23:37:33 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8210,7 +8210,7 @@ This report was generated on **Fri May 15 22:50:00 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:50:01 WEST 2026** using +This report was generated on **Fri May 15 23:37:33 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8955,7 +8955,7 @@ This report was generated on **Fri May 15 22:50:01 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:50:00 WEST 2026** using +This report was generated on **Fri May 15 23:37:33 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9195,7 +9195,7 @@ This report was generated on **Fri May 15 22:50:00 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:49:59 WEST 2026** using +This report was generated on **Fri May 15 23:37:32 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9545,6 +9545,6 @@ This report was generated on **Fri May 15 22:49:59 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 22:49:59 WEST 2026** using +This report was generated on **Fri May 15 23:37:32 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file From b84be3513d1f8b58a9b7c102b671bb7954795850 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 16 May 2026 15:14:05 +0100 Subject: [PATCH 30/36] Update embedded code --- docs/content/docs/validation/developer/build-and-release.md | 2 +- docs/content/docs/validation/developer/validation-model.md | 4 ++-- .../validation/user/01-getting-started/adding-to-build.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/content/docs/validation/developer/build-and-release.md b/docs/content/docs/validation/developer/build-and-release.md index dc0ca90609..af2858aec1 100644 --- a/docs/content/docs/validation/developer/build-and-release.md +++ b/docs/content/docs/validation/developer/build-and-release.md @@ -47,7 +47,7 @@ through Gradle's `extra` properties: end="val validationVersion"> ```kotlin -val validationVersion by extra("2.0.0-SNAPSHOT.421") +val validationVersion by extra("2.0.0-SNAPSHOT.430") ``` The root build script applies this file under `allprojects { … }` and assigns diff --git a/docs/content/docs/validation/developer/validation-model.md b/docs/content/docs/validation/developer/validation-model.md index e5ad33780b..52ad8052de 100644 --- a/docs/content/docs/validation/developer/validation-model.md +++ b/docs/content/docs/validation/developer/validation-model.md @@ -298,7 +298,7 @@ not free-form. Each option declares the placeholders it supports, and the reacti validates the template before the event is emitted: @@ -315,7 +315,7 @@ private fun String.checkPlaceholders( Compilation.check(missing.isEmpty(), file, span) { "The $declaration specifies an error message for the `($option)` option using unsupported" + " placeholders: `$missing`. Supported placeholders are the following:" + - " `${supported.map { it.value }}`." + " `${supported.map { it.name }}`." } } ``` diff --git a/docs/content/docs/validation/user/01-getting-started/adding-to-build.md b/docs/content/docs/validation/user/01-getting-started/adding-to-build.md index ab88f3805d..74b137cacb 100644 --- a/docs/content/docs/validation/user/01-getting-started/adding-to-build.md +++ b/docs/content/docs/validation/user/01-getting-started/adding-to-build.md @@ -90,7 +90,7 @@ Add the Validation plugin to the build. ```kotlin plugins { module - id("io.spine.validation") version "2.0.0-SNAPSHOT.421" + id("io.spine.validation") version "2.0.0-SNAPSHOT.430" } ``` From c7c17ef0621100194292b6d6552fffad3a3c11ff Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 16 May 2026 15:14:16 +0100 Subject: [PATCH 31/36] Bump Validation --- docs/_examples | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_examples b/docs/_examples index 0857c90894..1632f6f02b 160000 --- a/docs/_examples +++ b/docs/_examples @@ -1 +1 @@ -Subproject commit 0857c90894b6f4a4caf12408088c6b59768110ce +Subproject commit 1632f6f02b81ec52b0ef99365a352a8333f8094e From 6f6da7c8d9a0b23fe1ba69ddbb51c9098a3cf061 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 16 May 2026 15:56:18 +0100 Subject: [PATCH 32/36] Update build time --- docs/dependencies/dependencies.md | 32 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/dependencies/dependencies.md b/docs/dependencies/dependencies.md index 4345f29f0a..6a16cfa00c 100644 --- a/docs/dependencies/dependencies.md +++ b/docs/dependencies/dependencies.md @@ -1090,7 +1090,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:33 WEST 2026** using +This report was generated on **Sat May 16 15:55:10 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1791,7 +1791,7 @@ This report was generated on **Fri May 15 23:37:33 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:33 WEST 2026** using +This report was generated on **Sat May 16 15:55:10 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1805,7 +1805,7 @@ This report was generated on **Fri May 15 23:37:33 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:32 WEST 2026** using +This report was generated on **Sat May 16 15:49:45 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2864,7 +2864,7 @@ This report was generated on **Fri May 15 23:37:32 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:33 WEST 2026** using +This report was generated on **Sat May 16 15:55:10 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3961,7 +3961,7 @@ This report was generated on **Fri May 15 23:37:33 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:33 WEST 2026** using +This report was generated on **Sat May 16 15:55:10 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4015,7 +4015,7 @@ This report was generated on **Fri May 15 23:37:33 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:32 WEST 2026** using +This report was generated on **Sat May 16 15:55:09 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4822,7 +4822,7 @@ This report was generated on **Fri May 15 23:37:32 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:33 WEST 2026** using +This report was generated on **Sat May 16 15:55:10 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5511,7 +5511,7 @@ This report was generated on **Fri May 15 23:37:33 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:33 WEST 2026** using +This report was generated on **Sat May 16 15:55:10 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5976,7 +5976,7 @@ This report was generated on **Fri May 15 23:37:33 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:33 WEST 2026** using +This report was generated on **Sat May 16 15:55:10 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6602,7 +6602,7 @@ This report was generated on **Fri May 15 23:37:33 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:33 WEST 2026** using +This report was generated on **Sat May 16 15:55:10 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7170,7 +7170,7 @@ This report was generated on **Fri May 15 23:37:33 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:33 WEST 2026** using +This report was generated on **Sat May 16 15:55:10 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7599,7 +7599,7 @@ This report was generated on **Fri May 15 23:37:33 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:33 WEST 2026** using +This report was generated on **Sat May 16 15:55:10 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8210,7 +8210,7 @@ This report was generated on **Fri May 15 23:37:33 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:33 WEST 2026** using +This report was generated on **Sat May 16 15:55:10 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8955,7 +8955,7 @@ This report was generated on **Fri May 15 23:37:33 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:33 WEST 2026** using +This report was generated on **Sat May 16 15:55:10 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9195,7 +9195,7 @@ This report was generated on **Fri May 15 23:37:33 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:32 WEST 2026** using +This report was generated on **Sat May 16 15:55:09 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9545,6 +9545,6 @@ This report was generated on **Fri May 15 23:37:32 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 15 23:37:32 WEST 2026** using +This report was generated on **Sat May 16 15:55:09 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file From d438c4b5ddb1329d734f1f7f6c5a57ca7faab0f2 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 16 May 2026 16:55:51 +0100 Subject: [PATCH 33/36] Update docs/_examples submodule reference --- docs/_examples | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_examples b/docs/_examples index 1632f6f02b..0857c90894 160000 --- a/docs/_examples +++ b/docs/_examples @@ -1 +1 @@ -Subproject commit 1632f6f02b81ec52b0ef99365a352a8333f8094e +Subproject commit 0857c90894b6f4a4caf12408088c6b59768110ce From 5abad2e9c1a447f436951fcef3e0cbc45722e8a7 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 16 May 2026 17:34:31 +0100 Subject: [PATCH 34/36] Update `_example` ref. --- docs/_examples | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_examples b/docs/_examples index 0857c90894..04b2a5f00f 160000 --- a/docs/_examples +++ b/docs/_examples @@ -1 +1 @@ -Subproject commit 0857c90894b6f4a4caf12408088c6b59768110ce +Subproject commit 04b2a5f00fe5bd8d5cd069dfa56a403a407c0eed From 1e7e1ffba354884e5bacd761e0dd0669a5d2273b Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 16 May 2026 18:37:49 +0100 Subject: [PATCH 35/36] Update examples ref. --- docs/_examples | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_examples b/docs/_examples index 04b2a5f00f..ec10968b5e 160000 --- a/docs/_examples +++ b/docs/_examples @@ -1 +1 @@ -Subproject commit 04b2a5f00fe5bd8d5cd069dfa56a403a407c0eed +Subproject commit ec10968b5e925e217f809eed31a9312d1b8a8684 From 44f36573993b07687b0ee336d1b471a06fbc0fed Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 16 May 2026 18:37:56 +0100 Subject: [PATCH 36/36] Update build time --- docs/dependencies/dependencies.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/dependencies/dependencies.md b/docs/dependencies/dependencies.md index 6a16cfa00c..8ef411d895 100644 --- a/docs/dependencies/dependencies.md +++ b/docs/dependencies/dependencies.md @@ -1090,7 +1090,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:10 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1791,7 +1791,7 @@ This report was generated on **Sat May 16 15:55:10 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:10 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2864,7 +2864,7 @@ This report was generated on **Sat May 16 15:49:45 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:10 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3961,7 +3961,7 @@ This report was generated on **Sat May 16 15:55:10 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:10 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4015,7 +4015,7 @@ This report was generated on **Sat May 16 15:55:10 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:09 WEST 2026** using +This report was generated on **Sat May 16 17:35:15 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4822,7 +4822,7 @@ This report was generated on **Sat May 16 15:55:09 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:10 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5511,7 +5511,7 @@ This report was generated on **Sat May 16 15:55:10 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:10 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5976,7 +5976,7 @@ This report was generated on **Sat May 16 15:55:10 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:10 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6602,7 +6602,7 @@ This report was generated on **Sat May 16 15:55:10 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:10 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7170,7 +7170,7 @@ This report was generated on **Sat May 16 15:55:10 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:10 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7599,7 +7599,7 @@ This report was generated on **Sat May 16 15:55:10 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:10 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8210,7 +8210,7 @@ This report was generated on **Sat May 16 15:55:10 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:10 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8955,7 +8955,7 @@ This report was generated on **Sat May 16 15:55:10 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:10 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9195,7 +9195,7 @@ This report was generated on **Sat May 16 15:55:10 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:09 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9545,6 +9545,6 @@ This report was generated on **Sat May 16 15:55:09 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat May 16 15:55:09 WEST 2026** using +This report was generated on **Sat May 16 17:35:16 WEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file