blob: a69b602df1ad76b5dd48887f39d1beba69a22f4c [file] [log] [blame]
// Copyright 2014 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.analysis.configuredtargets;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.LicensesProvider;
import com.google.devtools.build.lib.analysis.LicensesProviderImpl;
import com.google.devtools.build.lib.analysis.OutputGroupInfo;
import com.google.devtools.build.lib.analysis.RequiredConfigFragmentsProvider;
import com.google.devtools.build.lib.analysis.TargetContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.analysis.test.InstrumentedFilesInfo;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.BuiltinProvider;
import com.google.devtools.build.lib.packages.Info;
import com.google.devtools.build.lib.packages.OutputFile;
import com.google.devtools.build.lib.packages.Provider;
import javax.annotation.Nullable;
import net.starlark.java.eval.Dict;
import net.starlark.java.eval.Printer;
/** A ConfiguredTarget for an OutputFile. */
@Immutable
public final class OutputFileConfiguredTarget extends FileConfiguredTarget {
private final RuleConfiguredTarget generatingRule;
public OutputFileConfiguredTarget(
TargetContext targetContext, Artifact outputArtifact, RuleConfiguredTarget generatingRule) {
super(targetContext, outputArtifact);
this.generatingRule = checkNotNull(generatingRule);
checkArgument(targetContext.getTarget() instanceof OutputFile, targetContext.getTarget());
}
public RuleConfiguredTarget getGeneratingRule() {
return generatingRule;
}
@Override
public BuiltinProvider<LicensesProvider> getProvider() {
return LicensesProvider.PROVIDER;
}
@Override
@Nullable
public <P extends TransitiveInfoProvider> P getProvider(Class<P> providerClass) {
P provider = super.getProvider(providerClass);
if (provider != null) {
return provider;
}
if (providerClass == RequiredConfigFragmentsProvider.class) {
return generatingRule.getProvider(providerClass);
}
return null;
}
@Nullable
@Override
protected Info rawGetStarlarkProvider(Provider.Key providerKey) {
// The following Starlark providers do not implement TransitiveInfoProvider and thus may only be
// requested via this method using a Provider.Key, not via getProvider(Class) above.
if (providerKey.equals(LicensesProvider.PROVIDER.getKey())) {
return generatingRule.get(LicensesProvider.PROVIDER);
}
if (providerKey.equals(InstrumentedFilesInfo.STARLARK_CONSTRUCTOR.getKey())) {
return firstNonNull(
generatingRule.get(InstrumentedFilesInfo.STARLARK_CONSTRUCTOR),
InstrumentedFilesInfo.EMPTY);
}
if (providerKey.equals(OutputGroupInfo.STARLARK_CONSTRUCTOR.getKey())) {
// We have an OutputFileConfiguredTarget, so the generating rule must have OutputGroupInfo.
NestedSet<Artifact> validationOutputs =
generatingRule
.get(OutputGroupInfo.STARLARK_CONSTRUCTOR)
.getOutputGroup(OutputGroupInfo.VALIDATION);
if (!validationOutputs.isEmpty()) {
return OutputGroupInfo.singleGroup(OutputGroupInfo.VALIDATION, validationOutputs);
}
}
return null;
}
@Override
public Dict<String, Object> getProvidersDictForQuery() {
Dict.Builder<String, Object> dict = Dict.builder();
dict.putAll(super.getProvidersDictForQuery());
addStarlarkProviderIfPresent(dict, InstrumentedFilesInfo.STARLARK_CONSTRUCTOR);
addStarlarkProviderIfPresent(dict, OutputGroupInfo.STARLARK_CONSTRUCTOR);
addNativeProviderFromRuleIfPresent(dict, RequiredConfigFragmentsProvider.class);
return dict.buildImmutable();
}
private void addStarlarkProviderIfPresent(Dict.Builder<String, Object> dict, Provider provider) {
Info info = rawGetStarlarkProvider(provider.getKey());
if (info != null) {
tryAddProviderForQuery(dict, provider.getKey(), info);
}
}
private void addNativeProviderFromRuleIfPresent(
Dict.Builder<String, Object> dict, Class<? extends TransitiveInfoProvider> providerClass) {
TransitiveInfoProvider provider = generatingRule.getProvider(providerClass);
if (provider != null) {
tryAddProviderForQuery(dict, providerClass, provider);
}
}
@Override
public NestedSet<TargetLicense> getTransitiveLicenses() {
return getLicencesProviderFromGeneratingRule().getTransitiveLicenses();
}
@Override
public TargetLicense getOutputLicenses() {
return getLicencesProviderFromGeneratingRule().getOutputLicenses();
}
@Override
public boolean hasOutputLicenses() {
return getLicencesProviderFromGeneratingRule().hasOutputLicenses();
}
private LicensesProvider getLicencesProviderFromGeneratingRule() {
return firstNonNull(generatingRule.get(LicensesProvider.PROVIDER), LicensesProviderImpl.EMPTY);
}
@Override
public void repr(Printer printer) {
printer.append("<output file target " + getLabel() + ">");
}
}