blob: 66213092d71748803a987de835c5cf44d801eb1e [file] [log] [blame]
Janak Ramakrishnane9cd0f32016-04-29 22:46:16 +00001// Copyright 2016 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.
14package com.google.devtools.build.lib.runtime;
15
tomlua155b532017-11-08 20:12:47 +010016import com.google.common.base.Preconditions;
Janak Ramakrishnane9cd0f32016-04-29 22:46:16 +000017import com.google.common.collect.ImmutableSet;
18import com.google.common.collect.Maps;
ccalvarinf39dc6f2017-06-09 11:51:45 -040019import com.google.devtools.common.options.CommandNameCache;
Janak Ramakrishnane9cd0f32016-04-29 22:46:16 +000020import java.util.ArrayDeque;
21import java.util.HashMap;
22import java.util.HashSet;
23import java.util.Map;
24import java.util.Queue;
25import java.util.Set;
26
27class CommandNameCacheImpl implements CommandNameCache {
28 private final Map<String, Command> commandMap;
29 private final Map<String, ImmutableSet<String>> cache = new HashMap<>();
30
31 CommandNameCacheImpl(Map<String, BlazeCommand> commandMap) {
32 // Note: it is important that this map is live, since the commandMap may be altered
33 // post-creation.
34 this.commandMap =
35 Maps.transformValues(
laurentlb3d2a68c2017-06-30 00:32:04 +020036 commandMap, blazeCommand -> blazeCommand.getClass().getAnnotation(Command.class));
Janak Ramakrishnane9cd0f32016-04-29 22:46:16 +000037 }
38
39 @Override
40 public ImmutableSet<String> get(String commandName) {
41 ImmutableSet<String> cachedResult = cache.get(commandName);
42 if (cachedResult != null) {
43 return cachedResult;
44 }
45 ImmutableSet.Builder<String> builder = ImmutableSet.builder();
46
47 Command command = Preconditions.checkNotNull(commandMap.get(commandName), commandName);
48 Set<Command> visited = new HashSet<>();
49 visited.add(command);
50 Queue<Command> queue = new ArrayDeque<>();
51 queue.add(command);
52 while (!queue.isEmpty()) {
53 Command cur = queue.remove();
54 builder.add(cur.name());
55 for (Class<? extends BlazeCommand> clazz : cur.inherits()) {
56 Command parent = clazz.getAnnotation(Command.class);
57 if (visited.add(parent)) {
58 queue.add(parent);
59 }
60 }
61 }
62 cachedResult = builder.build();
63 cache.put(commandName, cachedResult);
64 return cachedResult;
65 }
66}