Enable label-based Skylark loading. In particular, such labels may reference files in external repositories.

In addition:

- Cleaned up and refactored some tests to reflect the new loading behavior.

Deferred to future CLs:

- Updating Bazel Skylark documentation to reflect the new load form.

- Enabling command-line loading of Aspects via labels.

RELNOTES: Skylark load statements may now reference .bzl files via build labels, in addition to paths. In particular, such labels can be used to reference Skylark files in external repositories; e.g., load("@my_external_repo//some_pkg:some_file.bzl", ...). Path-based loads are now deprecated and may be disabled in the future. Caveats: Skylark files currently do not respect package visibility; i.e., all Skylark files are effectively public. Also, loads may not reference the special //external package.

--
MOS_MIGRATED_REVID=110786452
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
index b7f24c3..bf77b9b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
@@ -27,7 +27,6 @@
 import com.google.devtools.build.lib.util.Fingerprint;
 import com.google.devtools.build.lib.util.Pair;
 import com.google.devtools.build.lib.util.Preconditions;
-import com.google.devtools.build.lib.vfs.PathFragment;
 
 import java.io.Serializable;
 import java.util.HashMap;
@@ -294,9 +293,9 @@
   private final EventHandler eventHandler;
 
   /**
-   * For each imported extensions, a global Skylark frame from which to load() individual bindings.
+   * For each imported extension, a global Skylark frame from which to load() individual bindings.
    */
-  private final Map<PathFragment, Extension> importedExtensions;
+  private final Map<String, Extension> importedExtensions;
 
   /**
    * Is this Environment being executed in Skylark context?
@@ -468,7 +467,7 @@
       Frame globalFrame,
       Frame dynamicFrame,
       EventHandler eventHandler,
-      Map<PathFragment, Extension> importedExtensions,
+      Map<String, Extension> importedExtensions,
       boolean isSkylark,
       @Nullable String fileContentHashCode,
       boolean isLoadingPhase) {
@@ -492,7 +491,7 @@
     private boolean isLoadingPhase = false;
     @Nullable private Frame parent;
     @Nullable private EventHandler eventHandler;
-    @Nullable private Map<PathFragment, Extension> importedExtensions;
+    @Nullable private Map<String, Extension> importedExtensions;
     @Nullable private String fileContentHashCode;
 
     Builder(Mutability mutability) {
@@ -528,9 +527,9 @@
     }
 
     /** Declares imported extensions for load() statements. */
-    public Builder setImportedExtensions (Map<PathFragment, Extension> importedExtensions) {
+    public Builder setImportedExtensions (Map<String, Extension> importMap) {
       Preconditions.checkState(this.importedExtensions == null);
-      this.importedExtensions = importedExtensions;
+      this.importedExtensions = importMap;
       return this;
     }
 
@@ -773,22 +772,22 @@
    * that was not properly loaded.
    */
   public static class LoadFailedException extends Exception {
-    LoadFailedException(PathFragment extension) {
+    LoadFailedException(String importString) {
       super(String.format("file '%s' was not correctly loaded. "
               + "Make sure the 'load' statement appears in the global scope in your file",
-              extension));
+              importString));
     }
   }
 
-  public void importSymbol(PathFragment extension, Identifier symbol, String nameInLoadedFile)
+  public void importSymbol(String importString, Identifier symbol, String nameInLoadedFile)
       throws NoSuchVariableException, LoadFailedException {
     Preconditions.checkState(isGlobal()); // loading is only allowed at global scope.
 
-    if (!importedExtensions.containsKey(extension)) {
-      throw new LoadFailedException(extension);
+    if (!importedExtensions.containsKey(importString)) {
+      throw new LoadFailedException(importString);
     }
 
-    Extension ext = importedExtensions.get(extension);
+    Extension ext = importedExtensions.get(importString);
 
     // TODO(bazel-team): Throw a LoadFailedException instead, with an appropriate message.
     // Throwing a NoSuchVariableException is backward compatible, but backward.
@@ -801,7 +800,7 @@
     try {
       update(symbol.getName(), value);
     } catch (EvalException e) {
-      throw new LoadFailedException(extension);
+      throw new LoadFailedException(importString);
     }
   }
 
@@ -813,9 +812,9 @@
     // Calculate a new hash from the hash of the loaded Extension-s.
     Fingerprint fingerprint = new Fingerprint();
     fingerprint.addString(Preconditions.checkNotNull(fileContentHashCode));
-    TreeSet<PathFragment> paths = new TreeSet<>(importedExtensions.keySet());
-    for (PathFragment path : paths) {
-      fingerprint.addString(importedExtensions.get(path).getTransitiveContentHashCode());
+    TreeSet<String> importStrings = new TreeSet<>(importedExtensions.keySet());
+    for (String importString : importStrings) {
+      fingerprint.addString(importedExtensions.get(importString).getTransitiveContentHashCode());
     }
     return fingerprint.hexDigestAndReset();
   }