optionally error on files outside of known roots

The goal of this change is to provide a means for disallowing
files outside of declared, known locations in order to better
enforce the hermeticy and in turn reproducability of builds.
Previously when encountering these files (typically via external
symlinks) we would add a dependency on build_id, now we can
optionally fail the build.

--
MOS_MIGRATED_REVID=90015665
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileStateFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/FileStateFunction.java
index ec2e871..928306c 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/FileStateFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/FileStateFunction.java
@@ -42,12 +42,15 @@
   @Override
   public SkyValue compute(SkyKey skyKey, Environment env) throws FileStateFunctionException {
     RootedPath rootedPath = (RootedPath) skyKey.argument();
-    externalFilesHelper.maybeAddDepOnBuildId(rootedPath, env);
-    if (env.valuesMissing()) {
-      return null;
-    }
+
     try {
+      externalFilesHelper.maybeHandleExternalFile(rootedPath, env);
+      if (env.valuesMissing()) {
+        return null;
+      }
       return FileStateValue.create(rootedPath, tsgm);
+    } catch (FileOutsidePackageRootsException e) {
+      throw new FileStateFunctionException(e);
     } catch (IOException e) {
       throw new FileStateFunctionException(e);
     } catch (InconsistentFilesystemException e) {
@@ -72,5 +75,9 @@
     public FileStateFunctionException(InconsistentFilesystemException e) {
       super(e, Transience.TRANSIENT);
     }
+
+    public FileStateFunctionException(FileOutsidePackageRootsException e) {
+      super(e, Transience.PERSISTENT);
+    }
   }
 }