blob: 2ead69fcf2797a52dee487f6d45f652fe553fd61 [file] [log] [blame]
// 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();
}
}