• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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 package com.google.devtools.build.android.desugar.io;
15 
16 import static com.google.common.base.Preconditions.checkArgument;
17 import static com.google.common.base.Preconditions.checkState;
18 
19 import com.google.common.collect.ImmutableMap;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import javax.annotation.CheckReturnValue;
24 import javax.annotation.Nullable;
25 
26 /**
27  * Opens the given list of input files and compute an index of all classes in them, to avoid
28  * scanning all inputs over and over for each class to load. An indexed inputs can have a parent
29  * that is firstly used when a file name is searched.
30  */
31 public class IndexedInputs {
32 
33   private final ImmutableMap<String, InputFileProvider> inputFiles;
34 
35   /**
36    * Parent {@link IndexedInputs} to use before to search a file name into this {@link
37    * IndexedInputs}.
38    */
39   @Nullable
40   private final IndexedInputs parent;
41 
42   /** Index a list of input files without a parent {@link IndexedInputs}. */
IndexedInputs(List<InputFileProvider> inputProviders)43   public IndexedInputs(List<InputFileProvider> inputProviders) {
44     this.parent = null;
45     this.inputFiles = indexInputs(inputProviders);
46   }
47 
48   /**
49    * Create a new {@link IndexedInputs} with input files previously indexed and with a parent {@link
50    * IndexedInputs}.
51    */
IndexedInputs( ImmutableMap<String, InputFileProvider> inputFiles, IndexedInputs parentIndexedInputs)52   private IndexedInputs(
53       ImmutableMap<String, InputFileProvider> inputFiles, IndexedInputs parentIndexedInputs) {
54     this.parent = parentIndexedInputs;
55     this.inputFiles = inputFiles;
56   }
57 
58   /**
59    * Create a new {@link IndexedInputs} with input files already indexed and with a parent {@link
60    * IndexedInputs}.
61    */
62   @CheckReturnValue
withParent(IndexedInputs parent)63   public IndexedInputs withParent(IndexedInputs parent) {
64     checkState(this.parent == null);
65     return new IndexedInputs(this.inputFiles, parent);
66   }
67 
68   @Nullable
getInputFileProvider(String filename)69   public InputFileProvider getInputFileProvider(String filename) {
70     checkArgument(filename.endsWith(".class"));
71 
72     if (parent != null) {
73       InputFileProvider inputFileProvider = parent.getInputFileProvider(filename);
74       if (inputFileProvider != null) {
75         return inputFileProvider;
76       }
77     }
78 
79     return inputFiles.get(filename);
80   }
81 
indexInputs( List<InputFileProvider> inputProviders)82   private ImmutableMap<String, InputFileProvider> indexInputs(
83       List<InputFileProvider> inputProviders) {
84     Map<String, InputFileProvider> indexedInputs = new HashMap<>();
85     for (InputFileProvider inputProvider : inputProviders) {
86       for (String relativePath : inputProvider) {
87         if (relativePath.endsWith(".class") && !indexedInputs.containsKey(relativePath)) {
88           indexedInputs.put(relativePath, inputProvider);
89         }
90       }
91     }
92     return ImmutableMap.copyOf(indexedInputs);
93   }
94 }
95