1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
// Copyright 2017 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.rules.config;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_KEYED_STRING_DICT;
import com.google.common.collect.ImmutableSortedMap;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleTransitionFactory;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import java.util.Map;
/**
* Transition factory which allows for setting the values of config_feature_flags below the rule
* it is attached to based on one of that rule's attributes.
*
* <p>Currently, this is only intended for use by android_binary and other Android top-level rules.
*/
public class ConfigFeatureFlagTransitionFactory implements RuleTransitionFactory {
/** Transition which resets the set of flag-value pairs to the map it was constructed with. */
@AutoCodec
@VisibleForSerialization
static final class ConfigFeatureFlagValuesTransition implements PatchTransition {
private final ImmutableSortedMap<Label, String> flagValues;
private final int cachedHashCode;
public ConfigFeatureFlagValuesTransition(Map<Label, String> flagValues) {
this(ImmutableSortedMap.copyOf(flagValues), flagValues.hashCode());
}
@AutoCodec.Instantiator
ConfigFeatureFlagValuesTransition(
ImmutableSortedMap<Label, String> flagValues, int cachedHashCode) {
this.flagValues = ImmutableSortedMap.copyOf(flagValues);
this.cachedHashCode = cachedHashCode;
}
@Override
public BuildOptions patch(BuildOptions options) {
if (!options.contains(ConfigFeatureFlagOptions.class)) {
return options;
}
BuildOptions result = options.clone();
result.get(ConfigFeatureFlagOptions.class).replaceFlagValues(flagValues);
return result;
}
@Override
public boolean equals(Object other) {
return other instanceof ConfigFeatureFlagValuesTransition
&& this.flagValues.equals(((ConfigFeatureFlagValuesTransition) other).flagValues);
}
@Override
public int hashCode() {
return cachedHashCode;
}
@Override
public String toString() {
return String.format("ConfigFeatureFlagValuesTransition{flagValues=%s}", flagValues);
}
}
private final String attributeName;
/**
* Creates a transition factory which will generate a transition over a given rule which sets
* exactly the flag values in the attribute with the given {@code attributeName} of that rule,
* unsetting any flag values not listed there.
*
* <p>This attribute must be a nonconfigurable {@code LABEL_KEYED_STRING_DICT}.
*/
public ConfigFeatureFlagTransitionFactory(String attributeName) {
this.attributeName = attributeName;
}
@Override
public PatchTransition buildTransitionFor(Rule rule) {
NonconfigurableAttributeMapper attrs = NonconfigurableAttributeMapper.of(rule);
if (attrs.isAttributeValueExplicitlySpecified(attributeName)) {
return new ConfigFeatureFlagValuesTransition(
attrs.get(attributeName, LABEL_KEYED_STRING_DICT));
} else {
return NoTransition.INSTANCE;
}
}
/**
* Returns the attribute examined by this transition factory.
*/
public String getAttributeName() {
return this.attributeName;
}
@Override
public boolean equals(Object other) {
return other instanceof ConfigFeatureFlagTransitionFactory
&& this.attributeName.equals(((ConfigFeatureFlagTransitionFactory) other).attributeName);
}
@Override
public int hashCode() {
return attributeName.hashCode();
}
@Override
public String toString() {
return String.format("ConfigFeatureFlagTransitionFactory{attributeName=%s}", attributeName);
}
}
|