Repository: immutables/immutables
Issue: Generation with javax.validation.NotNull annotation fails

Using immutables 2.6.1 (and 1.8.0_171 on macOS) , annotation processing of this code (using Validation API 2.0):

```java
import javax.validation.constraints.NotNull;
import org.immutables.value.Value;

@Value.Immutable
public interface Test {
  @NotNull
  String getTest();
}
```

Fails with this exception:
```java
error: org.immutables.value.internal.$processor$.$Processor threw java.lang.IllegalArgumentException: Cannot parse type from input string '(@javax.validation.constraints.NotNull :: java.lang.String)'. unexpected term '('
        at org.immutables.value.internal.$processor$.encode.$Type$Parser$1Reader.type($Type.java:767)
        at org.immutables.value.internal.$processor$.encode.$Type$Parser.doParse($Type.java:891)
        at org.immutables.value.internal.$processor$.encode.$Type$Parser.parse($Type.java:715)
        at org.immutables.value.internal.$processor$.meta.$FromSupertypesModel.isEligibleFromType($FromSupertypesModel.java:137)
        at org.immutables.value.internal.$processor$.meta.$FromSupertypesModel.<init>($FromSupertypesModel.java:78)
        at org.immutables.value.internal.$processor$.meta.$ValueType.getBuildFromTypes($ValueType.java:1358)
        at org.immutables.value.internal.$processor$.$Generator_Immutables._t18__generateBuilder($Generator_Immutables.java:5008)
        at org.immutables.value.internal.$processor$.$Generator_Immutables$FragmentDispatch.run($Generator_Immutables.java:19510)
        at org.immutables.value.internal.$generator$.$Templates$Fragment.invoke($Templates.java:248)
        at org.immutables.value.internal.$generator$.$Intrinsics.$($Intrinsics.java:96)
        at org.immutables.value.internal.$processor$.$Generator_Immutables._t4__generateImmutable($Generator_Immutables.java:601)
        at org.immutables.value.internal.$processor$.$Generator_Immutables$FragmentDispatch.run($Generator_Immutables.java:19496)
        at org.immutables.value.internal.$generator$.$Templates$Fragment.invoke($Templates.java:248)
        at org.immutables.value.internal.$generator$.$Intrinsics.$($Intrinsics.java:96)
        at org.immutables.value.internal.$processor$.$Generator_Immutables$1.run($Generator_Immutables.java:23)
        at org.immutables.value.internal.$generator$.$Templates$Fragment.invoke($Templates.java:248)
        at org.immutables.value.internal.$generator$.$Output$7.invoke($Output.java:174)
        at org.immutables.value.internal.$generator$.$Intrinsics.$($Intrinsics.java:96)
        at org.immutables.value.internal.$processor$.$Generator_Immutables._t0__generate($Generator_Immutables.java:20)
        at org.immutables.value.internal.$processor$.$Generator_Immutables$FragmentDispatch.run($Generator_Immutables.java:19492)
        at org.immutables.value.internal.$generator$.$Templates$Fragment.invoke($Templates.java:248)
        at org.immutables.value.internal.$generator$.$AbstractGenerator.invoke($AbstractGenerator.java:57)
        at org.immutables.value.internal.$processor$.$Processor.process($Processor.java:63)
        at org.immutables.value.internal.$generator$.$AbstractGenerator.process($AbstractGenerator.java:87)
        at org.immutables.processor.ProxyProcessor.process(ProxyProcessor.java:72)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
        at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
        at com.sun.tools.javac.main.Main.compile(Main.java:523)
        at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
        at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
        at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:50)
        at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:36)
        at org.gradle.api.internal.tasks.compile.daemon.AbstractDaemonCompiler$CompilerCallable.call(AbstractDaemonCompiler.java:88)
        at org.gradle.api.internal.tasks.compile.daemon.AbstractDaemonCompiler$CompilerCallable.call(AbstractDaemonCompiler.java:76)
        at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:42)
        at org.gradle.workers.internal.WorkerDaemonServer.execute(WorkerDaemonServer.java:46)
        at org.gradle.workers.internal.WorkerDaemonServer.execute(WorkerDaemonServer.java:30)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:101)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:155)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:137)
        at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
        at java.lang.Thread.run(Thread.java:748)
1 error
```

The Validation API 2.0 introduced `TYPE_USE` as a Annotation target for `NotNull`, annotating the return type for the method (instead of the method itself), which `Parser` can not handle.

Changed files:
value-processor/src/org/immutables/value/processor/encode/Type.java, value-processor/test/org/immutables/value/processor/encode/TypeTest.java

diff --git a/value-processor/src/org/immutables/value/processor/encode/Type.java b/value-processor/src/org/immutables/value/processor/encode/Type.java
index 66bacb32..1d55d0a7 100644
--- a/value-processor/src/org/immutables/value/processor/encode/Type.java
+++ b/value-processor/src/org/immutables/value/processor/encode/Type.java
@@ -758,15 +758,25 @@ public interface Type {
           } else if (t.is("@")) {
             // just consume type annotation
             terms.poll();
-            named();
-            consumeAnnotationParameters();
-            consumeErraticTrailingComma();
+            consumeAnnotation();
             // and try again, yep, recursively...
             return type();
+          } else if (t.is("(")) {
+            return annotatedType();
           }
           throw new IllegalStateException("unexpected term '" + t + "'");
         }
 
+        Type annotatedType() {
+          terms.poll();
+          consumeAnnotation();
+          expect(terms.poll(), ":");
+          expect(terms.poll(), ":");
+          Type type = type();
+          expect(terms.poll(), ")");
+          return type;
+        }
+
         Wildcard wildcard() {
           expect(terms.poll(), "?");
 
@@ -822,14 +832,12 @@ public interface Type {
           List<String> segments = new ArrayList<>();
 
           for (;;) {
-            Term t = terms.poll();
-            if (t.isWordOrNumber()) {
-              segments.add(t.toString());
-            } else if (t.is("@")) {
+            if (terms.peek().isWordOrNumber()) {
+              segments.add(terms.poll().toString());
+            } else if (terms.peek().is("@")) {
+              terms.poll();
               // just consume type annotation
-              named();
-              consumeAnnotationParameters();
-              consumeErraticTrailingComma();
+              consumeAnnotation();
               continue;
             } else {
               break;
@@ -853,6 +861,12 @@ public interface Type {
           return forName(JOINER.join(segments));
         }
 
+        private void consumeAnnotation() {
+          named();
+          consumeAnnotationParameters();
+          consumeErraticTrailingComma();
+        }
+
         private void consumeAnnotationParameters() {
           consumeRecursiveUntil("(", ")");
         }
diff --git a/value-processor/test/org/immutables/value/processor/encode/TypeTest.java b/value-processor/test/org/immutables/value/processor/encode/TypeTest.java
index 4175441d..c2e7e1db 100644
--- a/value-processor/test/org/immutables/value/processor/encode/TypeTest.java
+++ b/value-processor/test/org/immutables/value/processor/encode/TypeTest.java
@@ -64,6 +64,7 @@ public class TypeTest {
     check(parser.parse("java.lang.@javax.validation.constraints.Size(max = 10)String")).is(Reference.STRING);
     check(parser.parse("java.lang.@javax.validation.constraints.Size(max = 10, @A(a=@B(b=1))) String")).is(Reference.STRING);
     check(parser.parse("@Ann(\\"b\\") int")).is(Primitive.INT);
+    check(parser.parse("(@javax.validation.constraints.NotNull :: java.lang.String)")).is(Reference.STRING);
   }
 
   @Test