blob: f3d557e8740f5b8efb460cf5706500ee21361c06 [file]
// Copyright (c) 2026, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
import com.android.tools.r8.keepanno.annotations.KeepForApi;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.internal.Box;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@KeepForApi
public final class ApiDatabaseGeneratorCommand {
private final List<Path> jarPaths;
private final List<Path> xmlPaths;
private final Path outputPath;
private final Reporter reporter;
private final boolean printHelp;
private final boolean printVersion;
private ApiDatabaseGeneratorCommand(
List<Path> jarPaths, List<Path> xmlPaths, Path outputPath, Reporter reporter) {
this.jarPaths = jarPaths;
this.xmlPaths = xmlPaths;
this.outputPath = outputPath;
this.reporter = reporter;
this.printHelp = false;
this.printVersion = false;
}
private ApiDatabaseGeneratorCommand(boolean printHelp, boolean printVersion) {
this.jarPaths = Collections.emptyList();
this.xmlPaths = Collections.emptyList();
this.outputPath = null;
this.reporter = new Reporter();
this.printHelp = printHelp;
this.printVersion = printVersion;
}
public DiagnosticsHandler getDiagnosticsHandler() {
return reporter;
}
public Reporter getReporter() {
return reporter;
}
public List<Path> getJarPaths() {
return jarPaths;
}
public List<Path> getXmlPaths() {
return xmlPaths;
}
public Path getOutputPath() {
return outputPath;
}
public boolean isPrintHelp() {
return printHelp;
}
public boolean isPrintVersion() {
return printVersion;
}
public static Builder parse(String[] args, Origin origin) {
return ApiDatabaseGeneratorCommandParser.parse(args, origin);
}
public static Builder parse(String[] args, Origin origin, DiagnosticsHandler handler) {
return ApiDatabaseGeneratorCommandParser.parse(args, origin, handler);
}
public static Builder builder() {
return new Builder();
}
public static Builder builder(DiagnosticsHandler diagnosticsHandler) {
return new Builder(diagnosticsHandler);
}
@KeepForApi
public static class Builder {
private final List<Path> inputPaths = new ArrayList<>();
private Path outputPath = null;
private boolean printHelp = false;
private boolean printVersion = false;
private final Reporter reporter;
private Builder() {
this.reporter = new Reporter();
}
private Builder(DiagnosticsHandler diagnosticsHandler) {
this.reporter = new Reporter(diagnosticsHandler);
}
public Builder addInputPath(Path inputPath) {
this.inputPaths.add(inputPath);
return this;
}
public Builder setOutputPath(Path outputPath) {
this.outputPath = outputPath;
return this;
}
public Builder setPrintHelp(boolean printHelp) {
this.printHelp = printHelp;
return this;
}
public Builder setPrintVersion(boolean printVersion) {
this.printVersion = printVersion;
return this;
}
public ApiDatabaseGeneratorCommand build() throws ApiDatabaseGeneratorException {
if (printHelp || printVersion) {
return new ApiDatabaseGeneratorCommand(printHelp, printVersion);
}
Box<ApiDatabaseGeneratorCommand> box = new Box<>(null);
ExceptionUtils.withDiagnosticsHandler(
reporter,
() -> {
List<Path> jarPaths = new ArrayList<>();
List<Path> xmlPaths = new ArrayList<>();
for (Path path : inputPaths) {
String name = path.getFileName().toString().toLowerCase();
if (name.endsWith(".jar")) {
jarPaths.add(path);
} else if (name.endsWith(".xml")) {
xmlPaths.add(path);
} else {
error(
new StringDiagnostic(
"Unsupported input file extension: "
+ path
+ ". Must be either .jar or .xml"));
}
}
if (jarPaths.isEmpty()) {
error(new StringDiagnostic("At least one SDK JAR input path must be specified"));
}
if (xmlPaths.isEmpty()) {
error(new StringDiagnostic("At least one API XML input path must be specified"));
}
if (outputPath == null) {
outputPath = Paths.get(".", "api_database.ser");
}
box.set(new ApiDatabaseGeneratorCommand(jarPaths, xmlPaths, outputPath, reporter));
},
(message, cause, cancelled) -> new ApiDatabaseGeneratorException(message, cause));
return box.get();
}
public void error(Diagnostic diagnostic) {
reporter.error(diagnostic);
}
public Builder addDiagnosticsLevelMapping(
DiagnosticsLevel from, String diagnosticsClassName, DiagnosticsLevel to) {
reporter.addDiagnosticsLevelMapping(from, diagnosticsClassName, to);
return this;
}
}
}