blob: e335ceaa7157fc8b403d59957f824ff3a7c17bcd [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
16import static com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment;
17
18import com.google.common.collect.ClassToInstanceMap;
19import com.google.common.collect.ImmutableSet;
20import com.google.common.collect.MutableClassToInstanceMap;
21import com.google.devtools.build.lib.analysis.BlazeDirectories;
Greg Estren00049432015-08-25 16:43:47 +000022import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
Greg Estren531fc042015-05-26 22:37:44 +000023import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
24import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
Greg Estren00049432015-08-25 16:43:47 +000025import com.google.devtools.build.lib.packages.RuleClassProvider;
Greg Estren531fc042015-05-26 22:37:44 +000026import com.google.devtools.build.skyframe.SkyFunction;
27import com.google.devtools.build.skyframe.SkyFunctionException;
28import com.google.devtools.build.skyframe.SkyKey;
29import com.google.devtools.build.skyframe.SkyValue;
30import com.google.devtools.build.skyframe.ValueOrException;
Greg Estren531fc042015-05-26 22:37:44 +000031import java.util.LinkedHashSet;
32import java.util.Map;
33import java.util.Set;
34
35/**
36 * A builder for {@link BuildConfigurationValue} instances.
37 */
38public class BuildConfigurationFunction implements SkyFunction {
39
40 private final BlazeDirectories directories;
gregce490b0952017-07-06 18:44:38 -040041 private final ConfiguredRuleClassProvider ruleClassProvider;
Greg Estren531fc042015-05-26 22:37:44 +000042
Greg Estren00049432015-08-25 16:43:47 +000043 public BuildConfigurationFunction(BlazeDirectories directories,
44 RuleClassProvider ruleClassProvider) {
Greg Estren531fc042015-05-26 22:37:44 +000045 this.directories = directories;
gregce490b0952017-07-06 18:44:38 -040046 this.ruleClassProvider = (ConfiguredRuleClassProvider) ruleClassProvider;
Greg Estren531fc042015-05-26 22:37:44 +000047 }
48
49 @Override
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +000050 public SkyValue compute(SkyKey skyKey, Environment env)
51 throws InterruptedException, BuildConfigurationFunctionException {
kchodorow85ae1902017-04-22 15:07:22 -040052 WorkspaceNameValue workspaceNameValue = (WorkspaceNameValue) env
53 .getValue(WorkspaceNameValue.key());
54 if (workspaceNameValue == null) {
55 return null;
56 }
57
Greg Estren531fc042015-05-26 22:37:44 +000058 BuildConfigurationValue.Key key = (BuildConfigurationValue.Key) skyKey.argument();
59 Set<Fragment> fragments;
60 try {
61 fragments = getConfigurationFragments(key, env);
62 } catch (InvalidConfigurationException e) {
63 throw new BuildConfigurationFunctionException(e);
64 }
65 if (fragments == null) {
66 return null;
67 }
68
69 ClassToInstanceMap<Fragment> fragmentsMap = MutableClassToInstanceMap.create();
70 for (Fragment fragment : fragments) {
71 fragmentsMap.put(fragment.getClass(), fragment);
72 }
73
gregce490b0952017-07-06 18:44:38 -040074 BuildConfiguration config =
75 new BuildConfiguration(
76 directories,
77 fragmentsMap,
78 key.getBuildOptions(),
gregce85297462017-08-18 21:20:29 +020079 workspaceNameValue.getName());
Greg Estren00049432015-08-25 16:43:47 +000080 return new BuildConfigurationValue(config);
Greg Estren531fc042015-05-26 22:37:44 +000081 }
82
83 private Set<Fragment> getConfigurationFragments(BuildConfigurationValue.Key key, Environment env)
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +000084 throws InvalidConfigurationException, InterruptedException {
Greg Estren00049432015-08-25 16:43:47 +000085
Greg Estren531fc042015-05-26 22:37:44 +000086 // Get SkyKeys for the fragments we need to load.
87 Set<SkyKey> fragmentKeys = new LinkedHashSet<>();
88 for (Class<? extends BuildConfiguration.Fragment> fragmentClass : key.getFragments()) {
Greg Estrena0eccb72016-02-01 22:46:10 +000089 fragmentKeys.add(
90 ConfigurationFragmentValue.key(key.getBuildOptions(), fragmentClass, ruleClassProvider));
Greg Estren531fc042015-05-26 22:37:44 +000091 }
92
93 // Load them as Skyframe deps.
94 Map<SkyKey, ValueOrException<InvalidConfigurationException>> fragmentDeps =
95 env.getValuesOrThrow(fragmentKeys, InvalidConfigurationException.class);
96 if (env.valuesMissing()) {
97 return null;
98 }
99
100 // Collect and return the results.
101 ImmutableSet.Builder<Fragment> fragments = ImmutableSet.builder();
102 for (ValueOrException<InvalidConfigurationException> value : fragmentDeps.values()) {
Greg Estren00049432015-08-25 16:43:47 +0000103 BuildConfiguration.Fragment fragment =
104 ((ConfigurationFragmentValue) value.get()).getFragment();
105 if (fragment != null) {
106 fragments.add(fragment);
107 }
Greg Estren531fc042015-05-26 22:37:44 +0000108 }
109 return fragments.build();
110 }
111
112 @Override
113 public String extractTag(SkyKey skyKey) {
114 return null;
115 }
116
117 private static final class BuildConfigurationFunctionException extends SkyFunctionException {
118 public BuildConfigurationFunctionException(InvalidConfigurationException e) {
119 super(e, Transience.PERSISTENT);
120 }
121 }
122}