1414
1515package com .google .devtools .build .lib .cmdline ;
1616
17- import com .google .auto . value . AutoValue ;
17+ import com .google .common . base . Objects ;
1818import com .google .common .base .Preconditions ;
1919import com .google .common .collect .ImmutableMap ;
20+ import com .google .common .collect .Maps ;
2021import java .util .HashMap ;
2122import java .util .Map ;
2223import java .util .Map .Entry ;
2324import java .util .Optional ;
2425import javax .annotation .Nullable ;
2526
2627/**
27- * A class to distinguish repository mappings for repos from WORKSPACE and Bzlmod.
28+ * Stores the mapping from apparent repo name to canonical repo name, from the viewpoint of an
29+ * "owner repo".
2830 *
2931 * <p>For repositories from the WORKSPACE file, if the requested repo doesn't exist in the mapping,
3032 * we fallback to the requested name. For repositories from Bzlmod, we return null to let the caller
31- * decide what to do. This class won't be needed if one day we don't define external repositories in
32- * the WORKSPACE file since {@code fallback} would always be false.
33+ * decide what to do.
3334 */
34- @ AutoValue
35- public abstract class RepositoryMapping {
36-
37- // Always fallback to the requested name
35+ public class RepositoryMapping {
36+ /* A repo mapping that always falls back to using the apparent name as the canonical name. */
3837 public static final RepositoryMapping ALWAYS_FALLBACK = createAllowingFallback (ImmutableMap .of ());
3938
39+ private final ImmutableMap <String , RepositoryName > entries ;
40+ @ Nullable private final RepositoryName ownerRepo ;
41+
42+ private RepositoryMapping (
43+ Map <String , RepositoryName > entries , @ Nullable RepositoryName ownerRepo ) {
44+ this .entries = ImmutableMap .copyOf (entries );
45+ this .ownerRepo = ownerRepo ;
46+ }
47+
4048 /** Returns all the entries in this repo mapping. */
41- public abstract ImmutableMap <String , RepositoryName > entries ();
49+ public final ImmutableMap <String , RepositoryName > entries () {
50+ return entries ;
51+ }
4252
4353 /**
4454 * The owner repo of this repository mapping. It is for providing useful debug information when
4555 * repository mapping fails due to enforcing strict dependency, therefore it's only recorded when
46- * we don't fallback to the requested repo name.
56+ * we don't fall back to the requested repo name.
4757 */
4858 @ Nullable
49- abstract RepositoryName ownerRepo ();
59+ public final RepositoryName ownerRepo () {
60+ return ownerRepo ;
61+ }
62+
63+ @ Override
64+ public boolean equals (Object o ) {
65+ if (this == o ) {
66+ return true ;
67+ }
68+ if (!(o instanceof RepositoryMapping )) {
69+ return false ;
70+ }
71+ RepositoryMapping that = (RepositoryMapping ) o ;
72+ return Objects .equal (entries , that .entries ) && Objects .equal (ownerRepo , that .ownerRepo );
73+ }
74+
75+ @ Override
76+ public int hashCode () {
77+ return Objects .hashCode (entries , ownerRepo );
78+ }
5079
5180 public static RepositoryMapping create (
5281 Map <String , RepositoryName > entries , RepositoryName ownerRepo ) {
53- return createInternal (
82+ return new RepositoryMapping (
5483 Preconditions .checkNotNull (entries ), Preconditions .checkNotNull (ownerRepo ));
5584 }
5685
5786 public static RepositoryMapping createAllowingFallback (Map <String , RepositoryName > entries ) {
58- return createInternal (Preconditions .checkNotNull (entries ), null );
59- }
60-
61- private static RepositoryMapping createInternal (
62- Map <String , RepositoryName > entries , RepositoryName ownerRepo ) {
63- return new AutoValue_RepositoryMapping (ImmutableMap .copyOf (entries ), ownerRepo );
87+ return new RepositoryMapping (Preconditions .checkNotNull (entries ), null );
6488 }
6589
6690 /**
@@ -70,7 +94,7 @@ private static RepositoryMapping createInternal(
7094 public RepositoryMapping withAdditionalMappings (Map <String , RepositoryName > additionalMappings ) {
7195 HashMap <String , RepositoryName > allMappings = new HashMap <>(additionalMappings );
7296 allMappings .putAll (entries ());
73- return createInternal (allMappings , ownerRepo ());
97+ return new RepositoryMapping (allMappings , ownerRepo ());
7498 }
7599
76100 /**
@@ -134,6 +158,26 @@ public RepositoryMapping composeWith(RepositoryMapping other) {
134158 RepositoryName mappedName = other .get (entry .getValue ().getName ());
135159 entries .put (entry .getKey (), mappedName .isVisible () ? mappedName : entry .getValue ());
136160 }
137- return createInternal (entries , null );
161+ return new RepositoryMapping (entries , null );
162+ }
163+
164+ /**
165+ * Returns a new {@link RepositoryMapping} instance with identical contents, except that the
166+ * inverse mapping is cached, causing {@link #getInverse} to be much more efficient. This is
167+ * particularly important for the main repo mapping, as it's often used to generate display-form
168+ * labels ({@link Label#getDisplayForm}).
169+ */
170+ public RepositoryMapping withCachedInverseMap () {
171+ var inverse = Maps .<RepositoryName , String >newHashMapWithExpectedSize (entries .size ());
172+ for (Map .Entry <String , RepositoryName > entry : entries .entrySet ()) {
173+ inverse .putIfAbsent (entry .getValue (), entry .getKey ());
174+ }
175+ var inverseCopy = ImmutableMap .copyOf (inverse );
176+ return new RepositoryMapping (entries , ownerRepo ) {
177+ @ Override
178+ public Optional <String > getInverse (RepositoryName postMappingName ) {
179+ return Optional .ofNullable (inverseCopy .get (postMappingName ));
180+ }
181+ };
138182 }
139183}
0 commit comments