VanillaJavaBuilder: don't crash formatting diagnostics without a source file

Fixes #2646

--
PiperOrigin-RevId: 149448578
MOS_MIGRATED_REVID=149448578
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/VanillaJavaBuilder.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/VanillaJavaBuilder.java
index df857a7..19f9ffc 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/VanillaJavaBuilder.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/VanillaJavaBuilder.java
@@ -198,11 +198,15 @@
     }
 
     for (Diagnostic<? extends JavaFileObject> diagnostic : diagnosticCollector.getDiagnostics()) {
-      StringBuilder message = new StringBuilder(diagnostic.getSource().getName());
-      if (diagnostic.getLineNumber() != -1) {
-        message.append(':').append(diagnostic.getLineNumber());
+      StringBuilder message = new StringBuilder();
+      if (diagnostic.getSource() != null) {
+        message.append(diagnostic.getSource().getName());
+        if (diagnostic.getLineNumber() != -1) {
+          message.append(':').append(diagnostic.getLineNumber());
+        }
+        message.append(": ");
       }
-      message.append(": ").append(diagnostic.getKind().toString().toLowerCase(ENGLISH));
+      message.append(diagnostic.getKind().toString().toLowerCase(ENGLISH));
       message.append(": ").append(diagnostic.getMessage(ENGLISH)).append(System.lineSeparator());
       output.write(message.toString());
     }
diff --git a/src/java_tools/buildjar/javatests/com/google/devtools/build/buildjar/VanillaJavaBuilderTest.java b/src/java_tools/buildjar/javatests/com/google/devtools/build/buildjar/VanillaJavaBuilderTest.java
index 6ae2f31..44e0ed7 100644
--- a/src/java_tools/buildjar/javatests/com/google/devtools/build/buildjar/VanillaJavaBuilderTest.java
+++ b/src/java_tools/buildjar/javatests/com/google/devtools/build/buildjar/VanillaJavaBuilderTest.java
@@ -145,4 +145,42 @@
     assertThat(result.ok()).isFalse();
     assertThat(Files.exists(output)).isFalse();
   }
+
+  @Test
+  public void diagnosticWithoutSource() throws Exception {
+    Path source = temporaryFolder.newFile("Test.java").toPath();
+    Path output = temporaryFolder.newFolder().toPath().resolve("out.jar");
+    Files.write(
+        source,
+        ImmutableList.of(
+            "import java.util.ArrayList;",
+            "import java.util.List;",
+            "abstract class A {",
+            "  abstract void f(List<String> xs);",
+            "  {",
+            "    f(new ArrayList<>());",
+            "  }",
+            "}"),
+        UTF_8);
+
+    VanillaJavaBuilderResult result =
+        run(
+            ImmutableList.of(
+                "--javacopts",
+                "-source",
+                "7",
+                "-Xlint:none",
+                "--sources",
+                source.toString(),
+                "--output",
+                output.toString(),
+                "--bootclasspath",
+                Paths.get(System.getProperty("java.home")).resolve("lib/rt.jar").toString(),
+                "--classdir",
+                temporaryFolder.newFolder().toString()));
+
+    assertThat(result.output()).contains("note: Some messages have been simplified");
+    assertThat(result.ok()).isFalse();
+    assertThat(Files.exists(output)).isFalse();
+  }
 }