Fix youtube tests

- Raise proper error where trying to ensure a synthetic
which is already present.
- Fix Youtube tests not to have desugared library on
library path unlike AppReduce.

Bug: 201737004
Change-Id: I7ec37c394ca6dbfd69831558eeb27e83cee10fce
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
index f9ca2e9..8f658a3 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
@@ -453,10 +453,12 @@
                   assert method.isClasspathMethod();
                   return appView
                       .getSyntheticItems()
-                      .createFixedClasspathClass(
+                      .ensureFixedClasspathClass(
                           SyntheticKind.INIT_TYPE_ARGUMENT,
                           method.asClasspathMethod().getHolder(),
-                          dexItemFactory)
+                          appView,
+                          ignored -> {},
+                          ignored -> {})
                       .getType();
                 }
               });
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index e407c3a..caf0f42 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -492,7 +492,9 @@
       // Recheck if it is present now the lock is held.
       dexClass = appView.definitionFor(type);
       if (dexClass != null) {
-        assert dexClass.isProgramClass();
+        if (!dexClass.isProgramClass()) {
+          errorOnInvalidSyntheticEnsure(dexClass, "program", appView);
+        }
         return dexClass.asProgramClass();
       }
       assert !isSyntheticClass(type);
@@ -625,17 +627,57 @@
     return new ProgramMethod(clazz, methodDefinition);
   }
 
