| // Copyright 2022 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.packages; |
| |
| import com.google.common.collect.ImmutableMap; |
| import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; |
| import com.google.devtools.build.lib.cmdline.Label; |
| import com.google.devtools.build.lib.cmdline.RepositoryName; |
| import com.google.errorprone.annotations.CanIgnoreReturnValue; |
| import java.util.Optional; |
| import javax.annotation.Nullable; |
| import net.starlark.java.eval.EvalException; |
| import net.starlark.java.eval.Starlark; |
| import net.starlark.java.eval.StarlarkThread; |
| |
| /** |
| * Bazel application data for the Starlark thread that evaluates the top-level code in a .bzl (or |
| * .scl) module (i.e. when evaluating that module's global symbols). |
| */ |
| public final class BzlInitThreadContext extends BazelStarlarkContext |
| implements RuleDefinitionEnvironment { |
| |
| private final Label bzlFile; |
| |
| /* Digest of the .bzl file being initialized along with all its transitive loads. */ |
| private final byte[] transitiveDigest; |
| |
| // For storing the result of calling `visibility()`. |
| @Nullable private BzlVisibility bzlVisibility; |
| |
| private final RepositoryName toolsRepository; |
| |
| // TODO(b/192694287): Remove once we migrate all tests from the allowlist |
| private final Optional<Label> networkAllowlistForTests; |
| |
| // Used for `configuration_field`. |
| private final ImmutableMap<String, Class<?>> fragmentNameToClass; |
| |
| /** |
| * Constructs a new context for initializing a .bzl file. |
| * |
| * @param bzlFile the name of the .bzl being initialized |
| * @param transitiveDigest the hash of that file and its transitive load()s |
| * @param toolsRepository the name of the tools repository, such as "@bazel_tools" |
| * @param networkAllowlistForTests an allowlist for rule classes created by this thread |
| * @param fragmentNameToClass a map from configuration fragment name to configuration fragment |
| * class, such as "apple" to AppleConfiguration.class |
| * @param symbolGenerator symbol generator for this context |
| */ |
| public BzlInitThreadContext( |
| Label bzlFile, |
| byte[] transitiveDigest, |
| RepositoryName toolsRepository, |
| Optional<Label> networkAllowlistForTests, |
| ImmutableMap<String, Class<?>> fragmentNameToClass, |
| SymbolGenerator<?> symbolGenerator) { |
| super(BazelStarlarkContext.Phase.LOADING, symbolGenerator); |
| this.bzlFile = bzlFile; |
| this.transitiveDigest = transitiveDigest; |
| this.toolsRepository = toolsRepository; |
| this.networkAllowlistForTests = networkAllowlistForTests; |
| this.fragmentNameToClass = fragmentNameToClass; |
| } |
| |
| /** |
| * Retrieves this context from a Starlark thread. If not present, throws {@code EvalException} |
| * with an error message indicating that {@code what} can't be used in this Starlark environment. |
| */ |
| @CanIgnoreReturnValue |
| public static BzlInitThreadContext fromOrFail(StarlarkThread thread, String what) |
| throws EvalException { |
| @Nullable BazelStarlarkContext ctx = thread.getThreadLocal(BazelStarlarkContext.class); |
| if (!(ctx instanceof BzlInitThreadContext)) { |
| throw Starlark.errorf( |
| "%s can only be used during .bzl initialization (top-level evaluation)", what); |
| } |
| return (BzlInitThreadContext) ctx; |
| } |
| |
| /** |
| * Returns the label of the .bzl module being initialized. |
| * |
| * <p>Note that this is not necessarily the same as the module of the innermost stack frame (i.e., |
| * {@code BazelModuleContext.of(Module.ofInnermostEnclosingStarlarkFunction(thread)).label()}), |
| * since the module may call helper functions loaded from elsewhere. |
| */ |
| public Label getBzlFile() { |
| return bzlFile; |
| } |
| |
| /** Returns the transitive digest of the .bzl module being initialized. */ |
| public byte[] getTransitiveDigest() { |
| return transitiveDigest; |
| } |
| |
| /** |
| * Returns the saved BzlVisibility that was declared for the currently initializing .bzl module. |
| */ |
| @Nullable |
| public BzlVisibility getBzlVisibility() { |
| return bzlVisibility; |
| } |
| |
| /** Sets the BzlVisibility for the currently initializing .bzl module. */ |
| public void setBzlVisibility(BzlVisibility bzlVisibility) { |
| this.bzlVisibility = bzlVisibility; |
| } |
| |
| /** Returns the name of the tools repository, such as "@bazel_tools". */ |
| @Override |
| public RepositoryName getToolsRepository() { |
| return toolsRepository; |
| } |
| |
| /** Returns a label for network allowlist for tests if one should be added. */ |
| // TODO(b/192694287): Remove once we migrate all tests from the allowlist. |
| @Override |
| public Optional<Label> getNetworkAllowlistForTests() { |
| return networkAllowlistForTests; |
| } |
| |
| /** Returns a map from configuration fragment name to configuration fragment class. */ |
| public ImmutableMap<String, Class<?>> getFragmentNameToClass() { |
| return fragmentNameToClass; |
| } |
| } |