From dd16cf66e68b42f9b2846ec7aa54c8dd2d1a9f7c Mon Sep 17 00:00:00 2001
From: Ashley Scopes <73482956+ascopes@users.noreply.github.com>
Date: Sun, 6 Jul 2025 13:46:25 +0100
Subject: [PATCH 1/2] Use immutables:datatype to remove the need for modifiable
parameter type duplicates
Implement initial POC for hooking Plexus into immutable builder classes
Use fix from https://github.com/paul-hammant/qdox/pull/271 temporarily to work around https://github.com/apache/maven-plugin-tools/issues/944
Fix test compilation failure
Fix ImmutablesDataPlexusConverter to handle stdlib/primitive types correctly
Start writing unit tests for plexus converter for Immutables types
Update logic in plexus converters
Use Datatypes rather than Data for immutables
Ran into https://github.com/immutables/immutables/issues/1608 when initialising the data type descriptors.
Add missing test case for https://github.com/immutables/immutables/issues/1608
Update Plexus converter to use weak references to class types
Move test data to subpackage
Fix issues with nested type handling, add new test cases
Suppress testdata in Checkstyle
---
.mvn/checkstyle/suppressions.xml | 3 +-
protobuf-maven-plugin/pom.xml | 6 +
.../dependencies/MavenDependency.java | 6 +-
.../dependencies/MavenExclusion.java | 6 +-
.../mojo/AbstractGenerateMojo.java | 12 +-
.../protobufmavenplugin/package-info.java | 2 -
.../plexus/ImmutablesDataPlexusConverter.java | 178 ++++++++++++++++++
.../protobufmavenplugin/plexus/KindHint.java | 20 +-
.../plexus/SealedTypePlexusConverter.java | 11 +-
.../BinaryMavenProtocPlugin.java | 5 +-
.../distributions/JvmMavenProtocPlugin.java | 8 +-
.../distributions/PathProtocPlugin.java | 8 +-
.../distributions/UriProtocPlugin.java | 15 +-
.../BinaryMavenProtocDistribution.java | 4 +-
.../distributions/PathProtocDistribution.java | 4 +-
.../distributions/UriProtocDistribution.java | 5 +-
.../fixtures/DependencyFixtures.java | 8 +-
.../AbstractGenerateMojoTestTemplate.java | 28 +--
.../ImmutablesDataPlexusConverterTest.java | 159 ++++++++++++++++
.../plexus/SealedTypePlexusConverterTest.java | 27 ++-
.../testdata/Datatypes_SomeBrokenModel.java | 21 +++
.../plexus/testdata/SomeBrokenModel.java | 19 ++
.../plexus/testdata/ValidInnerModel.java | 28 +++
.../plexus/testdata/ValidOuterModel.java | 31 +++
24 files changed, 525 insertions(+), 89 deletions(-)
create mode 100644 protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/plexus/ImmutablesDataPlexusConverter.java
create mode 100644 protobuf-maven-plugin/src/test/java/io/github/ascopes/protobufmavenplugin/plexus/ImmutablesDataPlexusConverterTest.java
create mode 100644 protobuf-maven-plugin/src/test/java/io/github/ascopes/protobufmavenplugin/plexus/testdata/Datatypes_SomeBrokenModel.java
create mode 100644 protobuf-maven-plugin/src/test/java/io/github/ascopes/protobufmavenplugin/plexus/testdata/SomeBrokenModel.java
create mode 100644 protobuf-maven-plugin/src/test/java/io/github/ascopes/protobufmavenplugin/plexus/testdata/ValidInnerModel.java
create mode 100644 protobuf-maven-plugin/src/test/java/io/github/ascopes/protobufmavenplugin/plexus/testdata/ValidOuterModel.java
diff --git a/.mvn/checkstyle/suppressions.xml b/.mvn/checkstyle/suppressions.xml
index 0157283f..f0038fb2 100644
--- a/.mvn/checkstyle/suppressions.xml
+++ b/.mvn/checkstyle/suppressions.xml
@@ -20,4 +20,5 @@
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
-
\ No newline at end of file
+
+
diff --git a/protobuf-maven-plugin/pom.xml b/protobuf-maven-plugin/pom.xml
index b957c0ad..e27d90cd 100644
--- a/protobuf-maven-plugin/pom.xml
+++ b/protobuf-maven-plugin/pom.xml
@@ -89,6 +89,12 @@
provided
+
+ org.immutables
+ datatype
+ compile
+
+
org.immutablesvalue
diff --git a/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/dependencies/MavenDependency.java b/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/dependencies/MavenDependency.java
index 7dac2aad..1d02f4e7 100644
--- a/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/dependencies/MavenDependency.java
+++ b/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/dependencies/MavenDependency.java
@@ -17,8 +17,8 @@
import io.github.ascopes.protobufmavenplugin.utils.DeadCodeGenerated;
import java.util.Set;
+import org.immutables.datatype.Data;
import org.immutables.value.Value.Immutable;
-import org.immutables.value.Value.Modifiable;
import org.jspecify.annotations.Nullable;
@@ -28,13 +28,13 @@
* @author Ashley Scopes
* @since 3.3.1
*/
+@Data
@Immutable
-@Modifiable
public abstract class MavenDependency extends MavenArtifact {
public abstract @Nullable DependencyResolutionDepth getDependencyResolutionDepth();
- public abstract Set getExclusions();
+ public abstract Set getExclusions();
@DeadCodeGenerated(reason = "Must be overridden to keep immutables happy.")
@Override
diff --git a/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/dependencies/MavenExclusion.java b/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/dependencies/MavenExclusion.java
index 890806d0..3d56b65a 100644
--- a/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/dependencies/MavenExclusion.java
+++ b/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/dependencies/MavenExclusion.java
@@ -15,7 +15,8 @@
*/
package io.github.ascopes.protobufmavenplugin.dependencies;
-import org.immutables.value.Value.Modifiable;
+import org.immutables.datatype.Data;
+import org.immutables.value.Value.Immutable;
/**
* Marker to exclude a specific transitive dependency.
@@ -26,7 +27,8 @@
* @author Ashley Scopes
* @since 2.12.0
*/
-@Modifiable
+@Data
+@Immutable
public interface MavenExclusion {
/**
diff --git a/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/mojo/AbstractGenerateMojo.java b/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/mojo/AbstractGenerateMojo.java
index 19e788d6..53dae85a 100644
--- a/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/mojo/AbstractGenerateMojo.java
+++ b/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/mojo/AbstractGenerateMojo.java
@@ -20,7 +20,7 @@
import static java.util.function.Predicate.not;
import io.github.ascopes.protobufmavenplugin.dependencies.DependencyResolutionDepth;
-import io.github.ascopes.protobufmavenplugin.dependencies.MavenDependencyBean;
+import io.github.ascopes.protobufmavenplugin.dependencies.MavenDependency;
import io.github.ascopes.protobufmavenplugin.digests.Digest;
import io.github.ascopes.protobufmavenplugin.generation.GenerationResult;
import io.github.ascopes.protobufmavenplugin.generation.ImmutableGenerationRequest;
@@ -301,7 +301,7 @@ public AbstractGenerateMojo() {
* @since 1.2.0
*/
@Parameter
- @Nullable List importDependencies;
+ @Nullable List importDependencies;
/**
* Specify additional paths to import protobuf sources from on the local file system.
@@ -743,7 +743,7 @@ public AbstractGenerateMojo() {
* @since 1.2.0
*/
@Parameter
- @Nullable List sourceDependencies;
+ @Nullable List sourceDependencies;
/**
* Protobuf Descriptor files to compile.
@@ -777,7 +777,7 @@ public AbstractGenerateMojo() {
* @since 3.1.0
*/
@Parameter
- @Nullable List sourceDescriptorDependencies;
+ @Nullable List sourceDescriptorDependencies;
/**
* The source directories to compile protobuf sources from.
@@ -813,6 +813,10 @@ public AbstractGenerateMojo() {
@Parameter
@Nullable List sourceDescriptorPaths;
+ /*
+ * Implementation-specific details.
+ */
+
/**
* Provides the default source directory to read protobuf sources from.
*
diff --git a/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/package-info.java b/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/package-info.java
index 2f44a8dd..92baf24a 100644
--- a/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/package-info.java
+++ b/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/package-info.java
@@ -19,8 +19,6 @@
*/
@NullMarked
@Style(
- beanFriendlyModifiables = true,
- create = "new",
defaults = @Immutable(copy = false),
defaultAsDefault = true,
get = {"get*", "is*"},
diff --git a/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/plexus/ImmutablesDataPlexusConverter.java b/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/plexus/ImmutablesDataPlexusConverter.java
new file mode 100644
index 00000000..fa9dcb71
--- /dev/null
+++ b/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/plexus/ImmutablesDataPlexusConverter.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2023 Ashley Scopes
+ *
+ * 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
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.github.ascopes.protobufmavenplugin.plexus;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+import java.util.WeakHashMap;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
+import org.codehaus.plexus.component.configurator.ConfigurationListener;
+import org.codehaus.plexus.component.configurator.converters.ParameterizedConfigurationConverter;
+import org.codehaus.plexus.component.configurator.converters.basic.AbstractBasicConverter;
+import org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup;
+import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.immutables.datatype.Datatype;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Converter for Plexus components that can build a generated "immutables" value type, based
+ * on the interface it was derived from.
+ *
+ *
Note that all objects must be annotated with both {@link org.immutables.value.Value}
+ * and {@link org.immutables.datatype.Data}, otherwise deserialization will fail at
+ * runtime.
+ *
+ * @author Ashley Scopes
+ * @since TBC
+ */
+@Named
+@Singleton
+final class ImmutablesDataPlexusConverter extends AbstractBasicConverter {
+ private final Map, Datatype