@Test
  public void findDepsFromParamsSetsUpDepsForFlavoredTarget() {
    // Create the thrift target and implicit dep.
    BuildTarget thriftTarget = BuildTargetFactory.newInstance("//bar:thrift_compiler");
    FakeBuildRule implicitDep =
        createFakeBuildRule("//foo:implicit_dep", new SourcePathResolver(new BuildRuleResolver()));

    // Setup the default values returned by the language specific enhancer.
    String language = "fake";
    Flavor flavor = ImmutableFlavor.of("fake");
    ImmutableSet<String> options = ImmutableSet.of();
    ImmutableSet<BuildTarget> implicitDeps = ImmutableSet.of(implicitDep.getBuildTarget());
    BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift");
    BuildTarget flavoredTarget =
        BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor);

    // Setup an empty thrift buck config and description.
    FakeBuckConfig buckConfig =
        new FakeBuckConfig(
            ImmutableMap.of("thrift", ImmutableMap.of("compiler", thriftTarget.toString())));
    ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig);
    ThriftLanguageSpecificEnhancer enhancer =
        new FakeThriftLanguageSpecificEnhancer(language, flavor, implicitDeps, options);
    ThriftLibraryDescription desc =
        new ThriftLibraryDescription(thriftBuckConfig, ImmutableList.of(enhancer));

    ThriftConstructorArg constructorArg = desc.createUnpopulatedConstructorArg();
    constructorArg.deps = Optional.of(ImmutableSortedSet.<BuildTarget>of());

    // Now call the find deps methods and verify it returns nothing.
    Iterable<BuildTarget> results =
        desc.findDepsForTargetFromConstructorArgs(flavoredTarget, constructorArg);
    assertEquals(
        ImmutableSet.<BuildTarget>builder()
            .add(unflavoredTarget)
            .add(thriftTarget)
            .addAll(implicitDeps)
            .build(),
        ImmutableSet.copyOf(results));
  }
  @Override
  public <A extends Arg> BuildRule createBuildRule(
      TargetGraph targetGraph,
      BuildRuleParams originalBuildRuleParams,
      BuildRuleResolver resolver,
      A args) {

    UnflavoredBuildTarget originalBuildTarget =
        originalBuildRuleParams.getBuildTarget().checkUnflavored();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    ImmutableList.Builder<BuildRule> aarExtraDepsBuilder =
        ImmutableList.<BuildRule>builder().addAll(originalBuildRuleParams.getExtraDeps().get());

    /* android_manifest */
    AndroidManifestDescription.Arg androidManifestArgs =
        androidManifestDescription.createUnpopulatedConstructorArg();
    androidManifestArgs.skeleton = args.manifestSkeleton;
    androidManifestArgs.deps = args.deps;

    BuildRuleParams androidManifestParams =
        originalBuildRuleParams.copyWithChanges(
            BuildTargets.createFlavoredBuildTarget(
                originalBuildTarget, AAR_ANDROID_MANIFEST_FLAVOR),
            originalBuildRuleParams.getDeclaredDeps(),
            originalBuildRuleParams.getExtraDeps());

    AndroidManifest manifest =
        androidManifestDescription.createBuildRule(
            targetGraph, androidManifestParams, resolver, androidManifestArgs);
    aarExtraDepsBuilder.add(resolver.addToIndex(manifest));

    /* assemble dirs */
    AndroidPackageableCollector collector =
        new AndroidPackageableCollector(
            originalBuildRuleParams.getBuildTarget(),
            /* buildTargetsToExcludeFromDex */ ImmutableSet.<BuildTarget>of(),
            /* resourcesToExclude */ ImmutableSet.<BuildTarget>of());
    collector.addPackageables(
        AndroidPackageableCollector.getPackageableRules(originalBuildRuleParams.getDeps()));
    AndroidPackageableCollection packageableCollection = collector.build();

    ImmutableSortedSet<BuildRule> androidResourceDeclaredDeps =
        AndroidResourceHelper.androidResOnly(originalBuildRuleParams.getDeclaredDeps().get());
    ImmutableSortedSet<BuildRule> androidResourceExtraDeps =
        AndroidResourceHelper.androidResOnly(originalBuildRuleParams.getExtraDeps().get());

    BuildRuleParams assembleAssetsParams =
        originalBuildRuleParams.copyWithChanges(
            BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_ASSEMBLE_ASSETS_FLAVOR),
            Suppliers.ofInstance(androidResourceDeclaredDeps),
            Suppliers.ofInstance(androidResourceExtraDeps));
    ImmutableCollection<SourcePath> assetsDirectories =
        packageableCollection.getAssetsDirectories();
    AssembleDirectories assembleAssetsDirectories =
        new AssembleDirectories(assembleAssetsParams, pathResolver, assetsDirectories);
    aarExtraDepsBuilder.add(resolver.addToIndex(assembleAssetsDirectories));

    BuildRuleParams assembleResourceParams =
        originalBuildRuleParams.copyWithChanges(
            BuildTargets.createFlavoredBuildTarget(
                originalBuildTarget, AAR_ASSEMBLE_RESOURCE_FLAVOR),
            Suppliers.ofInstance(androidResourceDeclaredDeps),
            Suppliers.ofInstance(androidResourceExtraDeps));
    ImmutableCollection<SourcePath> resDirectories =
        packageableCollection.getResourceDetails().getResourceDirectories();
    MergeAndroidResourceSources assembleResourceDirectories =
        new MergeAndroidResourceSources(assembleResourceParams, pathResolver, resDirectories);
    aarExtraDepsBuilder.add(resolver.addToIndex(assembleResourceDirectories));

    /* android_resource */
    BuildRuleParams androidResourceParams =
        originalBuildRuleParams.copyWithChanges(
            BuildTargets.createFlavoredBuildTarget(
                originalBuildTarget, AAR_ANDROID_RESOURCE_FLAVOR),
            Suppliers.ofInstance(
                ImmutableSortedSet.<BuildRule>of(
                    manifest, assembleAssetsDirectories, assembleResourceDirectories)),
            Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of()));

    AndroidResource androidResource =
        new AndroidResource(
            androidResourceParams,
            pathResolver,
            /* deps */ ImmutableSortedSet.<BuildRule>naturalOrder()
                .add(assembleAssetsDirectories)
                .add(assembleResourceDirectories)
                .addAll(originalBuildRuleParams.getDeclaredDeps().get())
                .build(),
            new BuildTargetSourcePath(assembleResourceDirectories.getBuildTarget()),
            /* resSrcs */ ImmutableSortedSet.<SourcePath>of(),
            Optional.<SourcePath>absent(),
            /* rDotJavaPackage */ null,
            new BuildTargetSourcePath(assembleAssetsDirectories.getBuildTarget()),
            /* assetsSrcs */ ImmutableSortedSet.<SourcePath>of(),
            Optional.<SourcePath>absent(),
            new BuildTargetSourcePath(manifest.getBuildTarget()),
            /* hasWhitelistedStrings */ false);
    aarExtraDepsBuilder.add(resolver.addToIndex(androidResource));

    /* native_libraries */
    AndroidNativeLibsPackageableGraphEnhancer packageableGraphEnhancer =
        new AndroidNativeLibsPackageableGraphEnhancer(
            resolver,
            originalBuildRuleParams,
            nativePlatforms,
            ImmutableSet.<NdkCxxPlatforms.TargetCpuType>of());
    Optional<CopyNativeLibraries> nativeLibrariesOptional =
        packageableGraphEnhancer.getCopyNativeLibraries(targetGraph, packageableCollection);
    if (nativeLibrariesOptional.isPresent()) {
      aarExtraDepsBuilder.add(resolver.addToIndex(nativeLibrariesOptional.get()));
    }

    Optional<Path> assembledNativeLibsDir =
        nativeLibrariesOptional.transform(
            new Function<CopyNativeLibraries, Path>() {
              @Override
              public Path apply(CopyNativeLibraries input) {
                return input.getPathToNativeLibsDir();
              }
            });
    BuildRuleParams androidAarParams =
        originalBuildRuleParams.copyWithExtraDeps(
            Suppliers.ofInstance(ImmutableSortedSet.copyOf(aarExtraDepsBuilder.build())));
    return new AndroidAar(
        androidAarParams,
        pathResolver,
        manifest,
        androidResource,
        assembleResourceDirectories.getPathToOutput(),
        assembleAssetsDirectories.getPathToOutput(),
        assembledNativeLibsDir,
        packageableCollection.getNativeLibAssetsDirectories());
  }
  @Test
  public void createThriftCompilerBuildRulesHasCorrectDeps() throws IOException {
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem();

    String language = "fake";
    Flavor flavor = ImmutableFlavor.of("fake");
    ImmutableSet<String> options = ImmutableSet.of();

    // Setup the default values returned by the language specific enhancer.
    BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift");
    BuildRuleParams unflavoredParams =
        new FakeBuildRuleParamsBuilder(BuildTarget.builder(unflavoredTarget).build())
            .setProjectFilesystem(filesystem)
            .build();

    // Setup a thrift source file generated by a genrule.
    BuildTarget flavoredTarget =
        BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor);
    BuildRuleParams flavoredParams =
        new FakeBuildRuleParamsBuilder(flavoredTarget).setProjectFilesystem(filesystem).build();

    // Create a path for the thrift compiler.
    Path thriftPath = Paths.get("thrift_path");
    filesystem.touch(thriftPath);

    // Setup an thrift buck config, with the path to the thrift compiler set.
    FakeBuckConfig buckConfig =
        new FakeBuckConfig(
            ImmutableMap.of("thrift", ImmutableMap.of("compiler", thriftPath.toString())),
            filesystem);
    ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig);
    ThriftLibraryDescription desc =
        new ThriftLibraryDescription(
            thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of());

    // Setup a simple thrift source.
    String sourceName = "test.thrift";
    SourcePath sourcePath = new TestSourcePath(sourceName);

    // Generate these rules using no deps.
    ImmutableMap<String, ThriftCompiler> rules =
        desc.createThriftCompilerBuildRules(
            flavoredParams,
            resolver,
            ThriftLibraryDescription.CompilerType.THRIFT,
            ImmutableList.<String>of(),
            language,
            options,
            ImmutableMap.of(sourceName, sourcePath),
            ImmutableSortedSet.<ThriftLibrary>of());

    // Now verify that the generated rule had no associated deps.
    assertSame(rules.size(), 1);
    ThriftCompiler rule = rules.get(sourceName);
    assertNotNull(rule);
    assertEquals(ImmutableSortedSet.<BuildRule>of(), rule.getDeps());

    // Lets do this again, but pass in a ThriftLibrary deps, wrapping some includes we need.
    Path includeRoot = desc.getIncludeRoot(unflavoredTarget);
    HeaderSymlinkTree thriftIncludeSymlinkTree =
        createFakeSymlinkTree(
            desc.createThriftIncludeSymlinkTreeTarget(unflavoredTarget), pathResolver, includeRoot);
    ThriftLibrary lib =
        new ThriftLibrary(
            unflavoredParams,
            pathResolver,
            ImmutableSortedSet.<ThriftLibrary>of(),
            thriftIncludeSymlinkTree,
            ImmutableMap.<Path, SourcePath>of());

    // Generate these rules using no deps.
    rules =
        desc.createThriftCompilerBuildRules(
            flavoredParams,
            resolver,
            ThriftLibraryDescription.CompilerType.THRIFT,
            ImmutableList.<String>of(),
            language,
            options,
            ImmutableMap.of(sourceName, sourcePath),
            ImmutableSortedSet.of(lib));

    // Now verify that the generated rule has all the deps from the passed in thrift library.
    assertSame(rules.size(), 1);
    rule = rules.get(sourceName);
    assertNotNull(rule);
    assertEquals(ImmutableSortedSet.<BuildRule>of(thriftIncludeSymlinkTree), rule.getDeps());

    // Setup a simple genrule that creates the thrift source and verify its dep is propagated.
    Genrule genrule =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:genrule"))
                .setOut(sourceName)
                .build(resolver);
    SourcePath ruleSourcePath = new BuildTargetSourcePath(genrule.getBuildTarget());

    // Generate these rules using no deps and the genrule generated source.
    rules =
        desc.createThriftCompilerBuildRules(
            flavoredParams,
            resolver,
            ThriftLibraryDescription.CompilerType.THRIFT,
            ImmutableList.<String>of(),
            language,
            options,
            ImmutableMap.of(sourceName, ruleSourcePath),
            ImmutableSortedSet.<ThriftLibrary>of());

    // Now verify that the generated rule had no associated deps.
    assertSame(rules.size(), 1);
    rule = rules.get(sourceName);
    assertNotNull(rule);
    assertEquals(ImmutableSortedSet.<BuildRule>of(genrule), rule.getDeps());

    // Create a build rule that represents the thrift rule.
    FakeBuildRule thriftRule = createFakeBuildRule("//thrift:target", pathResolver);
    resolver.addToIndex(thriftRule);
    filesystem.mkdirs(thriftRule.getBuildTarget().getBasePath());
    filesystem.touch(thriftRule.getBuildTarget().getBasePath().resolve("BUCK"));

    // Setup an empty thrift buck config, and set compiler target.
    buckConfig =
        new FakeBuckConfig(
            ImmutableMap.of(
                "thrift", ImmutableMap.of("compiler", thriftRule.getBuildTarget().toString())),
            filesystem);
    thriftBuckConfig = new ThriftBuckConfig(buckConfig);
    desc =
        new ThriftLibraryDescription(
            thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of());

    // Generate these rules using no deps with a compiler target.
    rules =
        desc.createThriftCompilerBuildRules(
            flavoredParams,
            resolver,
            ThriftLibraryDescription.CompilerType.THRIFT,
            ImmutableList.<String>of(),
            language,
            options,
            ImmutableMap.of(sourceName, sourcePath),
            ImmutableSortedSet.<ThriftLibrary>of());

    // Now verify that the generated rule only has deps from the compiler target.
    assertSame(rules.size(), 1);
    rule = rules.get(sourceName);
    assertNotNull(rule);
    assertEquals(ImmutableSortedSet.<BuildRule>of(thriftRule), rule.getDeps());
  }
  @Test
  public void createBuildRuleWithFlavoredTargetCallsEnhancerCorrectly() throws IOException {
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem();

    // Setup the default values returned by the language specific enhancer.
    String language = "fake";
    Flavor flavor = ImmutableFlavor.of("fake");
    final BuildRule implicitDep = createFakeBuildRule("//implicit:dep", pathResolver);
    resolver.addToIndex(implicitDep);
    filesystem.mkdirs(implicitDep.getBuildTarget().getBasePath());
    filesystem.touch(implicitDep.getBuildTarget().getBasePath().resolve("BUCK"));
    ImmutableSet<BuildTarget> implicitDeps = ImmutableSet.of(implicitDep.getBuildTarget());
    ImmutableSet<String> options = ImmutableSet.of();

    // Create the build targets and params.
    BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift");
    BuildRuleParams unflavoredParams =
        new FakeBuildRuleParamsBuilder(unflavoredTarget).setProjectFilesystem(filesystem).build();
    BuildTarget flavoredTarget =
        BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor);
    BuildRuleParams flavoredParams =
        new FakeBuildRuleParamsBuilder(flavoredTarget).setProjectFilesystem(filesystem).build();

    // Setup a thrift source file generated by a genrule.
    final String thriftSourceName1 = "foo.thrift";
    BuildTarget genruleTarget = BuildTargetFactory.newInstance("//:genrule");
    final Genrule genrule =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(genruleTarget)
                .setOut(thriftSourceName1)
                .build(resolver);
    SourcePath thriftSource1 = new BuildTargetSourcePath(genrule.getBuildTarget());
    final ImmutableList<String> thriftServices1 = ImmutableList.of();

    // Setup a normal thrift source file.
    final String thriftSourceName2 = "bar.thrift";
    SourcePath thriftSource2 = new TestSourcePath(thriftSourceName2);
    final ImmutableList<String> thriftServices2 = ImmutableList.of();

    // Create a build rule that represents the thrift rule.
    final FakeBuildRule thriftRule = createFakeBuildRule("//thrift:target", pathResolver);
    resolver.addToIndex(thriftRule);
    filesystem.mkdirs(thriftRule.getBuildTarget().getBasePath());
    filesystem.touch(thriftRule.getBuildTarget().getBasePath().resolve("BUCK"));

    // Setup a simple description with an empty config.
    FakeBuckConfig buckConfig =
        new FakeBuckConfig(
            ImmutableMap.of(
                "thrift", ImmutableMap.of("compiler", thriftRule.getBuildTarget().toString())));
    ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig);
    ThriftLibraryDescription desc =
        new ThriftLibraryDescription(
            thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of());

    // Setup the include rules.
    final BuildRule thriftIncludeSymlinkTree =
        createFakeBuildRule(
            desc.createThriftIncludeSymlinkTreeTarget(unflavoredTarget), pathResolver);

    // Setup our language enhancer
    FakeThriftLanguageSpecificEnhancer enhancer =
        new FakeThriftLanguageSpecificEnhancer(language, flavor, implicitDeps, options) {
          @Override
          public void checkCreateBuildRuleInputs(
              ImmutableMap<String, ThriftSource> sources, ImmutableSortedSet<BuildRule> deps) {

            // Verify both thrift sources are present in the list.
            assertEquals(2, sources.size());
            ThriftSource src1 = sources.get(thriftSourceName1);
            assertNotNull(src1);
            ThriftSource src2 = sources.get(thriftSourceName2);
            assertNotNull(src2);

            // Verify the services are listed correctly for both sources.
            assertEquals(thriftServices1, src1.getServices());
            assertEquals(thriftServices2, src2.getServices());

            // Verify dependencies are setup correctly.
            assertEquals(
                ImmutableSortedSet.of(genrule, thriftRule, thriftIncludeSymlinkTree),
                src1.getCompileRule().getDeps());
            assertEquals(
                ImmutableSortedSet.of(genrule, thriftRule, thriftIncludeSymlinkTree),
                src2.getCompileRule().getDeps());

            // Verify the language specific implicit rules are added correctly.
            assertEquals(
                ImmutableSortedSet.<BuildRule>naturalOrder().add(implicitDep).build(), deps);
          }
        };

    // Recreate the description with the enhancer we setup above.
    desc =
        new ThriftLibraryDescription(
            thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of(enhancer));

    // Setup the internal structure indicating that the thrift target was set in the
    // buck config.
    // desc.setCompilerTarget(thriftRule.getBuildTarget());

    // Setup the implicit deps for the flavored build target.
    // desc.setImplicitDeps(flavoredTarget, ImmutableList.of(implicitDep.getBuildTarget()));

    // Build up the constructor arg.
    ThriftConstructorArg arg = desc.createUnpopulatedConstructorArg();
    arg.name = "thrift";
    arg.srcs =
        ImmutableMap.of(
            thriftSource1, thriftServices1,
            thriftSource2, thriftServices2);
    arg.deps = Optional.absent();
    arg.flags = Optional.absent();

    // Setup the unflavored target, which should just produce a ThriftInclude, SymlinkTree, and
    // ThriftLibrary rule.
    BuildRule rule = desc.createBuildRule(TargetGraph.EMPTY, unflavoredParams, resolver, arg);
    resolver.addToIndex(rule);

    // Now attempt to create the flavored thrift library.
    desc.createBuildRule(TargetGraph.EMPTY, flavoredParams, resolver, arg);
  }
  /**
   * Creates a rooted DAG of build rules:
   *
   * <ul>
   *   <li>{@code unzip_aar} depends on the deps specified to the original {@code android_aar}
   *   <li>{@code prebuilt_jar} depends on {@code unzip_aar}
   *   <li>{@code android_resource} depends on {@code unzip_aar}
   *   <li>{@code android_library} depends on {@code android_resource}, {@code prebuilt_jar}, and
   *       {@code unzip_aar}
   * </ul>
   *
   * Therefore, the return value is an {link AndroidLibrary} with no {@code srcs}.
   */
  static BuildRule enhance(
      BuildRuleParams originalBuildRuleParams, SourcePath aarFile, BuildRuleResolver ruleResolver) {
    // unzip_aar
    BuildTarget originalBuildTarget = originalBuildRuleParams.getBuildTarget();
    BuildRuleParams unzipAarParams =
        originalBuildRuleParams.copyWithChanges(
            UNZIP_AAR_TYPE,
            BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_UNZIP_FLAVOR),
            originalBuildRuleParams.getDeclaredDeps(),
            originalBuildRuleParams.getExtraDeps());
    UnzipAar unzipAar = new UnzipAar(unzipAarParams, aarFile);
    ruleResolver.addToIndex(unzipAar);

    // unzip_aar#aar_classes_jar
    BuildRuleParams classesJarParams =
        originalBuildRuleParams.copyWithChanges(
            OutputOnlyBuildRule.TYPE,
            BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_CLASSES_JAR_FLAVOR),
            /* declaredDeps */ ImmutableSortedSet.<BuildRule>of(unzipAar),
            /* extraDeps */ ImmutableSortedSet.<BuildRule>of());
    OutputOnlyBuildRule classesJar =
        new OutputOnlyBuildRule(classesJarParams, unzipAar.getPathToClassesJar());
    ruleResolver.addToIndex(classesJar);

    // prebuilt_jar
    BuildRuleParams prebuiltJarParams =
        originalBuildRuleParams.copyWithChanges(
            PrebuiltJarDescription.TYPE,
            BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_PREBUILT_JAR_FLAVOR),
            /* declaredDeps */ ImmutableSortedSet.<BuildRule>of(unzipAar),
            /* extraDeps */ ImmutableSortedSet.<BuildRule>of());
    PrebuiltJar prebuiltJar =
        new PrebuiltJar(
            /* params */ prebuiltJarParams,
            new BuildRuleSourcePath(classesJar),
            /* sourceJar */ Optional.<SourcePath>absent(),
            /* gwtJar */ Optional.<SourcePath>absent(),
            /* javadocUrl */ Optional.<String>absent());
    ruleResolver.addToIndex(prebuiltJar);

    // unzip_aar#aar_manifest
    BuildRuleParams manifestParams =
        originalBuildRuleParams.copyWithChanges(
            OutputOnlyBuildRule.TYPE,
            BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_MANIFEST),
            /* declaredDeps */ ImmutableSortedSet.<BuildRule>of(unzipAar),
            /* extraDeps */ ImmutableSortedSet.<BuildRule>of());
    OutputOnlyBuildRule manifest =
        new OutputOnlyBuildRule(manifestParams, unzipAar.getAndroidManifest());
    ruleResolver.addToIndex(manifest);

    // android_resource
    BuildRuleParams androidResourceParams =
        originalBuildRuleParams.copyWithChanges(
            AndroidResourceDescription.TYPE,
            BuildTargets.createFlavoredBuildTarget(
                originalBuildTarget, AAR_ANDROID_RESOURCE_FLAVOR),
            /* declaredDeps */ ImmutableSortedSet.<BuildRule>of(manifest),
            /* extraDeps */ ImmutableSortedSet.<BuildRule>of());

    // Because all resources and assets are generated files, we specify them as empty collections.
    ImmutableSortedSet<Path> resSrcs = ImmutableSortedSet.of();
    ImmutableSortedSet<Path> assetsSrcs = ImmutableSortedSet.of();

    AndroidResource androidResource =
        new AndroidResource(
            androidResourceParams,
            /* deps */ ImmutableSortedSet.<BuildRule>of(unzipAar),
            unzipAar.getResDirectory(),
            resSrcs,
            /* rDotJavaPackage */ null,
            /* assets */ unzipAar.getAssetsDirectory(),
            assetsSrcs,
            new BuildRuleSourcePath(manifest),
            /* hasWhitelistedStrings */ false);
    ruleResolver.addToIndex(androidResource);

    // android_library
    BuildRuleParams androidLibraryParams =
        originalBuildRuleParams.copyWithChanges(
            AndroidLibraryDescription.TYPE,
            BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_ANDROID_LIBRARY_FLAVOR),
            /* declaredDeps */ ImmutableSortedSet.<BuildRule>of(
                androidResource, prebuiltJar, unzipAar),
            /* extraDeps */ ImmutableSortedSet.<BuildRule>of());
    return new AndroidLibrary(
        androidLibraryParams,
        /* srcs */ ImmutableSortedSet.<SourcePath>of(),
        /* resources */ ImmutableSortedSet.<SourcePath>of(),
        Optional.of(unzipAar.getProguardConfig()),
        /* postprocessClassesCommands */ ImmutableList.<String>of(),
        /* exportedDeps */ ImmutableSortedSet.<BuildRule>of(prebuiltJar),
        /* providedDeps */ ImmutableSortedSet.<BuildRule>of(),
        /* additionalClasspathEntries */ ImmutableSet.<Path>of(),
        /* javacOptions */ JavacOptions.DEFAULTS,
        /* resourcesRoot */ Optional.<Path>absent(),
        /* manifestFile */ Optional.<SourcePath>absent(),
        /* isPrebuiltAar */ true);
  }