blob: b869acef828567edb7406a642748e3a03a4e1d5f [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
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.analysis;
15
Googler58505032015-03-19 16:12:34 +000016import static com.google.common.base.Preconditions.checkArgument;
17import static com.google.common.base.Preconditions.checkNotNull;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010018import static com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType.ABSTRACT;
19import static com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType.TEST;
20
mstaib4a07a472018-04-19 14:16:41 -070021import com.google.common.annotations.VisibleForTesting;
Ulf Adams345e15e2016-07-07 13:27:28 +000022import com.google.common.base.Preconditions;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010023import com.google.common.collect.ImmutableList;
24import com.google.common.collect.ImmutableMap;
lberki406199f2018-04-09 03:16:19 -070025import com.google.common.collect.ImmutableSet;
janakr9fcef032018-01-23 13:38:24 -080026import com.google.common.collect.ImmutableSortedSet;
lberki86266232018-04-11 00:33:42 -070027import com.google.devtools.build.lib.actions.ActionEnvironment;
jcater0de10972020-04-07 12:15:05 -070028import com.google.devtools.build.lib.analysis.RuleContext.PrerequisiteValidator;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010029import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory;
jcater1865d892020-04-14 10:04:29 -070030import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoKey;
Greg Estrenc5a352f2015-11-13 17:25:36 +000031import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010032import com.google.devtools.build.lib.analysis.config.BuildOptions;
brandjon8a603602019-12-04 10:40:38 -080033import com.google.devtools.build.lib.analysis.config.ConvenienceSymlinks.SymlinkDefinition;
jcatera666f002020-04-14 14:55:20 -070034import com.google.devtools.build.lib.analysis.config.Fragment;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010035import com.google.devtools.build.lib.analysis.config.FragmentOptions;
jcaterfad3cda2020-04-15 10:48:19 -070036import com.google.devtools.build.lib.analysis.config.FragmentProvider;
John Caterb3b3e8b2019-04-03 09:18:42 -070037import com.google.devtools.build.lib.analysis.config.transitions.ComposingTransitionFactory;
gregce477d9652019-06-05 13:40:21 -070038import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
John Caterb3b3e8b2019-04-03 09:18:42 -070039import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory;
gregce6acfe4e2018-05-25 08:38:39 -070040import com.google.devtools.build.lib.analysis.constraints.ConstraintSemantics;
jcater802551e2020-04-15 09:59:58 -070041import com.google.devtools.build.lib.analysis.constraints.RuleContextConstraintSemantics;
gregceeefc91c2020-06-19 13:33:43 -070042import com.google.devtools.build.lib.analysis.starlark.StarlarkModules;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000043import com.google.devtools.build.lib.cmdline.Label;
Lukacs Berkia6434362015-09-15 13:56:14 +000044import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
dannarkd102a392019-01-09 13:12:01 -080045import com.google.devtools.build.lib.cmdline.RepositoryName;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010046import com.google.devtools.build.lib.graph.Digraph;
47import com.google.devtools.build.lib.graph.Node;
Googler995ef632019-09-04 12:25:41 -070048import com.google.devtools.build.lib.packages.BazelStarlarkContext;
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +000049import com.google.devtools.build.lib.packages.NativeAspectClass;
Michael Staib8618b9d2016-09-16 19:36:49 +000050import com.google.devtools.build.lib.packages.Rule;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010051import com.google.devtools.build.lib.packages.RuleClass;
gregce4aa059a2019-02-26 13:20:47 -080052import com.google.devtools.build.lib.packages.RuleClass.Builder.ThirdPartyLicenseExistencePolicy;
Googler995ef632019-09-04 12:25:41 -070053import com.google.devtools.build.lib.packages.SymbolGenerator;
gregcecf3a9232020-07-20 15:17:52 -070054import com.google.devtools.build.lib.starlarkbuildapi.core.Bootstrap;
mstaib2d7c0ff2019-02-28 08:28:11 -080055import com.google.devtools.common.options.Option;
mstaib6cf62782018-11-14 11:54:33 -080056import com.google.devtools.common.options.OptionDefinition;
juliexxia618a0762018-08-17 08:33:52 -070057import com.google.devtools.common.options.OptionsProvider;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010058import java.lang.reflect.Constructor;
mstaib2d7c0ff2019-02-28 08:28:11 -080059import java.lang.reflect.Field;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010060import java.lang.reflect.InvocationTargetException;
61import java.util.ArrayList;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010062import java.util.HashMap;
mstaib2d7c0ff2019-02-28 08:28:11 -080063import java.util.LinkedHashMap;
gregced6aa04d2019-01-02 12:42:28 -080064import java.util.LinkedHashSet;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010065import java.util.List;
66import java.util.Map;
lberki406199f2018-04-09 03:16:19 -070067import java.util.Set;
68import java.util.TreeSet;
mstaib4a07a472018-04-19 14:16:41 -070069import javax.annotation.Nullable;
adonovanb63c0f22020-10-14 13:01:18 -070070import net.starlark.java.annot.StarlarkAnnotations;
adonovanb0174682020-05-18 16:01:53 -070071import net.starlark.java.annot.StarlarkBuiltin;
adonovan450c7ad2020-09-14 13:00:21 -070072import net.starlark.java.eval.StarlarkThread;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010073
74/**
75 * Knows about every rule Blaze supports and the associated configuration options.
76 *
Googlerbffb6872019-10-22 11:14:46 -070077 * <p>This class is initialized on server startup and the set of rules, build info factories and
78 * configuration options is guaranteed not to change over the life time of the Blaze server.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010079 */
Googlerbffb6872019-10-22 11:14:46 -070080// This class has no subclasses except those created by the evil that is mockery.
jcaterfad3cda2020-04-15 10:48:19 -070081public /*final*/ class ConfiguredRuleClassProvider implements FragmentProvider {
Kristina Chodorow8612a272015-12-14 15:37:24 +000082
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010083 /**
Ulf Adamse3b4af22016-10-18 12:51:15 +000084 * A coherent set of options, fragments, aspects and rules; each of these may declare a dependency
85 * on other such sets.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010086 */
brandjon32d359f2018-01-22 10:50:45 -080087 public interface RuleSet {
Ulf Adamse3b4af22016-10-18 12:51:15 +000088 /** Add stuff to the configured rule class provider builder. */
89 void init(ConfiguredRuleClassProvider.Builder builder);
90
91 /** List of required modules. */
92 ImmutableList<RuleSet> requires();
93 }
94
95 /** Builder for {@link ConfiguredRuleClassProvider}. */
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010096 public static class Builder implements RuleDefinitionEnvironment {
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +000097 private final StringBuilder defaultWorkspaceFilePrefix = new StringBuilder();
98 private final StringBuilder defaultWorkspaceFileSuffix = new StringBuilder();
John Fielda97e17f2015-11-13 02:19:52 +000099 private Label preludeLabel;
Ulf Adamsd13207c2015-09-04 14:53:43 +0000100 private String runfilesPrefix;
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000101 private String toolsRepository;
brandjon39ca7272020-12-03 14:40:09 -0800102 private String builtinsPackagePathInSource;
gregce4ed65b02020-11-18 07:06:25 -0800103 private final List<Class<? extends Fragment>> configurationFragmentClasses = new ArrayList<>();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100104 private final List<BuildInfoFactory> buildInfoFactories = new ArrayList<>();
gregced6aa04d2019-01-02 12:42:28 -0800105 private final Set<Class<? extends FragmentOptions>> configurationOptions =
106 new LinkedHashSet<>();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100107
108 private final Map<String, RuleClass> ruleClassMap = new HashMap<>();
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000109 private final Map<String, RuleDefinition> ruleDefinitionMap = new HashMap<>();
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000110 private final Map<String, NativeAspectClass> nativeAspectClassMap =
Dmitry Lomove2033b12015-08-19 16:57:49 +0000111 new HashMap<>();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100112 private final Map<Class<? extends RuleDefinition>, RuleClass> ruleMap = new HashMap<>();
113 private final Digraph<Class<? extends RuleDefinition>> dependencyGraph =
114 new Digraph<>();
brandjon79712cb2019-12-04 10:01:17 -0800115 private final List<Class<? extends Fragment>> universalFragments = new ArrayList<>();
gregce477d9652019-06-05 13:40:21 -0700116 @Nullable private TransitionFactory<Rule> trimmingTransitionFactory = null;
117 @Nullable private PatchTransition toolchainTaggedTrimmingTransition = null;
mstaib6cf62782018-11-14 11:54:33 -0800118 private OptionsDiffPredicate shouldInvalidateCacheForOptionDiff =
mstaiba9b55852018-06-18 13:37:49 -0700119 OptionsDiffPredicate.ALWAYS_INVALIDATE;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100120 private PrerequisiteValidator prerequisiteValidator;
gregce47a99f32020-05-13 12:35:26 -0700121 private final ImmutableList.Builder<Bootstrap> starlarkBootstraps = ImmutableList.builder();
122 private ImmutableMap.Builder<String, Object> starlarkAccessibleTopLevels =
Ulf Adamsfd53b612016-07-06 07:23:59 +0000123 ImmutableMap.builder();
brandjon8a603602019-12-04 10:40:38 -0800124 private final ImmutableList.Builder<SymlinkDefinition> symlinkDefinitions =
125 ImmutableList.builder();
lberki406199f2018-04-09 03:16:19 -0700126 private Set<String> reservedActionMnemonics = new TreeSet<>();
lberki86266232018-04-11 00:33:42 -0700127 private BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider =
128 (BuildOptions options) -> ActionEnvironment.EMPTY;
jcater802551e2020-04-15 09:59:58 -0700129 private ConstraintSemantics<RuleContext> constraintSemantics =
130 new RuleContextConstraintSemantics();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100131
gregce4aa059a2019-02-26 13:20:47 -0800132 private ThirdPartyLicenseExistencePolicy thirdPartyLicenseExistencePolicy =
133 ThirdPartyLicenseExistencePolicy.USER_CONTROLLABLE;
jcater0321a152019-07-08 12:47:19 -0700134 private boolean enableExecutionTransition = false;
gregce4aa059a2019-02-26 13:20:47 -0800135
cpeysera7f8a912017-11-06 23:10:36 +0100136 public Builder addWorkspaceFilePrefix(String contents) {
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000137 defaultWorkspaceFilePrefix.append(contents);
cpeysera7f8a912017-11-06 23:10:36 +0100138 return this;
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000139 }
140
cpeysera7f8a912017-11-06 23:10:36 +0100141 public Builder addWorkspaceFileSuffix(String contents) {
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000142 defaultWorkspaceFileSuffix.append(contents);
cpeysera7f8a912017-11-06 23:10:36 +0100143 return this;
Kristina Chodorowbc4b4b12015-02-11 15:54:50 +0000144 }
145
Klaus Aehliga55714c2018-10-23 02:16:02 -0700146 @VisibleForTesting
147 public Builder clearWorkspaceFileSuffixForTesting() {
148 defaultWorkspaceFileSuffix.delete(0, defaultWorkspaceFileSuffix.length());
149 return this;
150 }
151
John Fielda97e17f2015-11-13 02:19:52 +0000152 public Builder setPrelude(String preludeLabelString) {
153 try {
dannark90e2b4b2018-06-27 13:35:04 -0700154 this.preludeLabel = Label.parseAbsolute(preludeLabelString, ImmutableMap.of());
John Fielda97e17f2015-11-13 02:19:52 +0000155 } catch (LabelSyntaxException e) {
156 String errorMsg =
157 String.format("Prelude label '%s' is invalid: %s", preludeLabelString, e.getMessage());
158 throw new IllegalArgumentException(errorMsg);
159 }
Ulf Adamsfdfdd922015-09-01 08:36:29 +0000160 return this;
161 }
162
Ulf Adamsd13207c2015-09-04 14:53:43 +0000163 public Builder setRunfilesPrefix(String runfilesPrefix) {
164 this.runfilesPrefix = runfilesPrefix;
165 return this;
166 }
Luis Fernando Pino Duque18d13222016-02-08 14:55:28 +0000167
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000168 public Builder setToolsRepository(String toolsRepository) {
169 this.toolsRepository = toolsRepository;
170 return this;
171 }
Ulf Adamsd13207c2015-09-04 14:53:43 +0000172
brandjon39ca7272020-12-03 14:40:09 -0800173 // This is required if the rule class provider will be used with
174 // "--experimental_builtins_bzl_path=%workspace%", but can be skipped in unit tests.
175 public Builder setBuiltinsPackagePathInSource(String path) {
176 this.builtinsPackagePathInSource = path;
177 return this;
178 }
179
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100180 public Builder setPrerequisiteValidator(PrerequisiteValidator prerequisiteValidator) {
181 this.prerequisiteValidator = prerequisiteValidator;
182 return this;
183 }
184
185 public Builder addBuildInfoFactory(BuildInfoFactory factory) {
186 buildInfoFactories.add(factory);
187 return this;
188 }
189
Googler58505032015-03-19 16:12:34 +0000190 public Builder addRuleDefinition(RuleDefinition ruleDefinition) {
191 Class<? extends RuleDefinition> ruleDefinitionClass = ruleDefinition.getClass();
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000192 ruleDefinitionMap.put(ruleDefinitionClass.getName(), ruleDefinition);
Googler58505032015-03-19 16:12:34 +0000193 dependencyGraph.createNode(ruleDefinitionClass);
194 for (Class<? extends RuleDefinition> ancestor : ruleDefinition.getMetadata().ancestors()) {
195 dependencyGraph.addEdge(ancestor, ruleDefinitionClass);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100196 }
197
198 return this;
199 }
200
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000201 public Builder addNativeAspectClass(NativeAspectClass aspectFactoryClass) {
202 nativeAspectClassMap.put(aspectFactoryClass.getName(), aspectFactoryClass);
Dmitry Lomove2033b12015-08-19 16:57:49 +0000203 return this;
204 }
205
Ulf Adamsbbcfa2f2016-10-18 07:24:13 +0000206 /**
gregce4ed65b02020-11-18 07:06:25 -0800207 * Adds a configuration fragment and all build options required by its fragment.
cparsonscaceacd2017-11-04 01:00:59 +0100208 *
gregceca48e9a2020-04-14 08:54:38 -0700209 * <p>Note that configuration fragments annotated with a Starlark name must have a unique name;
gregced6aa04d2019-01-02 12:42:28 -0800210 * no two different configuration fragments can share the same name.
cparsonscaceacd2017-11-04 01:00:59 +0100211 */
gregce4ed65b02020-11-18 07:06:25 -0800212 public Builder addConfigurationFragment(Class<? extends Fragment> fragmentClass) {
213 this.configurationOptions.addAll(Fragment.requiredOptions(fragmentClass));
214 configurationFragmentClasses.add(fragmentClass);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100215 return this;
216 }
217
gregced6aa04d2019-01-02 12:42:28 -0800218 /**
219 * Adds configuration options that aren't required by configuration fragments.
220 *
gregce4ed65b02020-11-18 07:06:25 -0800221 * <p>If {@link #addConfigurationFragment} adds a fragment that also requires these options,
222 * this method is redundant.
gregced6aa04d2019-01-02 12:42:28 -0800223 */
224 public Builder addConfigurationOptions(Class<? extends FragmentOptions> configurationOptions) {
225 this.configurationOptions.add(configurationOptions);
226 return this;
227 }
228
brandjon79712cb2019-12-04 10:01:17 -0800229 public Builder addUniversalConfigurationFragment(Class<? extends Fragment> fragment) {
lberki78651d42018-04-06 01:52:58 -0700230 this.universalFragments.add(fragment);
Greg Estrenc5a352f2015-11-13 17:25:36 +0000231 return this;
232 }
233
gregce47a99f32020-05-13 12:35:26 -0700234 public Builder addStarlarkBootstrap(Bootstrap bootstrap) {
235 this.starlarkBootstraps.add(bootstrap);
cparsonsfc474542018-06-01 12:05:28 -0700236 return this;
237 }
238
gregce47a99f32020-05-13 12:35:26 -0700239 public Builder addStarlarkAccessibleTopLevels(String name, Object object) {
240 this.starlarkAccessibleTopLevels.put(name, object);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100241 return this;
242 }
243
brandjon8a603602019-12-04 10:40:38 -0800244 public Builder addSymlinkDefinition(SymlinkDefinition symlinkDefinition) {
245 this.symlinkDefinitions.add(symlinkDefinition);
246 return this;
247 }
248
lberki406199f2018-04-09 03:16:19 -0700249 public Builder addReservedActionMnemonic(String mnemonic) {
250 this.reservedActionMnemonics.add(mnemonic);
251 return this;
252 }
253
lberki86266232018-04-11 00:33:42 -0700254 public Builder setActionEnvironmentProvider(
255 BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider) {
256 this.actionEnvironmentProvider = actionEnvironmentProvider;
257 return this;
258 }
259
Cal Peyserf296e872016-05-03 17:36:54 +0000260 /**
gregce6acfe4e2018-05-25 08:38:39 -0700261 * Sets the logic that lets rules declare which environments they support and validates rules
262 * don't depend on rules that aren't compatible with the same environments. Defaults to
263 * {@ConstraintSemantics}. See {@ConstraintSemantics} for more details.
264 */
jcater802551e2020-04-15 09:59:58 -0700265 public Builder setConstraintSemantics(ConstraintSemantics<RuleContext> constraintSemantics) {
gregce6acfe4e2018-05-25 08:38:39 -0700266 this.constraintSemantics = constraintSemantics;
267 return this;
268 }
269
270 /**
gregce4aa059a2019-02-26 13:20:47 -0800271 * Sets the policy for checking if third_party rules declare <code>licenses()</code>. See {@link
272 * #thirdPartyLicenseExistencePolicy} for the default value.
273 */
274 public Builder setThirdPartyLicenseExistencePolicy(ThirdPartyLicenseExistencePolicy policy) {
275 this.thirdPartyLicenseExistencePolicy = policy;
276 return this;
277 }
278
279 /**
mstaibe59cbd02018-06-01 15:23:00 -0700280 * Adds a transition factory that produces a trimming transition to be run over all targets
mstaib4a07a472018-04-19 14:16:41 -0700281 * after other transitions.
282 *
mstaibe59cbd02018-06-01 15:23:00 -0700283 * <p>Transitions are run in the order they're added.
284 *
285 * <p>This is a temporary measure for supporting trimming of test rules and manual trimming of
286 * feature flags, and support for this transition factory will likely be removed at some point
287 * in the future (whenever automatic trimming is sufficiently workable).
mstaib4a07a472018-04-19 14:16:41 -0700288 */
John Caterb3b3e8b2019-04-03 09:18:42 -0700289 public Builder addTrimmingTransitionFactory(TransitionFactory<Rule> factory) {
290 Preconditions.checkNotNull(factory);
291 Preconditions.checkArgument(!factory.isSplit());
mstaibe59cbd02018-06-01 15:23:00 -0700292 if (trimmingTransitionFactory == null) {
John Caterb3b3e8b2019-04-03 09:18:42 -0700293 trimmingTransitionFactory = factory;
mstaibe59cbd02018-06-01 15:23:00 -0700294 } else {
John Caterb3b3e8b2019-04-03 09:18:42 -0700295 trimmingTransitionFactory =
296 ComposingTransitionFactory.of(trimmingTransitionFactory, factory);
mstaibe59cbd02018-06-01 15:23:00 -0700297 }
mstaib4a07a472018-04-19 14:16:41 -0700298 return this;
299 }
300
gregce477d9652019-06-05 13:40:21 -0700301 /** Sets the transition manual feature flag trimming should apply to toolchain deps. */
302 public Builder setToolchainTaggedTrimmingTransition(PatchTransition transition) {
303 Preconditions.checkNotNull(transition);
304 Preconditions.checkState(toolchainTaggedTrimmingTransition == null);
305 this.toolchainTaggedTrimmingTransition = transition;
306 return this;
307 }
308
mstaib4a07a472018-04-19 14:16:41 -0700309 /**
310 * Overrides the transition factory run over all targets.
311 *
John Caterb3b3e8b2019-04-03 09:18:42 -0700312 * @see {@link #addTrimmingTransitionFactory(TransitionFactory<Rule>)}
mstaib4a07a472018-04-19 14:16:41 -0700313 */
hlopko8820d3a2018-06-15 09:10:05 -0700314 @VisibleForTesting(/* for testing trimming transition factories without relying on prod use */ )
John Caterb3b3e8b2019-04-03 09:18:42 -0700315 public Builder overrideTrimmingTransitionFactoryForTesting(TransitionFactory<Rule> factory) {
mstaib4a07a472018-04-19 14:16:41 -0700316 trimmingTransitionFactory = null;
mstaibe59cbd02018-06-01 15:23:00 -0700317 return this.addTrimmingTransitionFactory(factory);
mstaib4a07a472018-04-19 14:16:41 -0700318 }
319
mstaiba9b55852018-06-18 13:37:49 -0700320 /**
321 * Sets the predicate which determines whether the analysis cache should be invalidated for the
322 * given options diff.
323 */
mstaib6cf62782018-11-14 11:54:33 -0800324 public Builder setShouldInvalidateCacheForOptionDiff(
325 OptionsDiffPredicate shouldInvalidateCacheForOptionDiff) {
mstaiba9b55852018-06-18 13:37:49 -0700326 Preconditions.checkState(
mstaib6cf62782018-11-14 11:54:33 -0800327 this.shouldInvalidateCacheForOptionDiff.equals(OptionsDiffPredicate.ALWAYS_INVALIDATE),
mstaiba9b55852018-06-18 13:37:49 -0700328 "Cache invalidation function was already set");
mstaib6cf62782018-11-14 11:54:33 -0800329 this.shouldInvalidateCacheForOptionDiff = shouldInvalidateCacheForOptionDiff;
mstaiba9b55852018-06-18 13:37:49 -0700330 return this;
331 }
332
jcater0321a152019-07-08 12:47:19 -0700333 @Override
334 public boolean enableExecutionTransition() {
335 return enableExecutionTransition;
336 }
337
338 public Builder enableExecutionTransition(boolean flag) {
339 this.enableExecutionTransition = flag;
340 return this;
341 }
342
mstaiba9b55852018-06-18 13:37:49 -0700343 /**
344 * Overrides the predicate which determines whether the analysis cache should be invalidated for
345 * the given options diff.
346 */
347 @VisibleForTesting(/* for testing cache invalidation without relying on prod use */ )
mstaib6cf62782018-11-14 11:54:33 -0800348 public Builder overrideShouldInvalidateCacheForOptionDiffForTesting(
349 OptionsDiffPredicate shouldInvalidateCacheForOptionDiff) {
350 this.shouldInvalidateCacheForOptionDiff = OptionsDiffPredicate.ALWAYS_INVALIDATE;
351 return this.setShouldInvalidateCacheForOptionDiff(shouldInvalidateCacheForOptionDiff);
mstaiba9b55852018-06-18 13:37:49 -0700352 }
353
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100354 private RuleConfiguredTargetFactory createFactory(
355 Class<? extends RuleConfiguredTargetFactory> factoryClass) {
356 try {
357 Constructor<? extends RuleConfiguredTargetFactory> ctor = factoryClass.getConstructor();
358 return ctor.newInstance();
359 } catch (NoSuchMethodException | IllegalAccessException | InstantiationException
360 | InvocationTargetException e) {
361 throw new IllegalStateException(e);
362 }
363 }
364
365 private RuleClass commitRuleDefinition(Class<? extends RuleDefinition> definitionClass) {
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000366 RuleDefinition instance = checkNotNull(ruleDefinitionMap.get(definitionClass.getName()),
Googler58505032015-03-19 16:12:34 +0000367 "addRuleDefinition(new %s()) should be called before build()", definitionClass.getName());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100368
Googler58505032015-03-19 16:12:34 +0000369 RuleDefinition.Metadata metadata = instance.getMetadata();
lpino92cb8292017-10-27 14:38:10 +0200370 checkArgument(
371 ruleClassMap.get(metadata.name()) == null,
372 "The rule " + metadata.name() + " was committed already, use another name");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100373
Googler58505032015-03-19 16:12:34 +0000374 List<Class<? extends RuleDefinition>> ancestors = metadata.ancestors();
375
376 checkArgument(
377 metadata.type() == ABSTRACT ^ metadata.factoryClass()
378 != RuleConfiguredTargetFactory.class);
379 checkArgument(
380 (metadata.type() != TEST)
381 || ancestors.contains(BaseRuleClasses.TestBaseRule.class));
382
383 RuleClass[] ancestorClasses = new RuleClass[ancestors.size()];
384 for (int i = 0; i < ancestorClasses.length; i++) {
385 ancestorClasses[i] = ruleMap.get(ancestors.get(i));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100386 if (ancestorClasses[i] == null) {
387 // Ancestors should have been initialized by now
Googler58505032015-03-19 16:12:34 +0000388 throw new IllegalStateException("Ancestor " + ancestors.get(i) + " of "
389 + metadata.name() + " is not initialized");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100390 }
391 }
392
393 RuleConfiguredTargetFactory factory = null;
Googler58505032015-03-19 16:12:34 +0000394 if (metadata.type() != ABSTRACT) {
395 factory = createFactory(metadata.factoryClass());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100396 }
397
398 RuleClass.Builder builder = new RuleClass.Builder(
Googler58505032015-03-19 16:12:34 +0000399 metadata.name(), metadata.type(), false, ancestorClasses);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100400 builder.factory(factory);
gregce4aa059a2019-02-26 13:20:47 -0800401 builder.setThirdPartyLicenseExistencePolicy(thirdPartyLicenseExistencePolicy);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100402 RuleClass ruleClass = instance.build(builder, this);
403 ruleMap.put(definitionClass, ruleClass);
404 ruleClassMap.put(ruleClass.getName(), ruleClass);
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000405 ruleDefinitionMap.put(ruleClass.getName(), instance);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100406
407 return ruleClass;
408 }
409
410 public ConfiguredRuleClassProvider build() {
411 for (Node<Class<? extends RuleDefinition>> ruleDefinition :
Googler58505032015-03-19 16:12:34 +0000412 dependencyGraph.getTopologicalOrder()) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100413 commitRuleDefinition(ruleDefinition.getLabel());
414 }
415
416 return new ConfiguredRuleClassProvider(
John Fielda97e17f2015-11-13 02:19:52 +0000417 preludeLabel,
Ulf Adamsd13207c2015-09-04 14:53:43 +0000418 runfilesPrefix,
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000419 toolsRepository,
brandjon39ca7272020-12-03 14:40:09 -0800420 builtinsPackagePathInSource,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100421 ImmutableMap.copyOf(ruleClassMap),
422 ImmutableMap.copyOf(ruleDefinitionMap),
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000423 ImmutableMap.copyOf(nativeAspectClassMap),
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000424 defaultWorkspaceFilePrefix.toString(),
425 defaultWorkspaceFileSuffix.toString(),
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100426 ImmutableList.copyOf(buildInfoFactories),
427 ImmutableList.copyOf(configurationOptions),
gregce4ed65b02020-11-18 07:06:25 -0800428 ImmutableList.copyOf(configurationFragmentClasses),
lberki78651d42018-04-06 01:52:58 -0700429 ImmutableList.copyOf(universalFragments),
mstaib4a07a472018-04-19 14:16:41 -0700430 trimmingTransitionFactory,
gregce477d9652019-06-05 13:40:21 -0700431 toolchainTaggedTrimmingTransition,
mstaib6cf62782018-11-14 11:54:33 -0800432 shouldInvalidateCacheForOptionDiff,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100433 prerequisiteValidator,
gregce47a99f32020-05-13 12:35:26 -0700434 starlarkAccessibleTopLevels.build(),
435 starlarkBootstraps.build(),
brandjon8a603602019-12-04 10:40:38 -0800436 symlinkDefinitions.build(),
lberki406199f2018-04-09 03:16:19 -0700437 ImmutableSet.copyOf(reservedActionMnemonics),
gregce6acfe4e2018-05-25 08:38:39 -0700438 actionEnvironmentProvider,
gregce4aa059a2019-02-26 13:20:47 -0800439 constraintSemantics,
440 thirdPartyLicenseExistencePolicy);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100441 }
442
443 @Override
Luis Fernando Pino Duque18d13222016-02-08 14:55:28 +0000444 public Label getToolsLabel(String labelValue) {
janakrc19284e2018-06-20 15:22:33 -0700445 return Label.parseAbsoluteUnchecked(toolsRepository + labelValue);
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000446 }
Luis Fernando Pino Duque207ba4a2016-07-01 15:07:23 +0000447
448 @Override
449 public String getToolsRepository() {
450 return toolsRepository;
451 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100452 }
453
454 /**
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000455 * Default content that should be added at the beginning of the WORKSPACE file.
Kristina Chodorowbc4b4b12015-02-11 15:54:50 +0000456 */
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000457 private final String defaultWorkspaceFilePrefix;
458
459 /**
460 * Default content that should be added at the end of the WORKSPACE file.
461 */
462 private final String defaultWorkspaceFileSuffix;
463
Kristina Chodorowbc4b4b12015-02-11 15:54:50 +0000464
465 /**
John Fielda97e17f2015-11-13 02:19:52 +0000466 * Label for the prelude file.
Ulf Adamsfdfdd922015-09-01 08:36:29 +0000467 */
John Fielda97e17f2015-11-13 02:19:52 +0000468 private final Label preludeLabel;
Ulf Adamsfdfdd922015-09-01 08:36:29 +0000469
470 /**
Ulf Adamsd13207c2015-09-04 14:53:43 +0000471 * The default runfiles prefix.
472 */
473 private final String runfilesPrefix;
Luis Fernando Pino Duque18d13222016-02-08 14:55:28 +0000474
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000475 /**
476 * The path to the tools repository.
477 */
478 private final String toolsRepository;
Ulf Adamsd13207c2015-09-04 14:53:43 +0000479
brandjon39ca7272020-12-03 14:40:09 -0800480 /** The relative location of the builtins_bzl directory within a Bazel source tree. */
481 private final String builtinsPackagePathInSource;
482
Ulf Adamsd13207c2015-09-04 14:53:43 +0000483 /**
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100484 * Maps rule class name to the metaclass instance for that rule.
485 */
486 private final ImmutableMap<String, RuleClass> ruleClassMap;
487
488 /**
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000489 * Maps rule class name to the rule definition objects.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100490 */
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000491 private final ImmutableMap<String, RuleDefinition> ruleDefinitionMap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100492
493 /**
Dmitry Lomove2033b12015-08-19 16:57:49 +0000494 * Maps aspect name to the aspect factory meta class.
495 */
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000496 private final ImmutableMap<String, NativeAspectClass> nativeAspectClassMap;
Dmitry Lomove2033b12015-08-19 16:57:49 +0000497
498 /**
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100499 * The configuration options that affect the behavior of the rules.
500 */
501 private final ImmutableList<Class<? extends FragmentOptions>> configurationOptions;
502
Ulf Adams8d0be892016-10-14 13:56:46 +0000503 /** The set of configuration fragment factories. */
gregce4ed65b02020-11-18 07:06:25 -0800504 private final ImmutableList<Class<? extends Fragment>> configurationFragmentClasses;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100505
mstaib2d7c0ff2019-02-28 08:28:11 -0800506 /**
507 * Maps build option names to matching config fragments. This is used to determine correct
508 * fragment requirements for config_setting rules, which are unique in that their dependencies are
509 * triggered by string representations of option names.
510 */
511 private final Map<String, Class<? extends Fragment>> optionsToFragmentMap;
512
mstaib4a07a472018-04-19 14:16:41 -0700513 /** The transition factory used to produce the transition that will trim targets. */
John Caterb3b3e8b2019-04-03 09:18:42 -0700514 @Nullable private final TransitionFactory<Rule> trimmingTransitionFactory;
mstaib4a07a472018-04-19 14:16:41 -0700515
gregce477d9652019-06-05 13:40:21 -0700516 /** The transition to apply to toolchain deps for manual trimming. */
517 @Nullable private final PatchTransition toolchainTaggedTrimmingTransition;
518
mstaiba9b55852018-06-18 13:37:49 -0700519 /** The predicate used to determine whether a diff requires the cache to be invalidated. */
mstaib6cf62782018-11-14 11:54:33 -0800520 private final OptionsDiffPredicate shouldInvalidateCacheForOptionDiff;
mstaiba9b55852018-06-18 13:37:49 -0700521
gregce490b0952017-07-06 18:44:38 -0400522 /**
brandjon79712cb2019-12-04 10:01:17 -0800523 * Configuration fragments that should be available to all rules even when they don't explicitly
524 * require it.
Greg Estrenc5a352f2015-11-13 17:25:36 +0000525 */
brandjon79712cb2019-12-04 10:01:17 -0800526 private final ImmutableList<Class<? extends Fragment>> universalFragments;
Greg Estrenc5a352f2015-11-13 17:25:36 +0000527
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100528 private final ImmutableList<BuildInfoFactory> buildInfoFactories;
529
530 private final PrerequisiteValidator prerequisiteValidator;
531
brandjona0c6f812020-06-06 14:13:19 -0700532 private final ImmutableMap<String, Object> nativeRuleSpecificBindings;
533
Googlerbffb6872019-10-22 11:14:46 -0700534 private final ImmutableMap<String, Object> environment;
Janak Ramakrishnanb6e33bc2015-09-06 21:05:23 +0000535
brandjon8a603602019-12-04 10:40:38 -0800536 private final ImmutableList<SymlinkDefinition> symlinkDefinitions;
537
lberki406199f2018-04-09 03:16:19 -0700538 private final ImmutableSet<String> reservedActionMnemonics;
539
lberki86266232018-04-11 00:33:42 -0700540 private final BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider;
541
cparsonscaceacd2017-11-04 01:00:59 +0100542 private final ImmutableMap<String, Class<?>> configurationFragmentMap;
543
jcater802551e2020-04-15 09:59:58 -0700544 private final ConstraintSemantics<RuleContext> constraintSemantics;
gregce6acfe4e2018-05-25 08:38:39 -0700545
gregce4aa059a2019-02-26 13:20:47 -0800546 private final ThirdPartyLicenseExistencePolicy thirdPartyLicenseExistencePolicy;
547
Kristina Chodorow8612a272015-12-14 15:37:24 +0000548 private ConfiguredRuleClassProvider(
John Fielda97e17f2015-11-13 02:19:52 +0000549 Label preludeLabel,
Ulf Adamsd13207c2015-09-04 14:53:43 +0000550 String runfilesPrefix,
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000551 String toolsRepository,
brandjon39ca7272020-12-03 14:40:09 -0800552 String builtinsPackagePathInSource,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100553 ImmutableMap<String, RuleClass> ruleClassMap,
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000554 ImmutableMap<String, RuleDefinition> ruleDefinitionMap,
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000555 ImmutableMap<String, NativeAspectClass> nativeAspectClassMap,
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000556 String defaultWorkspaceFilePrefix,
557 String defaultWorkspaceFileSuffix,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100558 ImmutableList<BuildInfoFactory> buildInfoFactories,
559 ImmutableList<Class<? extends FragmentOptions>> configurationOptions,
gregce4ed65b02020-11-18 07:06:25 -0800560 ImmutableList<Class<? extends Fragment>> configurationFragmentClasses,
brandjon79712cb2019-12-04 10:01:17 -0800561 ImmutableList<Class<? extends Fragment>> universalFragments,
John Caterb3b3e8b2019-04-03 09:18:42 -0700562 @Nullable TransitionFactory<Rule> trimmingTransitionFactory,
gregce477d9652019-06-05 13:40:21 -0700563 PatchTransition toolchainTaggedTrimmingTransition,
mstaib6cf62782018-11-14 11:54:33 -0800564 OptionsDiffPredicate shouldInvalidateCacheForOptionDiff,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100565 PrerequisiteValidator prerequisiteValidator,
gregce47a99f32020-05-13 12:35:26 -0700566 ImmutableMap<String, Object> starlarkAccessibleJavaClasses,
567 ImmutableList<Bootstrap> starlarkBootstraps,
brandjon8a603602019-12-04 10:40:38 -0800568 ImmutableList<SymlinkDefinition> symlinkDefinitions,
lberki406199f2018-04-09 03:16:19 -0700569 ImmutableSet<String> reservedActionMnemonics,
gregce6acfe4e2018-05-25 08:38:39 -0700570 BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider,
jcater802551e2020-04-15 09:59:58 -0700571 ConstraintSemantics<RuleContext> constraintSemantics,
gregce4aa059a2019-02-26 13:20:47 -0800572 ThirdPartyLicenseExistencePolicy thirdPartyLicenseExistencePolicy) {
John Fielda97e17f2015-11-13 02:19:52 +0000573 this.preludeLabel = preludeLabel;
Ulf Adamsd13207c2015-09-04 14:53:43 +0000574 this.runfilesPrefix = runfilesPrefix;
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000575 this.toolsRepository = toolsRepository;
brandjon39ca7272020-12-03 14:40:09 -0800576 this.builtinsPackagePathInSource = builtinsPackagePathInSource;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100577 this.ruleClassMap = ruleClassMap;
578 this.ruleDefinitionMap = ruleDefinitionMap;
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000579 this.nativeAspectClassMap = nativeAspectClassMap;
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000580 this.defaultWorkspaceFilePrefix = defaultWorkspaceFilePrefix;
581 this.defaultWorkspaceFileSuffix = defaultWorkspaceFileSuffix;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100582 this.buildInfoFactories = buildInfoFactories;
583 this.configurationOptions = configurationOptions;
gregce4ed65b02020-11-18 07:06:25 -0800584 this.configurationFragmentClasses = configurationFragmentClasses;
585 this.optionsToFragmentMap = computeOptionsToFragmentMap(configurationFragmentClasses);
lberki78651d42018-04-06 01:52:58 -0700586 this.universalFragments = universalFragments;
mstaib4a07a472018-04-19 14:16:41 -0700587 this.trimmingTransitionFactory = trimmingTransitionFactory;
gregce477d9652019-06-05 13:40:21 -0700588 this.toolchainTaggedTrimmingTransition = toolchainTaggedTrimmingTransition;
mstaib6cf62782018-11-14 11:54:33 -0800589 this.shouldInvalidateCacheForOptionDiff = shouldInvalidateCacheForOptionDiff;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100590 this.prerequisiteValidator = prerequisiteValidator;
brandjona0c6f812020-06-06 14:13:19 -0700591 this.nativeRuleSpecificBindings =
592 createNativeRuleSpecificBindings(starlarkAccessibleJavaClasses, starlarkBootstraps);
593 this.environment = createEnvironment(nativeRuleSpecificBindings);
brandjon8a603602019-12-04 10:40:38 -0800594 this.symlinkDefinitions = symlinkDefinitions;
lberki406199f2018-04-09 03:16:19 -0700595 this.reservedActionMnemonics = reservedActionMnemonics;
lberki86266232018-04-11 00:33:42 -0700596 this.actionEnvironmentProvider = actionEnvironmentProvider;
gregce4ed65b02020-11-18 07:06:25 -0800597 this.configurationFragmentMap = createFragmentMap(configurationFragmentClasses);
gregce6acfe4e2018-05-25 08:38:39 -0700598 this.constraintSemantics = constraintSemantics;
gregce4aa059a2019-02-26 13:20:47 -0800599 this.thirdPartyLicenseExistencePolicy = thirdPartyLicenseExistencePolicy;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100600 }
601
mstaib2d7c0ff2019-02-28 08:28:11 -0800602 /**
603 * Computes the option name --> config fragments map. Note that this mapping is technically
604 * one-to-many: a single option may be required by multiple fragments (e.g. Java options are used
605 * by both JavaConfiguration and Jvm). In such cases, we arbitrarily choose one fragment since
606 * that's all that's needed to satisfy the config_setting.
607 */
608 private static Map<String, Class<? extends Fragment>> computeOptionsToFragmentMap(
gregce4ed65b02020-11-18 07:06:25 -0800609 ImmutableList<Class<? extends Fragment>> configurationFragments) {
mstaib2d7c0ff2019-02-28 08:28:11 -0800610 Map<String, Class<? extends Fragment>> result = new LinkedHashMap<>();
611 Map<Class<? extends FragmentOptions>, Integer> visitedOptionsClasses = new HashMap<>();
gregce4ed65b02020-11-18 07:06:25 -0800612 for (Class<? extends Fragment> fragment : configurationFragments) {
613 Set<Class<? extends FragmentOptions>> requiredOpts = Fragment.requiredOptions(fragment);
mstaib2d7c0ff2019-02-28 08:28:11 -0800614 for (Class<? extends FragmentOptions> optionsClass : requiredOpts) {
615 Integer previousBest = visitedOptionsClasses.get(optionsClass);
616 if (previousBest != null && previousBest <= requiredOpts.size()) {
617 // Multiple config fragments may require the same options class, but we only need one of
618 // them to guarantee that class makes it into the configuration. Pick one that depends
619 // on as few options classes as possible (not necessarily unique).
620 continue;
621 }
622 visitedOptionsClasses.put(optionsClass, requiredOpts.size());
623 for (Field field : optionsClass.getFields()) {
624 if (field.isAnnotationPresent(Option.class)) {
gregce4ed65b02020-11-18 07:06:25 -0800625 result.put(field.getAnnotation(Option.class).name(), fragment);
mstaib2d7c0ff2019-02-28 08:28:11 -0800626 }
627 }
628 }
629 }
630 return result;
631 }
632
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100633 public PrerequisiteValidator getPrerequisiteValidator() {
634 return prerequisiteValidator;
635 }
636
637 @Override
John Fielda97e17f2015-11-13 02:19:52 +0000638 public Label getPreludeLabel() {
639 return preludeLabel;
Ulf Adamsfdfdd922015-09-01 08:36:29 +0000640 }
641
642 @Override
Ulf Adamsd13207c2015-09-04 14:53:43 +0000643 public String getRunfilesPrefix() {
644 return runfilesPrefix;
645 }
Luis Fernando Pino Duque18d13222016-02-08 14:55:28 +0000646
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000647 @Override
648 public String getToolsRepository() {
649 return toolsRepository;
650 }
Ulf Adamsd13207c2015-09-04 14:53:43 +0000651
652 @Override
brandjon39ca7272020-12-03 14:40:09 -0800653 public String getBuiltinsPackagePathInSource() {
654 return builtinsPackagePathInSource;
655 }
656
657 @Override
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100658 public Map<String, RuleClass> getRuleClassMap() {
659 return ruleClassMap;
660 }
661
Dmitry Lomove2033b12015-08-19 16:57:49 +0000662 @Override
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000663 public Map<String, NativeAspectClass> getNativeAspectClassMap() {
664 return nativeAspectClassMap;
665 }
666
667 @Override
668 public NativeAspectClass getNativeAspectClass(String key) {
669 return nativeAspectClassMap.get(key);
Dmitry Lomove2033b12015-08-19 16:57:49 +0000670 }
671
ulfjack37407682019-09-17 06:30:49 -0700672 public Map<BuildInfoKey, BuildInfoFactory> getBuildInfoFactoriesAsMap() {
673 ImmutableMap.Builder<BuildInfoKey, BuildInfoFactory> factoryMapBuilder = ImmutableMap.builder();
674 for (BuildInfoFactory factory : buildInfoFactories) {
675 factoryMapBuilder.put(factory.getKey(), factory);
676 }
677 return factoryMapBuilder.build();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100678 }
679
David Ostrovskya1388772020-07-08 12:11:01 -0700680 /** Returns the set of configuration fragments provided by this module. */
681 @Override
gregce4ed65b02020-11-18 07:06:25 -0800682 public ImmutableList<Class<? extends Fragment>> getConfigurationFragments() {
683 return configurationFragmentClasses;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100684 }
685
mstaib2d7c0ff2019-02-28 08:28:11 -0800686 @Nullable
687 public Class<? extends Fragment> getConfigurationFragmentForOption(String requiredOption) {
688 return optionsToFragmentMap.get(requiredOption);
689 }
690
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100691 /**
mstaib4a07a472018-04-19 14:16:41 -0700692 * Returns the transition factory used to produce the transition to trim targets.
693 *
John Caterb3b3e8b2019-04-03 09:18:42 -0700694 * <p>This is a temporary measure for supporting manual trimming of feature flags, and support for
695 * this transition factory will likely be removed at some point in the future (whenever automatic
696 * trimming is sufficiently workable
mstaib4a07a472018-04-19 14:16:41 -0700697 */
698 @Nullable
John Caterb3b3e8b2019-04-03 09:18:42 -0700699 public TransitionFactory<Rule> getTrimmingTransitionFactory() {
mstaib4a07a472018-04-19 14:16:41 -0700700 return trimmingTransitionFactory;
701 }
702
gregce477d9652019-06-05 13:40:21 -0700703 /**
704 * Returns the transition manual feature flag trimming should apply to toolchain deps.
705 *
706 * <p>See extra notes on {@link #getTrimmingTransitionFactory()}.
707 */
708 @Nullable
709 public PatchTransition getToolchainTaggedTrimmingTransition() {
710 return toolchainTaggedTrimmingTransition;
711 }
712
mstaib6cf62782018-11-14 11:54:33 -0800713 /** Returns whether the analysis cache should be invalidated for the given option diff. */
714 public boolean shouldInvalidateCacheForOptionDiff(
715 BuildOptions newOptions, OptionDefinition changedOption, Object oldValue, Object newValue) {
716 return shouldInvalidateCacheForOptionDiff.apply(newOptions, changedOption, oldValue, newValue);
mstaiba9b55852018-06-18 13:37:49 -0700717 }
718
mstaib4a07a472018-04-19 14:16:41 -0700719 /**
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100720 * Returns the set of configuration options that are supported in this module.
721 */
722 public ImmutableList<Class<? extends FragmentOptions>> getConfigurationOptions() {
723 return configurationOptions;
724 }
725
726 /**
727 * Returns the definition of the rule class definition with the specified name.
728 */
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000729 public RuleDefinition getRuleClassDefinition(String ruleClassName) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100730 return ruleDefinitionMap.get(ruleClassName);
731 }
732
733 /**
brandjon79712cb2019-12-04 10:01:17 -0800734 * Returns the configuration fragment that should be available to all rules even when they don't
735 * explicitly require it.
Greg Estrenc5a352f2015-11-13 17:25:36 +0000736 */
brandjon79712cb2019-12-04 10:01:17 -0800737 public ImmutableList<Class<? extends Fragment>> getUniversalFragments() {
lberki78651d42018-04-06 01:52:58 -0700738 return universalFragments;
Greg Estrenc5a352f2015-11-13 17:25:36 +0000739 }
740
741 /**
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100742 * Creates a BuildOptions class for the given options taken from an optionsProvider.
743 */
juliexxia618a0762018-08-17 08:33:52 -0700744 public BuildOptions createBuildOptions(OptionsProvider optionsProvider) {
gregce9a3028c2017-07-26 00:19:10 +0200745 return BuildOptions.of(configurationOptions, optionsProvider);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100746 }
747
brandjona0c6f812020-06-06 14:13:19 -0700748 private static ImmutableMap<String, Object> createNativeRuleSpecificBindings(
gregce47a99f32020-05-13 12:35:26 -0700749 ImmutableMap<String, Object> starlarkAccessibleTopLevels,
cparsonsd2e0a942018-06-11 11:01:51 -0700750 ImmutableList<Bootstrap> bootstraps) {
brandjona0c6f812020-06-06 14:13:19 -0700751 ImmutableMap.Builder<String, Object> bindings = ImmutableMap.builder();
752 bindings.putAll(starlarkAccessibleTopLevels);
753 for (Bootstrap bootstrap : bootstraps) {
754 bootstrap.addBindingsToBuilder(bindings);
755 }
756 return bindings.build();
757 }
cparsonscf3e59d2018-05-23 10:01:20 -0700758
brandjona0c6f812020-06-06 14:13:19 -0700759 private static ImmutableMap<String, Object> createEnvironment(
760 ImmutableMap<String, Object> nativeRuleSpecificBindings) {
761 ImmutableMap.Builder<String, Object> envBuilder = ImmutableMap.builder();
adonovan09d13702020-05-19 08:26:55 -0700762 // Add predeclared symbols of the Bazel build language.
adonovan5a40ab62020-09-18 12:29:25 -0700763 StarlarkModules.addPredeclared(envBuilder);
brandjona0c6f812020-06-06 14:13:19 -0700764 // Add all the extensions registered with the rule class provider.
765 envBuilder.putAll(nativeRuleSpecificBindings);
Googlerbffb6872019-10-22 11:14:46 -0700766 return envBuilder.build();
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000767 }
768
cparsonscaceacd2017-11-04 01:00:59 +0100769 private static ImmutableMap<String, Class<?>> createFragmentMap(
gregce4ed65b02020-11-18 07:06:25 -0800770 Iterable<Class<? extends Fragment>> configurationFragments) {
cparsonscaceacd2017-11-04 01:00:59 +0100771 ImmutableMap.Builder<String, Class<?>> mapBuilder = ImmutableMap.builder();
gregce4ed65b02020-11-18 07:06:25 -0800772 for (Class<? extends Fragment> fragmentClass : configurationFragments) {
adonovanb63c0f22020-10-14 13:01:18 -0700773 StarlarkBuiltin fragmentModule = StarlarkAnnotations.getStarlarkBuiltin(fragmentClass);
cparsons14420542018-05-07 05:47:23 -0700774 if (fragmentModule != null) {
775 mapBuilder.put(fragmentModule.name(), fragmentClass);
cparsonscaceacd2017-11-04 01:00:59 +0100776 }
777 }
778 return mapBuilder.build();
779 }
780
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100781 @Override
brandjona0c6f812020-06-06 14:13:19 -0700782 public ImmutableMap<String, Object> getNativeRuleSpecificBindings() {
783 // Include rule-related stuff like CcInfo, but not core stuff like rule(). Essentially, this
784 // is intended to include things that could in principle be migrated to Starlark (and hence
brandjon5a33c632020-10-23 22:09:26 -0700785 // should be overridable by @_builtins); in practice it means anything specifically
786 // registered with the RuleClassProvider.
brandjona0c6f812020-06-06 14:13:19 -0700787 return nativeRuleSpecificBindings;
788 }
789
790 @Override
Googlerbffb6872019-10-22 11:14:46 -0700791 public ImmutableMap<String, Object> getEnvironment() {
792 return environment;
793 }
794
795 @Override
adonovan67741542020-05-08 11:37:13 -0700796 public void setStarlarkThreadContext(
797 StarlarkThread thread,
Googler7fa0dd22019-09-24 20:07:53 -0700798 Label fileLabel,
dannarkd102a392019-01-09 13:12:01 -0800799 ImmutableMap<RepositoryName, RepositoryName> repoMapping) {
Googler7fa0dd22019-09-24 20:07:53 -0700800 new BazelStarlarkContext(
adonovanb23b8c72019-12-12 11:42:14 -0800801 BazelStarlarkContext.Phase.LOADING,
Googler7fa0dd22019-09-24 20:07:53 -0700802 toolsRepository,
803 configurationFragmentMap,
804 repoMapping,
nharmatafecf56f2020-12-15 06:47:26 -0800805 /*convertedLabelsInPackage=*/ new HashMap<>(),
Googler7fa0dd22019-09-24 20:07:53 -0700806 new SymbolGenerator<>(fileLabel),
ajurkowski9f2cab52020-05-12 12:00:24 -0700807 /*analysisRuleLabel=*/ null)
Googlera3421e22019-09-26 06:48:32 -0700808 .storeInThread(thread);
Janak Ramakrishnanb6e33bc2015-09-06 21:05:23 +0000809 }
810
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000811 @Override
812 public String getDefaultWorkspacePrefix() {
813 return defaultWorkspaceFilePrefix;
814 }
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000815
Janak Ramakrishnanb6e33bc2015-09-06 21:05:23 +0000816 @Override
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000817 public String getDefaultWorkspaceSuffix() {
818 return defaultWorkspaceFileSuffix;
Kristina Chodorowbc4b4b12015-02-11 15:54:50 +0000819 }
Greg Estrenc396f9c2016-10-04 18:01:01 +0000820
cparsonscaceacd2017-11-04 01:00:59 +0100821 @Override
822 public Map<String, Class<?>> getConfigurationFragmentMap() {
823 return configurationFragmentMap;
824 }
825
brandjon8a603602019-12-04 10:40:38 -0800826 /**
827 * Returns the symlink definitions introduced by the fragments registered with this rule class
828 * provider.
829 *
830 * <p>This only includes definitions added by {@link #addSymlinkDefinition}, not the standard
831 * symlinks in {@link ConvenienceSymlinks#getStandardLinkDefinitions}.
832 *
833 * <p>Note: Usages of custom symlink definitions should be rare. Currently it is only used to
834 * implement the py2-bin / py3-bin symlinks.
835 */
836 public ImmutableList<SymlinkDefinition> getSymlinkDefinitions() {
837 return symlinkDefinitions;
838 }
839
jcater802551e2020-04-15 09:59:58 -0700840 public ConstraintSemantics<RuleContext> getConstraintSemantics() {
gregce6acfe4e2018-05-25 08:38:39 -0700841 return constraintSemantics;
842 }
843
gregce4aa059a2019-02-26 13:20:47 -0800844 @Override
845 public ThirdPartyLicenseExistencePolicy getThirdPartyLicenseExistencePolicy() {
846 return thirdPartyLicenseExistencePolicy;
847 }
848
brandjon79712cb2019-12-04 10:01:17 -0800849 /** Returns all registered {@link Fragment} classes. */
850 public ImmutableSortedSet<Class<? extends Fragment>> getAllFragments() {
851 ImmutableSortedSet.Builder<Class<? extends Fragment>> fragmentsBuilder =
janakr9fcef032018-01-23 13:38:24 -0800852 ImmutableSortedSet.orderedBy(BuildConfiguration.lexicalFragmentSorter);
gregce4ed65b02020-11-18 07:06:25 -0800853 fragmentsBuilder.addAll(getConfigurationFragments());
lberki78651d42018-04-06 01:52:58 -0700854 fragmentsBuilder.addAll(getUniversalFragments());
Greg Estrenc396f9c2016-10-04 18:01:01 +0000855 return fragmentsBuilder.build();
856 }
brandjon32d359f2018-01-22 10:50:45 -0800857
gregceca48e9a2020-04-14 08:54:38 -0700858 /** Returns a reserved set of action mnemonics. These cannot be used from a Starlark action. */
lberki406199f2018-04-09 03:16:19 -0700859 public ImmutableSet<String> getReservedActionMnemonics() {
860 return reservedActionMnemonics;
861 }
862
lberki86266232018-04-11 00:33:42 -0700863 public BuildConfiguration.ActionEnvironmentProvider getActionEnvironmentProvider() {
864 return actionEnvironmentProvider;
865 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100866}