// Copyright 2018 The Bazel Authors. All rights reserved. // // 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.google.devtools.build.lib.rules.android; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.packages.BuiltinProvider; import com.google.devtools.build.lib.packages.NativeInfo; import com.google.devtools.build.lib.skylarkbuildapi.android.AndroidAssetsInfoApi; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.SkylarkNestedSet; import java.util.Optional; import javax.annotation.Nullable; /** Provides information about transitive Android assets. */ public final class AndroidAssetsInfo extends NativeInfo implements AndroidAssetsInfoApi { public static final String PROVIDER_NAME = "AndroidAssetsInfo"; public static final Provider PROVIDER = new Provider(); private final Label label; @Nullable private final Artifact validationResult; private final NestedSet directParsedAssets; private final NestedSet transitiveParsedAssets; private final NestedSet transitiveAssets; private final NestedSet transitiveSymbols; /** * Whether the local assets have been specified. This field is needed to distinguish between the * situation when the local assets haven't been specified and the {@link #directParsedAssets} * contains assets form the target's dependencies. */ private final boolean hasLocalAssets; private final NestedSet transitiveCompiledSymbols; static AndroidAssetsInfo empty(Label label) { return new AndroidAssetsInfo( label, null, NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER)); } public static AndroidAssetsInfo of( Label label, @Nullable Artifact validationResult, NestedSet directParsedAssets, NestedSet transitiveParsedAssets, NestedSet transitiveAssets, NestedSet transitiveSymbols, NestedSet transitiveCompiledSymbols) { return new AndroidAssetsInfo( label, validationResult, directParsedAssets, transitiveParsedAssets, transitiveAssets, transitiveSymbols, transitiveCompiledSymbols); } private AndroidAssetsInfo( Label label, @Nullable Artifact validationResult, NestedSet directParsedAssets, NestedSet transitiveParsedAssets, NestedSet transitiveAssets, NestedSet transitiveSymbols, NestedSet transitiveCompiledSymbols) { super(PROVIDER); this.label = label; this.hasLocalAssets = validationResult != null; this.validationResult = validationResult; this.directParsedAssets = directParsedAssets; this.transitiveParsedAssets = transitiveParsedAssets; this.transitiveAssets = transitiveAssets; this.transitiveSymbols = transitiveSymbols; this.transitiveCompiledSymbols = transitiveCompiledSymbols; } @Override public Label getLabel() { return label; } @Nullable @Override public Artifact getValidationResult() { return validationResult; } @Override public NestedSet getDirectParsedAssets() { return directParsedAssets; } @Override public ImmutableList getLocalAssets() { return getLocalParsedAndroidAssets().map(AndroidAssets::getAssets).orElse(null); } @Override public String getLocalAssetDir() { return getLocalParsedAndroidAssets().map(AndroidAssets::getAssetDirAsString).orElse(null); } @Override public NestedSet getTransitiveParsedAssets() { return transitiveParsedAssets; } @Override public NestedSet getAssets() { return transitiveAssets; } @Override public NestedSet getSymbols() { return transitiveSymbols; } private Optional getLocalParsedAndroidAssets() { return hasLocalAssets && getDirectParsedAssets().isSingleton() ? Optional.of(Iterables.getOnlyElement(getDirectParsedAssets())) : Optional.empty(); } @Override public NestedSet getCompiledSymbols() { return transitiveCompiledSymbols; } /** The provider can construct the Android IDL provider. */ public static class Provider extends BuiltinProvider implements AndroidAssetsInfoApi.Provider { private Provider() { super(PROVIDER_NAME, AndroidAssetsInfo.class); } @Override public AndroidAssetsInfo createInfo( Label label, Artifact validationResult, SkylarkNestedSet directParsedAssets, SkylarkNestedSet transitiveParsedAssets, SkylarkNestedSet transitiveAssets, SkylarkNestedSet transitiveSymbols, SkylarkNestedSet transitiveCompiledSymbols) throws EvalException { return new AndroidAssetsInfo( label, validationResult, nestedSet(directParsedAssets, ParsedAndroidAssets.class), nestedSet(transitiveParsedAssets, ParsedAndroidAssets.class), nestedSet(transitiveAssets, Artifact.class), nestedSet(transitiveSymbols, Artifact.class), nestedSet(transitiveCompiledSymbols, Artifact.class)); } private NestedSet nestedSet(SkylarkNestedSet from, Class with) { return NestedSetBuilder.naiveLinkOrder().addTransitive(from.getSet(with)).build(); } } }