| // 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()); |
| } |
| } |