blob: d3b69cf6b1159bc987e581ccb9c9465c0c3c8ffa [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.origin.Origin;
import com.android.tools.r8.utils.CliParserUtils;
import com.android.tools.r8.utils.FlagFile;
import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.internal.CliParser;
import com.android.tools.r8.utils.internal.StringUtils;
import java.nio.file.Paths;
public class ApiDatabaseGeneratorCommandParser {
private static class ParserState {
final ApiDatabaseGeneratorCommand.Builder builder;
final Origin origin;
ParserState(ApiDatabaseGeneratorCommand.Builder builder, Origin origin) {
this.builder = builder;
this.origin = origin;
}
}
private static CliParser<ParserState> createParser() {
String usageHeader =
StringUtils.joinLines(
"Usage: apidatabasegenerator [options]",
"Combines Android API information (--xml) with Android SDK information (--jar)",
"into an API database file required for compilation.",
"Multiple inputs of both are supported and any entries not present in both JAR and XML",
"form is trimmed away.",
"Note that the database format is unstable and not backwards compatible.",
"The options are:");
CliParser<ParserState> parser = new CliParser<>(usageHeader);
return parser
.option1(
"--jar",
"<jar-file>",
"Android SDK JAR file (e.g., android.jar).",
(state, arg) -> state.builder.addJarPath(Paths.get(arg)))
.option1(
"--xml",
"<xml-file>",
"Android API XML file (e.g., api-versions.xml).",
(state, arg) -> state.builder.addXmlPath(Paths.get(arg)))
.option1(
"--sdk",
"<sdk-dir>",
"Android SDK platform directory (e.g., $ANDROID_HOME/android-34).",
(state, arg) -> state.builder.addSdkPath(Paths.get(arg)))
.option1(
"--output",
"<database-file>",
"Output result in <database-file> (must be a file, not a directory). Defaults to"
+ " 'api_database.ser'.",
(state, arg) -> state.builder.setOutputPath(Paths.get(arg)))
.option0(
"--dont-amend",
"By default, the API database is amended with known missing information."
+ " This option disables that and processes inputs directly as they are.",
state -> state.builder.setAmend(false))
.apply(
CliParserUtils.addMapDiagnosticsOption(
state -> state.builder.getReporter(), state -> state.origin))
.apply(CliParserUtils.addVersionOption(state -> state.builder.setPrintVersion(true)))
.apply(CliParserUtils.addHelpOption(state -> state.builder.setPrintHelp(true)));
}
public static ApiDatabaseGeneratorCommand.Builder parse(String[] args, Origin origin) {
return new ApiDatabaseGeneratorCommandParser()
.parse(args, origin, ApiDatabaseGeneratorCommand.builder());
}
public static ApiDatabaseGeneratorCommand.Builder parse(
String[] args, Origin origin, DiagnosticsHandler handler) {
return new ApiDatabaseGeneratorCommandParser()
.parse(args, origin, ApiDatabaseGeneratorCommand.builder(handler));
}
private ApiDatabaseGeneratorCommand.Builder parse(
String[] args, Origin origin, ApiDatabaseGeneratorCommand.Builder builder) {
String[] expandedArgs = FlagFile.expandFlagFiles(args, builder::error);
ParserState state = new ParserState(builder, origin);
createParser()
.parse(expandedArgs, state, error -> builder.error(new StringDiagnostic(error, origin)));
return builder;
}
static String getUsageMessage() {
return CliParserUtils.getUsageMessage(createParser());
}
}