blob: c3526aabb5c6271299ec15c78085ab3ecc4664bd [file] [log] [blame]
/*
* Copyright 2014-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.android;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.rules.coercer.BuildConfigFields;
import com.facebook.buck.rules.coercer.ImmutableBuildConfigFields;
import com.google.common.collect.ImmutableList;
/**
* Utilities for generating a {@code BuildConfig.java} file for Android.
*/
public class BuildConfigs {
/**
* Name of the boolean global variable provided by the standard Android tools to indicate whether
* an app was built in debug mode or not.
*/
public static final String DEBUG_CONSTANT = "DEBUG";
/**
* Name of a Buck-specific global variable that indicates whether an app was built using
* exopackage.
*/
public static final String IS_EXO_CONSTANT = "IS_EXOPACKAGE";
/**
* Name of a global variable that includes the exopackage configuration as a bitmask.
*/
public static final String EXOPACKAGE_FLAGS = "EXOPACKAGE_FLAGS";
/** @see #getDefaultBuildConfigFields() */
private static final BuildConfigFields DEFAULT_BUILD_CONFIG_CONSTANTS =
BuildConfigFields.fromFields(ImmutableList.<BuildConfigFields.Field>of(
// DEBUG is expected by the standard Android tools.
ImmutableBuildConfigFields.Field.of("boolean", DEBUG_CONSTANT, "true"),
// IS_EXOPACKAGE is a value we use internally for checking whether exopackage is being
// used.
ImmutableBuildConfigFields.Field.of("boolean", IS_EXO_CONSTANT, "false"),
ImmutableBuildConfigFields.Field.of("int", EXOPACKAGE_FLAGS, "0")));
/** Utility class: do not instantiate. */
private BuildConfigs() {}
/**
* Returns a list of fields (with values) that every {@code BuildConfig.java} should
* declare. The default value of each constant may be overridden by the {@code userFields} passed
* to {@link #generateBuildConfigDotJava(BuildTarget, String, boolean, BuildConfigFields)} when
* generating a {@code BuildConfig.java}.
*/
public static BuildConfigFields getDefaultBuildConfigFields() {
return DEFAULT_BUILD_CONFIG_CONSTANTS;
}
/**
* Generates the source code for an Android {@code BuildConfig.java} file with the default set of
* fields specified by {@link #getDefaultBuildConfigFields()}.
*/
public static String generateBuildConfigDotJava(BuildTarget source, String javaPackage) {
return generateBuildConfigDotJava(
source,
javaPackage,
/* useConstantExpressions */ false,
BuildConfigFields.empty());
}
/**
* Generates the source code for an Android {@code BuildConfig.java} file with fields
* specified by {@code userFields}.
* <p>
* The output will also contain a constant for every entry in the collection returned by
* {@link #getDefaultBuildConfigFields()}.
* <p>
* If the name of a field in {@code userFields} matches one in the collection returned by
* {@link #getDefaultBuildConfigFields()}, the value in the {@code userFields} map will be
* used.
* @param javaPackage The package for the Java class generated by this method.
* @param useConstantExpressions If {@code true}, the value for each static final field in the
* generated class will be declared as the literal value in {@code userFields}. The
* values of such fields can be inlined by {@code javac}.
* <p>
* If {@code false}, the value for each static final field in the generated class will be
* declared as a non-constant expression that is guaranteed to evaluate to the same value
* in {@code userFields}. This ensures that the generated {@code BuildConfig.java}
* can still be used in Robolectric tests, but does not run the risk of its values being
* inlined by {@code javac}. This is important if the generated {@code BuildConfig} class is
* going to be swapped out by a different implementation by {@link AndroidBinary}. See
* {@link AndroidBuildConfig} for details.
* @param userFields represents the fields that should be declared in the generated
* {@code BuildConfig} class.
*/
public static String generateBuildConfigDotJava(
BuildTarget source,
String javaPackage,
boolean useConstantExpressions,
BuildConfigFields userFields) {
BuildConfigFields totalFields = getDefaultBuildConfigFields().putAll(userFields);
return totalFields.generateBuildConfigDotJava(source, javaPackage, useConstantExpressions);
}
}