private static void applyDoclava()

in buildSrc/src/main/java/com/google/firebase/gradle/plugins/JavadocPlugin.java [85:273]


  private static void applyDoclava(Project project) {
    project.getConfigurations().maybeCreate("javadocCustomConfig");
    project.getDependencies().add("javadocCustomConfig", "com.google.doclava:doclava:1.0.6");

    // setting overwrite as java-library adds the javadoc task by default and it does not work
    // with our @hide tags.
    Javadoc generateJavadoc = project.getTasks().replace("generateJavadoc", Javadoc.class);
    project.configure(
        generateJavadoc,
        closureOf(
            (Javadoc javadoc) -> {
              project
                  .getTasks()
                  .all(
                      it -> {
                        if (it.getName().equals("assembleRelease")) {
                          javadoc.dependsOn(it);
                        }
                      });
              // Besides third party libraries, firestore depends on the sibling module
              // :immutable-collection,
              // which needs to be in the classpath when javadoc is run
              // Ref:
              // https://stackoverflow.com/questions/41076271/javadoc-generation-error-package-does-not-exist-in-multi-module-project
              if (ProjectUtilsKt.isAndroid(project)) {
                LibraryExtension android =
                    project.getExtensions().getByType(LibraryExtension.class);
                javadoc.setClasspath(
                    javadoc.getClasspath().plus(project.files(android.getBootClasspath())));
                // We include the Timestamp file in common's javadoc source set and remove it from
                // Firestore"s source set
                // This comes with the risks of Timestamp's javadoc and binary releases having
                // disconnected timelines.
                // Given the repeated tedium in dealing with javadoc, this risk seems worth taking
                if ("firebase-common".equals(project.getName())) {
                  Project firestoreProject = project.findProject(":firebase-firestore");
                  javadoc.setSource(
                      android
                          .getSourceSets()
                          .getByName("main")
                          .getJava()
                          .getSourceFiles()
                          .plus(
                              firestoreProject.files(
                                  "src/main/java/com/google/firebase/Timestamp.java")));

                } else if ("firebase-firestore".equals(project.getName())) {
                  javadoc.setSource(
                      android
                          .getSourceSets()
                          .getByName("main")
                          .getJava()
                          .getSourceFiles()
                          .minus(
                              project.files("src/main/java/com/google/firebase/Timestamp.java")));
                } else {
                  javadoc.setSource(
                      android.getSourceSets().getByName("main").getJava().getSrcDirs());
                }
                android
                    .getLibraryVariants()
                    .all(
                        variant -> {
                          if (!"release".equals(variant.getName().toLowerCase())) {
                            return;
                          }
                          javadoc.setClasspath(
                              javadoc
                                  .getClasspath()
                                  .plus(
                                      getJars(variant.getCompileConfiguration())
                                          .plus(getJars(variant.getRuntimeConfiguration()))));

                          // this includes compiled sources which avoids "cannot find symbol" errors
                          javadoc.setClasspath(
                              javadoc
                                  .getClasspath()
                                  .plus(
                                      project.files(variant.getJavaCompile().getDestinationDir())));
                        });
              } else {
                JavaPluginConvention java =
                    project.getConvention().getPlugin(JavaPluginConvention.class);
                javadoc.setSource(java.getSourceSets().getByName("main").getAllJava());
                javadoc.setClasspath(java.getSourceSets().getByName("main").getCompileClasspath());
              }

              Configuration javadocClasspath =
                  project.getConfigurations().findByName("javadocClasspath");

              if (javadocClasspath != null) {
                javadoc.setClasspath(javadoc.getClasspath().plus(getJars(javadocClasspath)));
              }

              // Gradle passes the (unsupported) -doctitle option to the doclava doclet.
              // We set the title to null to overcome this issue
              javadoc.setTitle(null);
              javadoc.getOptions().setDoclet("com.google.doclava.Doclava");

              // set book path and project path used in g3 templates
              CoreJavadocOptions options = (CoreJavadocOptions) javadoc.getOptions();
              options
                  .addMultilineMultiValueOption("hdf")
                  .setValue(
                      ImmutableList.of(
                          ImmutableList.of("book.path", "/docs/reference/_book.yaml"),
                          ImmutableList.of("project.path", "/_project.yaml")));

              // root path assumed by docs
              options.addStringOption("toroot", "/docs/reference/android/");

              // TODO(ashwinraghav) : These currently fail because of unknown annotations in
              // Firestore
              // @Documented, @TypeQualifierNickname, @Retention which are relatively minor
              // b/74115412
              // options.addMultilineStringsOption("error").setValue(["103", "104"])

              options.addMultilineStringsOption("warning").setValue(ImmutableList.of("101", "106"));

              // destination for generated toc yaml
              options.addStringOption("yaml", "_toc.yaml");

              if (project.hasProperty("templatedir")) {
                options.addStringOption(
                    "templatedir", project.getProperties().get("templatedir").toString());
              }

              // Custom doclet can be specified in certain scenarios
              if (project.hasProperty("docletpath")) {
                options.setDocletpath(
                    ImmutableList.of(project.file(project.getProperties().get("docletpath"))));
              } else {
                options.setDocletpath(
                    ImmutableList.copyOf(
                        project.getConfigurations().getByName("javadocCustomConfig").getFiles()));
              }

              ImmutableList.Builder<List<String>> federationApiFiles = ImmutableList.builder();
              ImmutableList.Builder<List<String>> federationUrls = ImmutableList.builder();

              if (project.hasProperty("android_api_file")) {
                federationUrls.add(ImmutableList.of("Android", "https://developer.android.com"));
                federationApiFiles.add(
                    ImmutableList.of(
                        "Android", project.getProperties().get("android_api_file").toString()));
              }
              if (project.hasProperty("android_support_library_api_file")) {
                federationUrls.add(
                    ImmutableList.of("Android Support Library", "https://developer.android.com"));
                federationApiFiles.add(
                    ImmutableList.of(
                        "Android Support Library",
                        project
                            .getProperties()
                            .get("android_support_library_api_file")
                            .toString()));
              }
              if (project.hasProperty("google_play_services_api_file")) {
                federationUrls.add(
                    ImmutableList.of(
                        "Google Play services", "https://developers.google.com/android"));
                federationApiFiles.add(
                    ImmutableList.of(
                        "Google Play services",
                        project.getProperties().get("google_play_services_api_file").toString()));
              }
              if (project.hasProperty("tasks_api_file")) {
                federationUrls.add(
                    ImmutableList.of("Tasks", "https://developers.google.com/android"));
                federationApiFiles.add(
                    ImmutableList.of(
                        "Tasks", project.getProperties().get("tasks_api_file").toString()));
              }

              // set federated links for external projects that need to be linked
              options.addMultilineMultiValueOption("federate").setValue(federationUrls.build());
              options
                  .addMultilineMultiValueOption("federationapi")
                  .setValue(federationApiFiles.build());
            }));
    project
        .getTasks()
        .create(
            TasksKt.JAVADOC_TASK_NAME,
            task -> {
              task.dependsOn(generateJavadoc);
              createEmptyApiFile(project);
            });
  }