| // Copyright 2020 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.skyframe; | |
| import com.google.common.collect.ImmutableMap; | |
| import com.google.devtools.build.lib.cmdline.RepositoryName; | |
| import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationConstant; | |
| import com.google.devtools.build.skyframe.SkyFunctionName; | |
| import com.google.devtools.build.skyframe.SkyKey; | |
| import com.google.devtools.build.skyframe.SkyValue; | |
| import net.starlark.java.eval.StarlarkSemantics; | |
| /** | |
| * A Skyframe value representing the result of evaluating the {@code @_builtins} pseudo-repository. | |
| * | |
| * <p>To avoid unnecessary Skyframe edges, the {@code StarlarkSemantics} are included in this value, | |
| * so that a caller who obtains a StarlarkBuiltinsValue can also access the StarlarkSemantics | |
| * without an additional dependency. | |
| * | |
| * <p>These are parsed from {@code @_builtins//:exports.bzl}. | |
| */ | |
| public final class StarlarkBuiltinsValue implements SkyValue { | |
| static final String BUILTINS_NAME = "_builtins"; | |
| /** | |
| * The builtins pseudo-repository. | |
| * | |
| * <p>It is illegal to declare a repository in WORKSPACE whose name collides with this one. | |
| * Whether a collision has in fact occurred is determined by {@link RepositoryName#equals}, and | |
| * hence depends on the OS path policy (i.e. the case sensitivity of the host system). | |
| * | |
| * <p>Regardless of path policy, all actual uses of the builtins pseudo-repo are case sensitive | |
| * and must match {@link #BUILTINS_NAME} exactly. | |
| */ | |
| // TODO(#11437): Add actual enforcement that users cannot define a repo named "@_builtins". | |
| @SerializationConstant | |
| static final RepositoryName BUILTINS_REPO = RepositoryName.createUnvalidated(BUILTINS_NAME); | |
| /** Reports whether the given repository is the special builtins pseudo-repository. */ | |
| static boolean isBuiltinsRepo(RepositoryName repo) { | |
| // Use String.equals(), not RepositoryName.equals(), to force case sensitivity. | |
| return repo.getName().equals(BUILTINS_NAME); | |
| } | |
| // These are all (except transitiveDigest) deeply immutable since the Starlark values are already | |
| // frozen, so let's skip the accessors and mutators. | |
| /** | |
| * Top-level predeclared symbols for a .bzl file loaded on behalf of a BUILD file, after builtins | |
| * injection has been applied. | |
| */ | |
| public final ImmutableMap<String, Object> predeclaredForBuildBzl; | |
| /** | |
| * Top-level predeclared symbols for a BUILD file, after builtins injection but before any prelude | |
| * file has been applied. | |
| */ | |
| public final ImmutableMap<String, Object> predeclaredForBuild; | |
| /** Contents of the {@code exported_to_java} dict. */ | |
| public final ImmutableMap<String, Object> exportedToJava; | |
| /** Transitive digest of all .bzl files in {@code @_builtins}. */ | |
| public final byte[] transitiveDigest; | |
| /** The StarlarkSemantics used for {@code @_builtins} evaluation. */ | |
| public final StarlarkSemantics starlarkSemantics; | |
| private StarlarkBuiltinsValue( | |
| ImmutableMap<String, Object> predeclaredForBuildBzl, | |
| ImmutableMap<String, Object> predeclaredForBuild, | |
| ImmutableMap<String, Object> exportedToJava, | |
| byte[] transitiveDigest, | |
| StarlarkSemantics starlarkSemantics) { | |
| this.predeclaredForBuildBzl = predeclaredForBuildBzl; | |
| this.predeclaredForBuild = predeclaredForBuild; | |
| this.exportedToJava = exportedToJava; | |
| this.transitiveDigest = transitiveDigest; | |
| this.starlarkSemantics = starlarkSemantics; | |
| } | |
| public static StarlarkBuiltinsValue create( | |
| ImmutableMap<String, Object> predeclaredForBuildBzl, | |
| ImmutableMap<String, Object> predeclaredForBuild, | |
| ImmutableMap<String, Object> exportedToJava, | |
| byte[] transitiveDigest, | |
| StarlarkSemantics starlarkSemantics) { | |
| return new StarlarkBuiltinsValue( | |
| predeclaredForBuildBzl, | |
| predeclaredForBuild, | |
| exportedToJava, | |
| transitiveDigest, | |
| starlarkSemantics); | |
| } | |
| /** | |
| * Constructs a placeholder builtins value to be used when builtins injection is disabled, or for | |
| * use within builtins evaluation itself. | |
| * | |
| * <p>The placeholder simply wraps the StarlarkSemantics object. This lets code paths that don't | |
| * use injection still conveniently access the semantics without incurring a separate Skyframe | |
| * edge. | |
| */ | |
| public static StarlarkBuiltinsValue createEmpty(StarlarkSemantics starlarkSemantics) { | |
| return new StarlarkBuiltinsValue( | |
| /*predeclaredForBuildBzl=*/ ImmutableMap.of(), | |
| /*predeclaredForBuild=*/ ImmutableMap.of(), | |
| /*exportedToJava=*/ ImmutableMap.of(), | |
| /*transitiveDigest=*/ new byte[] {}, | |
| starlarkSemantics); | |
| } | |
| /** Returns the singleton SkyKey for this type of value. */ | |
| public static Key key() { | |
| return Key.INSTANCE; | |
| } | |
| /** | |
| * Skyframe key for retrieving the {@code @_builtins} definitions. | |
| * | |
| * <p>This has no fields since there is only one {@code StarlarkBuiltinsValue} at a time. | |
| */ | |
| static final class Key implements SkyKey { | |
| private static final Key INSTANCE = new Key(); | |
| private Key() {} | |
| @Override | |
| public SkyFunctionName functionName() { | |
| return SkyFunctions.STARLARK_BUILTINS; | |
| } | |
| @Override | |
| public String toString() { | |
| return "Starlark @_builtins"; | |
| } | |
| @Override | |
| public boolean equals(Object other) { | |
| return other instanceof Key; | |
| } | |
| @Override | |
| public int hashCode() { | |
| return 7727; // more or less xkcd/221 | |
| } | |
| } | |
| } |