blob: 5935b0e7f37d24eb68e1cebaa2baecb700c7cbc5 [file] [log] [blame]
cparsons5d85e752018-06-26 13:47:28 -07001// Copyright 2018 The Bazel Authors. 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.
14
15package com.google.devtools.build.skydoc.fakebuildapi;
16
kendalllane85841272019-08-07 15:01:07 -070017import com.google.common.collect.ImmutableList;
18import com.google.devtools.build.lib.skylarkbuildapi.ProviderApi;
cparsons5d85e752018-06-26 13:47:28 -070019import com.google.devtools.build.lib.skylarkbuildapi.SkylarkAttrApi;
20import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
dannarkec4f5752019-01-10 13:07:01 -080021import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
cparsons5d85e752018-06-26 13:47:28 -070022import com.google.devtools.build.lib.syntax.Environment;
23import com.google.devtools.build.lib.syntax.EvalException;
24import com.google.devtools.build.lib.syntax.FuncallExpression;
25import com.google.devtools.build.lib.syntax.SkylarkDict;
26import com.google.devtools.build.lib.syntax.SkylarkList;
cparsons5ece6502019-04-17 10:19:41 -070027import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeType;
kendalllane85841272019-08-07 15:01:07 -070028import java.util.ArrayList;
29import java.util.List;
30import java.util.Map;
31import java.util.Map.Entry;
cparsons5d85e752018-06-26 13:47:28 -070032
33/**
34 * Fake implementation of {@link SkylarkAttrApi}.
35 */
36public class FakeSkylarkAttrApi implements SkylarkAttrApi {
37
38 @Override
dannarkec4f5752019-01-10 13:07:01 -080039 public Descriptor intAttribute(
40 Integer defaultInt,
41 String doc,
42 Boolean mandatory,
43 SkylarkList<?> values,
44 FuncallExpression ast,
45 Environment env,
46 StarlarkContext context)
47 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -070048 return new FakeDescriptor(AttributeType.INT, doc, mandatory, ImmutableList.of());
cparsons5d85e752018-06-26 13:47:28 -070049 }
50
51 @Override
dannarkec4f5752019-01-10 13:07:01 -080052 public Descriptor stringAttribute(
53 String defaultString,
54 String doc,
55 Boolean mandatory,
56 SkylarkList<?> values,
57 FuncallExpression ast,
58 Environment env,
59 StarlarkContext context)
60 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -070061 return new FakeDescriptor(AttributeType.STRING, doc, mandatory, ImmutableList.of());
cparsons5d85e752018-06-26 13:47:28 -070062 }
63
64 @Override
dannarkec4f5752019-01-10 13:07:01 -080065 public Descriptor labelAttribute(
66 Object defaultO,
67 String doc,
68 Boolean executable,
69 Object allowFiles,
70 Object allowSingleFile,
71 Boolean mandatory,
72 SkylarkList<?> providers,
73 Object allowRules,
74 Boolean singleFile,
75 Object cfg,
76 SkylarkList<?> aspects,
77 FuncallExpression ast,
78 Environment env,
79 StarlarkContext context)
80 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -070081 List<List<String>> allNameGroups = new ArrayList<>();
82 if (providers != null) {
83 allNameGroups = allProviderNameGroups(providers, env);
84 }
85 return new FakeDescriptor(AttributeType.LABEL, doc, mandatory, allNameGroups);
cparsons5d85e752018-06-26 13:47:28 -070086 }
87
88 @Override
dannarkec4f5752019-01-10 13:07:01 -080089 public Descriptor stringListAttribute(
90 Boolean mandatory,
91 Boolean nonEmpty,
92 Boolean allowEmpty,
93 SkylarkList<?> defaultList,
94 String doc,
95 FuncallExpression ast,
96 Environment env,
97 StarlarkContext context)
cparsons5d85e752018-06-26 13:47:28 -070098 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -070099 return new FakeDescriptor(AttributeType.STRING_LIST, doc, mandatory, ImmutableList.of());
cparsons5d85e752018-06-26 13:47:28 -0700100 }
101
102 @Override
dannarkec4f5752019-01-10 13:07:01 -0800103 public Descriptor intListAttribute(
104 Boolean mandatory,
105 Boolean nonEmpty,
106 Boolean allowEmpty,
107 SkylarkList<?> defaultList,
108 String doc,
109 FuncallExpression ast,
110 Environment env,
111 StarlarkContext context)
cparsons5d85e752018-06-26 13:47:28 -0700112 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -0700113 return new FakeDescriptor(AttributeType.INT_LIST, doc, mandatory, ImmutableList.of());
cparsons5d85e752018-06-26 13:47:28 -0700114 }
115
116 @Override
dannarkec4f5752019-01-10 13:07:01 -0800117 public Descriptor labelListAttribute(
118 Boolean allowEmpty,
119 Object defaultList,
120 String doc,
121 Object allowFiles,
122 Object allowRules,
123 SkylarkList<?> providers,
124 SkylarkList<?> flags,
125 Boolean mandatory,
126 Boolean nonEmpty,
127 Object cfg,
128 SkylarkList<?> aspects,
129 FuncallExpression ast,
130 Environment env,
131 StarlarkContext context)
132 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -0700133 List<List<String>> allNameGroups = new ArrayList<>();
134 if (providers != null) {
135 allNameGroups = allProviderNameGroups(providers, env);
136 }
137 return new FakeDescriptor(AttributeType.LABEL_LIST, doc, mandatory, allNameGroups);
cparsons5d85e752018-06-26 13:47:28 -0700138 }
139
140 @Override
dannarkec4f5752019-01-10 13:07:01 -0800141 public Descriptor labelKeyedStringDictAttribute(
142 Boolean allowEmpty,
143 Object defaultList,
144 String doc,
145 Object allowFiles,
146 Object allowRules,
147 SkylarkList<?> providers,
148 SkylarkList<?> flags,
149 Boolean mandatory,
150 Boolean nonEmpty,
151 Object cfg,
152 SkylarkList<?> aspects,
153 FuncallExpression ast,
154 Environment env,
155 StarlarkContext context)
156 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -0700157 List<List<String>> allNameGroups = new ArrayList<>();
158 if (providers != null) {
159 allNameGroups = allProviderNameGroups(providers, env);
160 }
161 return new FakeDescriptor(AttributeType.LABEL_STRING_DICT, doc, mandatory, allNameGroups);
cparsons5d85e752018-06-26 13:47:28 -0700162 }
163
164 @Override
dannarkec4f5752019-01-10 13:07:01 -0800165 public Descriptor boolAttribute(
166 Boolean defaultO,
167 String doc,
168 Boolean mandatory,
169 FuncallExpression ast,
170 Environment env,
171 StarlarkContext context)
172 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -0700173 return new FakeDescriptor(AttributeType.BOOLEAN, doc, mandatory, ImmutableList.of());
cparsons5d85e752018-06-26 13:47:28 -0700174 }
175
176 @Override
dannarkec4f5752019-01-10 13:07:01 -0800177 public Descriptor outputAttribute(
178 Object defaultO,
179 String doc,
180 Boolean mandatory,
181 FuncallExpression ast,
182 Environment env,
183 StarlarkContext context)
184 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -0700185 return new FakeDescriptor(AttributeType.OUTPUT, doc, mandatory, ImmutableList.of());
cparsons5d85e752018-06-26 13:47:28 -0700186 }
187
188 @Override
dannarkec4f5752019-01-10 13:07:01 -0800189 public Descriptor outputListAttribute(
190 Boolean allowEmpty,
191 Object defaultList,
192 String doc,
193 Boolean mandatory,
194 Boolean nonEmpty,
195 FuncallExpression ast,
196 Environment env,
197 StarlarkContext context)
cparsons5d85e752018-06-26 13:47:28 -0700198 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -0700199 return new FakeDescriptor(AttributeType.OUTPUT_LIST, doc, mandatory, ImmutableList.of());
cparsons5d85e752018-06-26 13:47:28 -0700200 }
201
202 @Override
dannarkec4f5752019-01-10 13:07:01 -0800203 public Descriptor stringDictAttribute(
204 Boolean allowEmpty,
205 SkylarkDict<?, ?> defaultO,
206 String doc,
207 Boolean mandatory,
208 Boolean nonEmpty,
209 FuncallExpression ast,
210 Environment env,
211 StarlarkContext context)
cparsons5d85e752018-06-26 13:47:28 -0700212 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -0700213 return new FakeDescriptor(AttributeType.STRING_DICT, doc, mandatory, ImmutableList.of());
cparsons5d85e752018-06-26 13:47:28 -0700214 }
215
216 @Override
dannarkec4f5752019-01-10 13:07:01 -0800217 public Descriptor stringListDictAttribute(
218 Boolean allowEmpty,
219 SkylarkDict<?, ?> defaultO,
220 String doc,
221 Boolean mandatory,
222 Boolean nonEmpty,
223 FuncallExpression ast,
224 Environment env,
225 StarlarkContext context)
cparsons5d85e752018-06-26 13:47:28 -0700226 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -0700227 return new FakeDescriptor(AttributeType.STRING_LIST_DICT, doc, mandatory, ImmutableList.of());
cparsons5d85e752018-06-26 13:47:28 -0700228 }
229
230 @Override
dannarkec4f5752019-01-10 13:07:01 -0800231 public Descriptor licenseAttribute(
232 Object defaultO,
233 String doc,
234 Boolean mandatory,
235 FuncallExpression ast,
236 Environment env,
237 StarlarkContext context)
238 throws EvalException {
kendalllane85841272019-08-07 15:01:07 -0700239 return new FakeDescriptor(AttributeType.STRING_LIST, doc, mandatory, ImmutableList.of());
cparsons5d85e752018-06-26 13:47:28 -0700240 }
241
242 @Override
243 public void repr(SkylarkPrinter printer) {}
kendalllane85841272019-08-07 15:01:07 -0700244
245 /**
246 * Returns a list of provider name groups, given the value of a Starlark attribute's "providers"
247 * argument.
248 *
249 * <p>{@code providers} can either be a list of providers, or a list of lists of providers. If it
250 * is the first case, the entire list is considered a single group. In the second case, each of
251 * the inner lists is a group.
252 */
253 private static List<List<String>> allProviderNameGroups(SkylarkList<?> providers, Environment env)
254 throws EvalException {
255
256 List<List<String>> allNameGroups = new ArrayList<>();
257 List<List<ProviderApi>> allProviderGroups = new ArrayList<>();
258 for (Object object : providers) {
259 if (object instanceof ProviderApi) {
260 allProviderGroups.add(providers.getContents(ProviderApi.class, "providers"));
261 break;
262 } else if (object instanceof SkylarkList) {
263 allProviderGroups.add(
264 ((SkylarkList<?>) object).getContents(ProviderApi.class, "provider groups"));
265 }
266 }
267
268 for (List<ProviderApi> providerGroup : allProviderGroups) {
269 List<String> nameGroup = providerNameGroup(providerGroup, env);
270 allNameGroups.add(nameGroup);
271 }
272
273 return allNameGroups;
274 }
275
276 /** Returns the names of the providers in the given group. */
277 private static List<String> providerNameGroup(List<ProviderApi> providerGroup, Environment env) {
278 List<String> providerNameGroup = new ArrayList<>();
279 for (ProviderApi provider : providerGroup) {
280 String providerName = providerName(provider, env);
281 providerNameGroup.add(providerName);
282 }
283 return providerNameGroup;
284 }
285
286 /**
287 * Returns the name of {@code provider}.
288 *
289 * <p>{@code env} contains a {@code Map<String, Object>} where the values are built-in objects or
290 * objects defined in the file and the keys are the names of these objects. If a {@code provider}
291 * is in the map, the name of the provider is set as the key of this object in {@code bindings}.
292 * If it is not in the map, the provider may be part of a module in the map and the name will be
293 * set to "Unknown Provider".
294 */
295 private static String providerName(ProviderApi provider, Environment env) {
296 Map<String, Object> bindings = env.getGlobals().getTransitiveBindings();
297 if (bindings.containsValue(provider)) {
298 for (Entry<String, Object> envEntry : bindings.entrySet()) {
299 if (provider.equals(envEntry.getValue())) {
300 return envEntry.getKey();
301 }
302 }
303 }
304 return "Unknown Provider";
305 }
cparsons5d85e752018-06-26 13:47:28 -0700306}
kendalllane85841272019-08-07 15:01:07 -0700307