-  public DexClasspathClass createFixedClasspathClass(
-      SyntheticKind kind, DexClasspathClass context, DexItemFactory factory) {
-    // Obtain the outer synthesizing context in the case the context itself is synthetic.
-    // This is to ensure a flat input-type -> synthetic-item mapping.
-    SynthesizingContext outerContext = SynthesizingContext.fromNonSyntheticInputContext(context);
-    DexType type = SyntheticNaming.createFixedType(kind, outerContext, factory);
-    SyntheticClasspathClassBuilder classBuilder =
-        new SyntheticClasspathClassBuilder(type, kind, outerContext, factory);
-    DexClasspathClass clazz = classBuilder.build();
-    addPendingDefinition(new SyntheticClasspathClassDefinition(kind, outerContext, clazz));
-    return clazz;
+  private void errorOnInvalidSyntheticEnsure(DexClass dexClass, String kind, AppView<?> appView) {
+    String classKind =
+        dexClass.isProgramClass()
+            ? "program"
+            : dexClass.isClasspathClass() ? "classpath" : "library";
+    throw appView
+        .reporter()
+        .fatalError(
+            "Cannot ensure "
+                + dexClass.type
+                + " as a synthetic "
+                + kind
+                + " class, because it is already a "
+                + classKind
+                + " class.");
+  }
+
+  private DexClasspathClass internalEnsureDexClasspathClass(
+      SyntheticKind kind,
+      Consumer<SyntheticClasspathClassBuilder> classConsumer,
+      Consumer<DexClasspathClass> onCreationConsumer,
+      SynthesizingContext outerContext,
+      DexType type,
+      AppView<?> appView) {
+    synchronized (type) {
+      DexClass clazz = appView.definitionFor(type);
+      if (clazz != null) {
+        if (!clazz.isClasspathClass()) {
+          errorOnInvalidSyntheticEnsure(clazz, "classpath", appView);
+        }
+        return clazz.asClasspathClass();
+      }
+      SyntheticClasspathClassBuilder classBuilder =
+          new SyntheticClasspathClassBuilder(type, kind, outerContext, appView.dexItemFactory());
+      classConsumer.accept(classBuilder);
+      DexClasspathClass definition = classBuilder.build();
+      addPendingDefinition(new SyntheticClasspathClassDefinition(kind, outerContext, definition));
+      onCreationConsumer.accept(definition);
+      return definition;
+    }
+  }
+
+  public DexClasspathClass ensureFixedClasspathClassFromType(
+      SyntheticKind kind,
+      DexType contextType,
+      AppView<?> appView,
+      Consumer<SyntheticClasspathClassBuilder> classConsumer) {
+    SynthesizingContext outerContext = SynthesizingContext.fromType(contextType);
+    DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
+    return internalEnsureDexClasspathClass(
+        kind, classConsumer, ignored -> {}, outerContext, type, appView);
   }
 
   public DexClasspathClass ensureFixedClasspathClass(
@@ -644,29 +686,12 @@
       AppView<?> appView,
       Consumer<SyntheticClasspathClassBuilder> classConsumer,
       Consumer<DexClasspathClass> onCreationConsumer) {
+    // Obtain the outer synthesizing context in the case the context itself is synthetic.
+    // This is to ensure a flat input-type -> synthetic-item mapping.
     SynthesizingContext outerContext = SynthesizingContext.fromNonSyntheticInputContext(context);
     DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
-    DexClass dexClass = appView.appInfo().definitionForWithoutExistenceAssert(type);
-    if (dexClass != null) {
-      assert dexClass.isClasspathClass();
-      return dexClass.asClasspathClass();
-    }
-    synchronized (context) {
-      dexClass = appView.appInfo().definitionForWithoutExistenceAssert(type);
-      if (dexClass != null) {
-        assert dexClass.isClasspathClass();
-        return dexClass.asClasspathClass();
-      }
-      // Obtain the outer synthesizing context in the case the context itself is synthetic.
-      // This is to ensure a flat input-type -> synthetic-item mapping.
-      SyntheticClasspathClassBuilder classBuilder =
-          new SyntheticClasspathClassBuilder(type, kind, outerContext, appView.dexItemFactory());
-      classConsumer.accept(classBuilder);
-      DexClasspathClass clazz = classBuilder.build();
-      addPendingDefinition(new SyntheticClasspathClassDefinition(kind, outerContext, clazz));
-      onCreationConsumer.accept(clazz);
-      return clazz;
-    }
+    return internalEnsureDexClasspathClass(
+        kind, classConsumer, onCreationConsumer, outerContext, type, appView);
   }
 
   public DexClassAndMethod ensureFixedClasspathClassMethod(
@@ -737,28 +762,6 @@
     return internalEnsureDexProgramClass(kind, fn, onCreationConsumer, outerContext, type, appView);
   }
 
-  public DexClasspathClass ensureFixedClasspathClassFromType(
-      SyntheticKind kind,
-      DexType contextType,
-      AppView<?> appView,
-      Consumer<SyntheticClasspathClassBuilder> fn) {
-    SynthesizingContext outerContext = SynthesizingContext.fromType(contextType);
-    DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
-    synchronized (contextType) {
-      DexClass clazz = appView.definitionFor(type);
-      if (clazz != null) {
-        assert clazz.isClasspathClass();
-        return clazz.asClasspathClass();
-      }
-      SyntheticClasspathClassBuilder classBuilder =
-          new SyntheticClasspathClassBuilder(type, kind, outerContext, appView.dexItemFactory());
-      fn.accept(classBuilder);
-      DexClasspathClass definition = classBuilder.build();
-      addPendingDefinition(new SyntheticClasspathClassDefinition(kind, outerContext, definition));
-      return definition;
-    }
-  }
-
   /** Create a single synthetic method item. */
   public ProgramMethod createMethod(
       SyntheticKind kind,
diff --git a/src/test/java/com/android/tools/r8/internal/YouTubeCompilationTestBase.java b/src/test/java/com/android/tools/r8/internal/YouTubeCompilationTestBase.java
index aea7348..f280e80 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeCompilationTestBase.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeCompilationTestBase.java
@@ -5,14 +5,19 @@
 
 import static org.junit.Assert.assertTrue;
 
+import com.android.tools.r8.ByteDataView;
+import com.android.tools.r8.ClassFileConsumer.ArchiveConsumer;
 import com.android.tools.r8.R8TestCompileResult;
+import com.android.tools.r8.TestBase;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.ZipUtils;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.analysis.ProtoApplicationStats;
 import com.google.common.collect.ImmutableList;
+import com.google.common.io.ByteStreams;
 import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -84,15 +89,33 @@
     return builder.build();
   }
 
-  protected List<Path> getLibraryFiles() {
+  protected Path getLibraryFile() {
     Path filtered =
         Paths.get(base).resolve("legacy_YouTubeRelease_combined_library_jars_filtered.jar");
     if (filtered.toFile().exists()) {
-      return ImmutableList.of(filtered);
+      return filtered;
     }
     Path unfiltered = Paths.get(base, "legacy_YouTubeRelease_combined_library_jars.jar");
     assertTrue(unfiltered.toFile().exists());
-    return ImmutableList.of(unfiltered);
+    return unfiltered;
+  }
+
+  Path getLibraryFileWithoutDesugaredLibrary() throws IOException {
+    Path libraryFile = getLibraryFile();
+    Path filteredLibraryFile =
+        Paths.get(libraryFile.toString().replace(".jar", "desugared_lib_filtered.jar"));
+    ArchiveConsumer consumer = new ArchiveConsumer(filteredLibraryFile);
+    ZipUtils.iter(
+        libraryFile,
+        (entry, inputStream) -> {
+          String entryString = entry.toString();
+          if (entryString.endsWith(".class") && !entryString.startsWith("j$")) {
+            byte[] bytes = ByteStreams.toByteArray(inputStream);
+            consumer.accept(ByteDataView.of(bytes), TestBase.extractClassDescriptor(bytes), null);
+          }
+        });
+    consumer.finished(null);
+    return filteredLibraryFile;
   }
 
   protected List<Path> getMainDexRuleFiles() {
diff --git a/src/test/java/com/android/tools/r8/internal/YouTubeV1533TreeShakeJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/YouTubeV1533TreeShakeJarVerificationTest.java
index 24ae3c1..9ae3939 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeV1533TreeShakeJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeV1533TreeShakeJarVerificationTest.java
@@ -12,6 +12,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.utils.AndroidApiLevel;
+import com.google.common.collect.ImmutableList;
 import java.nio.file.Paths;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -43,7 +44,7 @@
     LibrarySanitizer librarySanitizer =
         new LibrarySanitizer(temp)
             .addProgramFiles(getProgramFiles())
-            .addLibraryFiles(getLibraryFiles())
+            .addLibraryFiles(ImmutableList.of(getLibraryFile()))
             .sanitize()
             .assertSanitizedProguardConfigurationIsEmpty();
 
diff --git a/src/test/java/com/android/tools/r8/internal/YouTubeV1612Test.java b/src/test/java/com/android/tools/r8/internal/YouTubeV1612Test.java
index 830d6fc..50442c9 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeV1612Test.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeV1612Test.java
@@ -115,7 +115,7 @@
       throws IOException, CompilationFailedException {
     return testForR8(parameters.getBackend())
         .addProgramFiles(getProgramFiles())
-        .addLibraryFiles(getLibraryFiles())
+        .addLibraryFiles(getLibraryFileWithoutDesugaredLibrary())
         .addKeepRuleFiles(getKeepRuleFiles())
         .addDontWarn("android.app.Activity$TranslucentConversionListener")
         .allowDiagnosticMessages()
diff --git a/src/test/java/com/android/tools/r8/internal/YouTubeV1620Test.java b/src/test/java/com/android/tools/r8/internal/YouTubeV1620Test.java
index 0b76040..0c3abdd 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeV1620Test.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeV1620Test.java
@@ -115,7 +115,7 @@
       throws IOException, CompilationFailedException {
     return testForR8(parameters.getBackend())
         .addProgramFiles(getProgramFiles())
-        .addLibraryFiles(getLibraryFiles())
+        .addLibraryFiles(getLibraryFileWithoutDesugaredLibrary())
         .addKeepRuleFiles(getKeepRuleFiles())
         .addDontWarn("android.app.Activity$TranslucentConversionListener")
         .allowDiagnosticMessages()