make desugar resilient to unrelated lambdas being dumped while it runs
RELNOTES: None.

PiperOrigin-RevId: 178952440
diff --git a/src/test/java/com/google/devtools/build/android/desugar/BUILD b/src/test/java/com/google/devtools/build/android/desugar/BUILD
index c1e011a..69b30c2 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/BUILD
+++ b/src/test/java/com/google/devtools/build/android/desugar/BUILD
@@ -1913,6 +1913,24 @@
     ],
 )
 
+# Regression test for b/70415451
+genrule(
+    name = "desugar_guava_at_head",
+    srcs = [
+        "//third_party:guava-jars",
+        # Depend on Jacoco runtime in case testdata was built with coverage
+        # instrumentation
+        "//third_party/java/jacoco:blaze-agent",
+        "//tools/defaults:android_jar",
+    ],
+    outs = ["guava_at_head_desugared.jar"],
+    cmd = "$(location //src/tools/android/java/com/google/devtools/build/android/desugar:Desugar) " +
+          "-i $(location //third_party:guava-jars) -o $@ " +
+          "--bootclasspath_entry $(location //tools/defaults:android_jar)",
+    tags = ["no_windows"],
+    tools = ["//src/tools/android/java/com/google/devtools/build/android/desugar:Desugar"],
+)
+
 java_binary(
     name = "generate_lambda_with_constant_arguments",
     srcs = ["Bug62060793TestDataGenerator.java"],
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java b/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java
index beaeb03..1f240ef 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java
@@ -14,18 +14,19 @@
 package com.google.devtools.build.android.desugar;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.Iterables.getOnlyElement;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterators;
 import java.io.IOException;
 import java.lang.invoke.MethodHandle;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.Map;
-import java.util.function.Predicate;
-import java.util.stream.Stream;
+import java.util.Set;
 
 class LambdaClassMaker {
 
@@ -33,6 +34,7 @@
 
   private final Path rootDirectory;
   private final Map<Path, LambdaInfo> generatedClasses = new LinkedHashMap<>();
+  private final Set<Path> existingPaths = new HashSet<>();
 
   public LambdaClassMaker(Path rootDirectory) {
     checkArgument(
@@ -42,7 +44,9 @@
 
   public void generateLambdaClass(String invokerInternalName, LambdaInfo lambdaInfo,
       MethodHandle bootstrapMethod, ArrayList<Object> bsmArgs) throws IOException {
-    // Invoking the bootstrap method will dump the generated class
+    // Invoking the bootstrap method will dump the generated class.  Ignore any pre-existing
+    // matching files, which can come from desugar's implementation using classes being desugared.
+    existingPaths.addAll(findUnprocessed(invokerInternalName + "$$Lambda$"));
     try {
       bootstrapMethod.invokeWithArguments(bsmArgs);
     } catch (Throwable e) {
@@ -50,8 +54,9 @@
           + invokerInternalName + " using " + bootstrapMethod + " with arguments " + bsmArgs, e);
     }
 
-    Path generatedClassFile = findOnlyUnprocessed(invokerInternalName + "$$Lambda$");
+    Path generatedClassFile = getOnlyElement(findUnprocessed(invokerInternalName + "$$Lambda$"));
     generatedClasses.put(generatedClassFile, lambdaInfo);
+    existingPaths.add(generatedClassFile);
   }
 
   /**
@@ -64,7 +69,7 @@
     return result;
   }
 
-  private Path findOnlyUnprocessed(String pathPrefix) throws IOException {
+  private ImmutableList<Path> findUnprocessed(String pathPrefix) throws IOException {
     // pathPrefix is an internal class name prefix containing '/', but paths obtained on Windows
     // will not contain '/' and searches will fail.  So, construct an absolute path from the given
     // string and use its string representation to find the file we need regardless of host
@@ -72,18 +77,14 @@
     Path rootPathPrefix = rootDirectory.resolve(pathPrefix);
     final String rootPathPrefixStr = rootPathPrefix.toString();
 
-    // TODO(bazel-team): This could be much nicer with lambdas
-    try (Stream<Path> paths =
-        Files.list(rootPathPrefix.getParent())
-            .filter(
-                new Predicate<Path>() {
-                  @Override
-                  public boolean test(Path path) {
-                    return path.toString().startsWith(rootPathPrefixStr)
-                        && !generatedClasses.containsKey(path);
-                  }
-                })) {
-      return Iterators.getOnlyElement(paths.iterator());
+    if (!Files.exists(rootPathPrefix.getParent())) {
+      return ImmutableList.of();
     }
+    return Files.list(rootPathPrefix.getParent())
+        .filter(
+            path ->
+                path.toString().startsWith(rootPathPrefixStr)
+                    && !existingPaths.contains(path))
+        .collect(ImmutableList.toImmutableList());
   }
 }