| // Copyright 2024 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.base.Objects; | |
| import com.google.common.base.Preconditions; | |
| import com.google.common.collect.ImmutableList; | |
| import com.google.devtools.build.lib.cmdline.Label; | |
| import com.google.devtools.build.lib.cmdline.PackageIdentifier; | |
| import com.google.devtools.build.lib.skyframe.serialization.VisibleForSerialization; | |
| import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; | |
| import com.google.devtools.build.skyframe.AbstractSkyKey; | |
| import com.google.devtools.build.skyframe.SkyFunctionName; | |
| import com.google.devtools.build.skyframe.SkyKey; | |
| import com.google.devtools.build.skyframe.SkyValue; | |
| import java.util.Collection; | |
| /** | |
| * {@link SkyValue} for finding the PROJECT files associated with a package. | |
| * | |
| * <p>See {@link com.google.devtools.build.lib.analysis.Project}. | |
| */ | |
| public class ProjectFilesLookupValue implements SkyValue { | |
| private final ImmutableList<Label> projectFiles; | |
| /** | |
| * Returns the {@link com.google.devtools.build.lib.analysis.Project} files associated with the | |
| * corresponding {@link Key}'s package. | |
| * | |
| * <p>Given {@code a/b/c/d}, project resolution walks up the package path (i.e. walks up the | |
| * directory tree from {@code d} back to {@code a}, only counting directories with BUILD files). | |
| * Each directory with both a BUILD file and project file has a label reference to the project | |
| * file here. | |
| * | |
| * <p>Order is innermost to outermost: if both {@code a/PROJECT.scl} and {@code a/b/c/PROJECT.scl} | |
| * are included, {@code a/b/c/PROJECT.scl} appears first. | |
| */ | |
| public ImmutableList<Label> getProjectFiles() { | |
| return projectFiles; | |
| } | |
| /** | |
| * Lookup key. | |
| * | |
| * @param id the package for which to find enclosing {@link | |
| * com.google.devtools.build.lib.analysis.Project} files | |
| */ | |
| public static Key key(PackageIdentifier id) { | |
| Preconditions.checkArgument(!id.getPackageFragment().isAbsolute(), id); | |
| return Key.create(id); | |
| } | |
| private static final ProjectFilesLookupValue NO_PROJECT_FILES = | |
| new ProjectFilesLookupValue(ImmutableList.of()); | |
| static ProjectFilesLookupValue of(Collection<Label> projectFiles) { | |
| return projectFiles.isEmpty() | |
| ? NO_PROJECT_FILES | |
| : new ProjectFilesLookupValue(ImmutableList.copyOf(projectFiles)); | |
| } | |
| private ProjectFilesLookupValue(ImmutableList<Label> projectFiles) { | |
| this.projectFiles = projectFiles; | |
| } | |
| @Override | |
| public boolean equals(Object o) { | |
| if (this == o) { | |
| return true; | |
| } | |
| if (!(o instanceof ProjectFilesLookupValue)) { | |
| return false; | |
| } | |
| return Objects.equal(projectFiles, ((ProjectFilesLookupValue) o).projectFiles); | |
| } | |
| @Override | |
| public int hashCode() { | |
| return java.util.Objects.hashCode(projectFiles); | |
| } | |
| /** {@link SkyKey} for {@code ProjectFilesLookupValue}. */ | |
| @AutoCodec | |
| public static class Key extends AbstractSkyKey<PackageIdentifier> { | |
| private static final SkyKeyInterner<Key> interner = SkyKey.newInterner(); | |
| private Key(PackageIdentifier arg) { | |
| super(arg); | |
| } | |
| private static Key create(PackageIdentifier arg) { | |
| return interner.intern(new Key(arg)); | |
| } | |
| @VisibleForSerialization | |
| @AutoCodec.Interner | |
| static Key intern(Key key) { | |
| return interner.intern(key); | |
| } | |
| @Override | |
| public SkyFunctionName functionName() { | |
| return SkyFunctions.PROJECT_FILES_LOOKUP; | |
| } | |
| @Override | |
| public SkyKeyInterner<Key> getSkyKeyInterner() { | |
| return interner; | |
| } | |
| } | |
| } |