blob: 3de1bc5c090f554371a7e9716131c9b68a2b09fb [file] [log] [blame]
Greg Estren531fc042015-05-26 22:37:44 +00001// Copyright 2015 Google Inc. All rights reserved.
2//
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;
22import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
23import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
24import com.google.devtools.build.skyframe.SkyFunction;
25import com.google.devtools.build.skyframe.SkyFunctionException;
26import com.google.devtools.build.skyframe.SkyKey;
27import com.google.devtools.build.skyframe.SkyValue;
28import com.google.devtools.build.skyframe.ValueOrException;
29
30import java.util.LinkedHashSet;
31import java.util.Map;
32import java.util.Set;
33
34/**
35 * A builder for {@link BuildConfigurationValue} instances.
36 */
37public class BuildConfigurationFunction implements SkyFunction {
38
39 private final BlazeDirectories directories;
40
41 public BuildConfigurationFunction(BlazeDirectories directories) {
42 this.directories = directories;
43 }
44
45 @Override
46 public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException,
47 SkyFunctionException {
48 BuildConfigurationValue.Key key = (BuildConfigurationValue.Key) skyKey.argument();
49 Set<Fragment> fragments;
50 try {
51 fragments = getConfigurationFragments(key, env);
52 } catch (InvalidConfigurationException e) {
53 throw new BuildConfigurationFunctionException(e);
54 }
55 if (fragments == null) {
56 return null;
57 }
58
59 ClassToInstanceMap<Fragment> fragmentsMap = MutableClassToInstanceMap.create();
60 for (Fragment fragment : fragments) {
61 fragmentsMap.put(fragment.getClass(), fragment);
62 }
63
64 return new BuildConfigurationValue(
65 new BuildConfiguration(directories, fragmentsMap, key.getBuildOptions(),
66 !key.actionsEnabled()));
67 }
68
69 private Set<Fragment> getConfigurationFragments(BuildConfigurationValue.Key key, Environment env)
70 throws InvalidConfigurationException {
71 // Get SkyKeys for the fragments we need to load.
72 Set<SkyKey> fragmentKeys = new LinkedHashSet<>();
73 for (Class<? extends BuildConfiguration.Fragment> fragmentClass : key.getFragments()) {
74 fragmentKeys.add(ConfigurationFragmentValue.key(key.getBuildOptions(), fragmentClass));
75 }
76
77 // Load them as Skyframe deps.
78 Map<SkyKey, ValueOrException<InvalidConfigurationException>> fragmentDeps =
79 env.getValuesOrThrow(fragmentKeys, InvalidConfigurationException.class);
80 if (env.valuesMissing()) {
81 return null;
82 }
83
84 // Collect and return the results.
85 ImmutableSet.Builder<Fragment> fragments = ImmutableSet.builder();
86 for (ValueOrException<InvalidConfigurationException> value : fragmentDeps.values()) {
87 fragments.add(((ConfigurationFragmentValue) value.get()).getFragment());
88 }
89 return fragments.build();
90 }
91
92 @Override
93 public String extractTag(SkyKey skyKey) {
94 return null;
95 }
96
97 private static final class BuildConfigurationFunctionException extends SkyFunctionException {
98 public BuildConfigurationFunctionException(InvalidConfigurationException e) {
99 super(e, Transience.PERSISTENT);
100 }
101 }
102}