blob: 924a601bf317953aa27e4d5239d70bc404c32e21 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2015 The Bazel Authors. All rights reserved.
Greg Estren531fc042015-05-26 22:37:44 +00002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.lib.skyframe;
15
janakr171a7eb2018-03-26 09:26:53 -070016import com.google.common.annotations.VisibleForTesting;
janakr29bd80d2017-12-28 12:59:48 -080017import com.google.common.collect.ImmutableSortedSet;
18import com.google.common.collect.Interner;
Greg Estren531fc042015-05-26 22:37:44 +000019import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
20import com.google.devtools.build.lib.analysis.config.BuildOptions;
janakra39a5622018-01-24 08:43:35 -080021import com.google.devtools.build.lib.analysis.config.FragmentClassSet;
janakr29bd80d2017-12-28 12:59:48 -080022import com.google.devtools.build.lib.concurrent.BlazeInterners;
Greg Estren531fc042015-05-26 22:37:44 +000023import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
shahan9694cae2018-01-10 18:02:30 -080024import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
janakr129c3e22018-07-27 10:50:45 -070025import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
janakr34e1b3c2017-12-20 14:27:55 -080026import com.google.devtools.build.skyframe.SkyFunctionName;
Greg Estren531fc042015-05-26 22:37:44 +000027import com.google.devtools.build.skyframe.SkyKey;
28import com.google.devtools.build.skyframe.SkyValue;
schmitt3e770242019-04-22 14:12:24 -070029import com.google.devtools.common.options.OptionsParsingException;
Greg Estren531fc042015-05-26 22:37:44 +000030import java.io.Serializable;
31import java.util.Objects;
32import java.util.Set;
Greg Estren531fc042015-05-26 22:37:44 +000033
shahan9694cae2018-01-10 18:02:30 -080034/** A Skyframe value representing a {@link BuildConfiguration}. */
Greg Estren531fc042015-05-26 22:37:44 +000035// TODO(bazel-team): mark this immutable when BuildConfiguration is immutable.
36// @Immutable
shahanfae34b92018-02-13 10:08:47 -080037@AutoCodec
Greg Estren531fc042015-05-26 22:37:44 +000038@ThreadSafe
39public class BuildConfigurationValue implements SkyValue {
Greg Estren531fc042015-05-26 22:37:44 +000040 private final BuildConfiguration configuration;
41
42 BuildConfigurationValue(BuildConfiguration configuration) {
43 this.configuration = configuration;
44 }
45
46 public BuildConfiguration getConfiguration() {
47 return configuration;
48 }
49
50 /**
schmitt3e770242019-04-22 14:12:24 -070051 * Creates a new configuration key based on the given diff, after applying a platform mapping
52 * transformation.
53 *
54 * @param platformMappingValue sky value that can transform a configuration key based on a
55 * platform mapping
56 * @param defaultBuildOptions set of native build options without modifications based on parsing
57 * flags
58 * @param fragments set of options fragments this configuration should cover
59 * @param optionsDiff diff between the default options and the desired configuration
60 * @throws OptionsParsingException if the platform mapping cannot be parsed
61 */
62 public static Key keyWithPlatformMapping(
63 PlatformMappingValue platformMappingValue,
64 BuildOptions defaultBuildOptions,
65 FragmentClassSet fragments,
66 BuildOptions.OptionsDiffForReconstruction optionsDiff)
67 throws OptionsParsingException {
68 return platformMappingValue.map(
69 keyWithoutPlatformMapping(fragments, optionsDiff), defaultBuildOptions);
70 }
71
72 /**
73 * Creates a new configuration key based on the given diff, after applying a platform mapping
74 * transformation.
75 *
76 * @param platformMappingValue sky value that can transform a configuration key based on a
77 * platform mapping
78 * @param defaultBuildOptions set of native build options without modifications based on parsing
79 * flags
80 * @param fragments set of options fragments this configuration should cover
81 * @param optionsDiff diff between the default options and the desired configuration
82 * @throws OptionsParsingException if the platform mapping cannot be parsed
83 */
84 public static Key keyWithPlatformMapping(
85 PlatformMappingValue platformMappingValue,
86 BuildOptions defaultBuildOptions,
87 Set<Class<? extends BuildConfiguration.Fragment>> fragments,
88 BuildOptions.OptionsDiffForReconstruction optionsDiff)
89 throws OptionsParsingException {
90 return platformMappingValue.map(
91 keyWithoutPlatformMapping(fragments, optionsDiff), defaultBuildOptions);
92 }
93
94 /**
Greg Estren531fc042015-05-26 22:37:44 +000095 * Returns the key for a requested configuration.
96 *
schmitt3e770242019-04-22 14:12:24 -070097 * <p>Callers are responsible for applying the platform mapping or ascertaining that a platform
98 * mapping is not required.
99 *
Greg Estren531fc042015-05-26 22:37:44 +0000100 * @param fragments the fragments the configuration should contain
mjhalupka5d7fa7b2018-03-22 13:37:38 -0700101 * @param optionsDiff the {@link BuildOptions.OptionsDiffForReconstruction} object the {@link
102 * BuildOptions} should be rebuilt from
Greg Estren531fc042015-05-26 22:37:44 +0000103 */
104 @ThreadSafe
schmitt3e770242019-04-22 14:12:24 -0700105 static Key keyWithoutPlatformMapping(
mjhalupka5d7fa7b2018-03-22 13:37:38 -0700106 Set<Class<? extends BuildConfiguration.Fragment>> fragments,
107 BuildOptions.OptionsDiffForReconstruction optionsDiff) {
janakr129c3e22018-07-27 10:50:45 -0700108 return Key.create(
janakra39a5622018-01-24 08:43:35 -0800109 FragmentClassSet.of(
110 ImmutableSortedSet.copyOf(BuildConfiguration.lexicalFragmentSorter, fragments)),
mjhalupka5d7fa7b2018-03-22 13:37:38 -0700111 optionsDiff);
janakra39a5622018-01-24 08:43:35 -0800112 }
113
schmitt3e770242019-04-22 14:12:24 -0700114 private static Key keyWithoutPlatformMapping(
mjhalupka5d7fa7b2018-03-22 13:37:38 -0700115 FragmentClassSet fragmentClassSet, BuildOptions.OptionsDiffForReconstruction optionsDiff) {
116 return Key.create(fragmentClassSet, optionsDiff);
Greg Estren531fc042015-05-26 22:37:44 +0000117 }
118
schmitt3e770242019-04-22 14:12:24 -0700119 /**
120 * Returns a configuration key for the given configuration.
121 *
122 * <p>Note that this key creation method does not apply a platform mapping, it is assumed that the
123 * passed configuration was created with one such and thus its key does not need to be mapped
124 * again.
125 *
126 * @param buildConfiguration configuration whose key is requested
127 */
janakr9c4fa4a2018-03-28 11:37:34 -0700128 public static Key key(BuildConfiguration buildConfiguration) {
schmitt3e770242019-04-22 14:12:24 -0700129 return keyWithoutPlatformMapping(
130 buildConfiguration.fragmentClasses(), buildConfiguration.getBuildOptionsDiff());
janakr9c4fa4a2018-03-28 11:37:34 -0700131 }
132
janakr269d9bd2018-01-24 10:15:56 -0800133 /** {@link SkyKey} for {@link BuildConfigurationValue}. */
janakr129c3e22018-07-27 10:50:45 -0700134 @AutoCodec
janakr269d9bd2018-01-24 10:15:56 -0800135 public static final class Key implements SkyKey, Serializable {
mjhalupka5d7fa7b2018-03-22 13:37:38 -0700136 private static final Interner<Key> keyInterner = BlazeInterners.newWeakInterner();
137
janakra39a5622018-01-24 08:43:35 -0800138 private final FragmentClassSet fragments;
janakr129c3e22018-07-27 10:50:45 -0700139 final BuildOptions.OptionsDiffForReconstruction optionsDiff;
janakr29bd80d2017-12-28 12:59:48 -0800140 // If hashCode really is -1, we'll recompute it from scratch each time. Oh well.
141 private volatile int hashCode = -1;
Greg Estren531fc042015-05-26 22:37:44 +0000142
janakr129c3e22018-07-27 10:50:45 -0700143 @AutoCodec.Instantiator
144 @VisibleForSerialization
145 static Key create(
mjhalupka5d7fa7b2018-03-22 13:37:38 -0700146 FragmentClassSet fragments, BuildOptions.OptionsDiffForReconstruction optionsDiff) {
147 return keyInterner.intern(new Key(fragments, optionsDiff));
148 }
149
janakr56d78522018-03-28 09:58:15 -0700150 private Key(FragmentClassSet fragments, BuildOptions.OptionsDiffForReconstruction optionsDiff) {
Greg Estren531fc042015-05-26 22:37:44 +0000151 this.fragments = fragments;
mjhalupka5d7fa7b2018-03-22 13:37:38 -0700152 this.optionsDiff = optionsDiff;
Greg Estren531fc042015-05-26 22:37:44 +0000153 }
154
janakr171a7eb2018-03-26 09:26:53 -0700155 @VisibleForTesting
156 public ImmutableSortedSet<Class<? extends BuildConfiguration.Fragment>> getFragments() {
janakra39a5622018-01-24 08:43:35 -0800157 return fragments.fragmentClasses();
Greg Estren531fc042015-05-26 22:37:44 +0000158 }
159
janakr56d78522018-03-28 09:58:15 -0700160 public BuildOptions.OptionsDiffForReconstruction getOptionsDiff() {
mjhalupka5d7fa7b2018-03-22 13:37:38 -0700161 return optionsDiff;
Greg Estren531fc042015-05-26 22:37:44 +0000162 }
163
Greg Estren531fc042015-05-26 22:37:44 +0000164 @Override
janakr34e1b3c2017-12-20 14:27:55 -0800165 public SkyFunctionName functionName() {
166 return SkyFunctions.BUILD_CONFIGURATION;
167 }
168
169 @Override
Greg Estren531fc042015-05-26 22:37:44 +0000170 public boolean equals(Object o) {
janakr29bd80d2017-12-28 12:59:48 -0800171 if (this == o) {
172 return true;
173 }
Greg Estren531fc042015-05-26 22:37:44 +0000174 if (!(o instanceof Key)) {
175 return false;
176 }
177 Key otherConfig = (Key) o;
mjhalupka5d7fa7b2018-03-22 13:37:38 -0700178 return optionsDiff.equals(otherConfig.optionsDiff)
janakr534191b2018-01-11 12:24:49 -0800179 && Objects.equals(fragments, otherConfig.fragments);
Greg Estren531fc042015-05-26 22:37:44 +0000180 }
181
182 @Override
183 public int hashCode() {
janakr29bd80d2017-12-28 12:59:48 -0800184 if (hashCode == -1) {
mjhalupka5d7fa7b2018-03-22 13:37:38 -0700185 hashCode = Objects.hash(fragments, optionsDiff);
janakr29bd80d2017-12-28 12:59:48 -0800186 }
187 return hashCode;
Greg Estren531fc042015-05-26 22:37:44 +0000188 }
janakr192c8902018-01-19 22:29:42 -0800189
mjhalupka6febc732018-04-11 11:23:44 -0700190 @Override
191 public String toString() {
shahana9612662018-05-17 07:54:17 -0700192 return "BuildConfigurationValue.Key[" + optionsDiff.getChecksum() + "]";
mjhalupka6febc732018-04-11 11:23:44 -0700193 }
janakr52177122018-05-14 12:06:36 -0700194 }
Greg Estren531fc042015-05-26 22:37:44 +0000195}