Pass annotation processors to kotlinc

Enable the kotlin-annotation-processing plugin and pass annotation
processors to it.

Bug: 122251693
Test: m checkbuild
Test: TestKapt in kotlin_test.go
Change-Id: I841df454beaaa7edd263eea714ca0d958a03c9de
diff --git a/java/kotlin_test.go b/java/kotlin_test.go
index 08a3085..1069f42 100644
--- a/java/kotlin_test.go
+++ b/java/kotlin_test.go
@@ -15,6 +15,7 @@
 package java
 
 import (
+	"strconv"
 	"strings"
 	"testing"
 )
@@ -80,3 +81,109 @@
 			bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings())
 	}
 }
+
+func TestKapt(t *testing.T) {
+	ctx := testJava(t, `
+		java_library {
+			name: "foo",
+			srcs: ["a.java", "b.kt"],
+			annotation_processors: ["bar"],
+		}
+
+		java_library_host {
+			name: "bar",
+		}
+		`)
+
+	kapt := ctx.ModuleForTests("foo", "android_common").Rule("kapt")
+	kotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc")
+	javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
+
+	// Test that the kotlin and java sources are passed to kapt and kotlinc
+	if len(kapt.Inputs) != 2 || kapt.Inputs[0].String() != "a.java" || kapt.Inputs[1].String() != "b.kt" {
+		t.Errorf(`foo kapt inputs %v != ["a.java", "b.kt"]`, kapt.Inputs)
+	}
+	if len(kotlinc.Inputs) != 2 || kotlinc.Inputs[0].String() != "a.java" || kotlinc.Inputs[1].String() != "b.kt" {
+		t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, kotlinc.Inputs)
+	}
+
+	// Test that only the java sources are passed to javac
+	if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
+		t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
+	}
+
+	// Test that the kapt srcjar is a dependency of kotlinc and javac rules
+	if !inList(kapt.Output.String(), kotlinc.Implicits.Strings()) {
+		t.Errorf("expected %q in kotlinc implicits %v", kapt.Output.String(), kotlinc.Implicits.Strings())
+	}
+	if !inList(kapt.Output.String(), javac.Implicits.Strings()) {
+		t.Errorf("expected %q in javac implicits %v", kapt.Output.String(), javac.Implicits.Strings())
+	}
+
+	// Test that the kapt srcjar is extracted by the kotlinc and javac rules
+	if kotlinc.Args["srcJars"] != kapt.Output.String() {
+		t.Errorf("expected %q in kotlinc srcjars %v", kapt.Output.String(), kotlinc.Args["srcJars"])
+	}
+	if javac.Args["srcJars"] != kapt.Output.String() {
+		t.Errorf("expected %q in javac srcjars %v", kapt.Output.String(), kotlinc.Args["srcJars"])
+	}
+}
+
+func TestKaptEncodeFlags(t *testing.T) {
+	// Compares the kaptEncodeFlags against the results of the example implementation at
+	// https://kotlinlang.org/docs/reference/kapt.html#apjavac-options-encoding
+	tests := []struct {
+		in  [][2]string
+		out string
+	}{
+		{
+			// empty input
+			in:  [][2]string{},
+			out: "rO0ABXcEAAAAAA==",
+		},
+		{
+			// common input
+			in: [][2]string{
+				{"-source", "1.8"},
+				{"-target", "1.8"},
+			},
+			out: "rO0ABXcgAAAAAgAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjg=",
+		},
+		{
+			// input that serializes to a 255 byte block
+			in: [][2]string{
+				{"-source", "1.8"},
+				{"-target", "1.8"},
+				{"a", strings.Repeat("b", 218)},
+			},
+			out: "rO0ABXf/AAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA2mJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi",
+		},
+		{
+			// input that serializes to a 256 byte block
+			in: [][2]string{
+				{"-source", "1.8"},
+				{"-target", "1.8"},
+				{"a", strings.Repeat("b", 219)},
+			},
+			out: "rO0ABXoAAAEAAAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA22JiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYg==",
+		},
+		{
+			// input that serializes to a 257 byte block
+			in: [][2]string{
+				{"-source", "1.8"},
+				{"-target", "1.8"},
+				{"a", strings.Repeat("b", 220)},
+			},
+			out: "rO0ABXoAAAEBAAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA3GJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmI=",
+		},
+	}
+
+	for i, test := range tests {
+		t.Run(strconv.Itoa(i), func(t *testing.T) {
+			got := kaptEncodeFlags(test.in)
+			if got != test.out {
+				t.Errorf("\nwant %q\n got %q", test.out, got)
+			}
+		})
+	}
+}