| // 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.cmdline; |
| |
| import com.google.common.base.Preconditions; |
| import com.google.devtools.build.lib.supplier.InterruptibleSupplier; |
| import javax.annotation.Nullable; |
| import net.starlark.java.eval.StarlarkThread; |
| |
| /** |
| * Bazel-specific contextual information associated with a Starlark evaluation thread. |
| * |
| * <p>This is stored in the {@link StarlarkThread} object as a thread-local. A distinct subclass of |
| * this class should be defined and used for each different scenario of Starlark evaluation; in any |
| * case, it is still keyed in the thread-locals under {@code StarlarkThreadContext.class}. Users of |
| * this class should prefer to use a {@code fromOrFail} static method to retrieve an instance from a |
| * {@link StarlarkThread} instead of calling {@link StarlarkThread#getThreadLocal} directly, and |
| * prefer to use {@link #storeInThread} instead of calling {@link StarlarkThread#setThreadLocal} |
| * directly. |
| * |
| * <p>This object tends to be mutable and should not be accessed simultaneously or reused for more |
| * than one Starlark thread. |
| */ |
| public abstract class StarlarkThreadContext { |
| // TODO: decide the extent to which we should enforce that such a context object is available |
| // anywhere we execute Starlark code in Bazel. As of right now (Jun 2024), the only field here is |
| // `mainRepoMappingSupplier`, and even that one is not strictly necessary (can be null and things |
| // will still work). |
| |
| /** |
| * Saves this {@link StarlarkThreadContext} in the specified Starlark thread. Call only once, |
| * before evaluation begins. |
| * |
| * <p>Users of this class should prefer to use this method instead of calling {@link |
| * StarlarkThread#setThreadLocal} directly. |
| */ |
| public void storeInThread(StarlarkThread thread) { |
| Preconditions.checkState(thread.getThreadLocal(StarlarkThreadContext.class) == null); |
| thread.setThreadLocal(StarlarkThreadContext.class, this); |
| } |
| |
| @Nullable private final InterruptibleSupplier<RepositoryMapping> mainRepoMappingSupplier; |
| |
| /** |
| * @param mainRepoMappingSupplier a supplier for the repo mapping of the main repo. This is used |
| * for debug-printing {@link Label} objects. Can be null if the main repo mapping isn't |
| * readily available, which just causes the debug-printing to produce canonical label |
| * literals. |
| */ |
| protected StarlarkThreadContext( |
| @Nullable InterruptibleSupplier<RepositoryMapping> mainRepoMappingSupplier) { |
| this.mainRepoMappingSupplier = mainRepoMappingSupplier; |
| } |
| |
| /** |
| * The repository mapping applicable to the main repository. This is purely meant to support |
| * {@link Label#debugPrint}. |
| */ |
| @Nullable |
| public RepositoryMapping getMainRepoMapping() throws InterruptedException { |
| return mainRepoMappingSupplier == null ? null : mainRepoMappingSupplier.get(); |
| } |
| } |