Introduce Root class.

This class represents a root (such as a package path or an output root) used for file lookups and artifacts. It is meant to be as opaque as possible in order to hide the user's environment from sky keys and sky functions.

Roots are used by RootedPaths and ArtifactRoots.

This CL attempts to make the minimum number of modifications necessary to change RootedPath and ArtifactRoot to use these fields. Deprecated methods and invasive accessors are permitted to minimise the risk of any observable changes.

RELNOTES: None
PiperOrigin-RevId: 182271759
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/RootedPathTest.java b/src/test/java/com/google/devtools/build/lib/vfs/RootedPathTest.java
index d84d8b7..6f452c2 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/RootedPathTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/RootedPathTest.java
@@ -32,21 +32,25 @@
   @Before
   public final void initializeFileSystem() throws Exception  {
     filesystem = new InMemoryFileSystem(BlazeClock.instance());
-    root = filesystem.getRootDirectory();
+    root = filesystem.getPath("/");
   }
 
   @Test
   public void testEqualsAndHashCodeContract() throws Exception {
     Path pkgRoot1 = root.getRelative("pkgroot1");
     Path pkgRoot2 = root.getRelative("pkgroot2");
-    RootedPath rootedPathA1 = RootedPath.toRootedPath(pkgRoot1, PathFragment.create("foo/bar"));
-    RootedPath rootedPathA2 = RootedPath.toRootedPath(pkgRoot1, PathFragment.create("foo/bar"));
+    RootedPath rootedPathA1 =
+        RootedPath.toRootedPath(Root.fromPath(pkgRoot1), PathFragment.create("foo/bar"));
+    RootedPath rootedPathA2 =
+        RootedPath.toRootedPath(Root.fromPath(pkgRoot1), PathFragment.create("foo/bar"));
     RootedPath absolutePath1 =
-        RootedPath.toRootedPath(root, PathFragment.create("pkgroot1/foo/bar"));
-    RootedPath rootedPathB1 = RootedPath.toRootedPath(pkgRoot2, PathFragment.create("foo/bar"));
-    RootedPath rootedPathB2 = RootedPath.toRootedPath(pkgRoot2, PathFragment.create("foo/bar"));
+        RootedPath.toRootedPath(Root.fromPath(root), PathFragment.create("pkgroot1/foo/bar"));
+    RootedPath rootedPathB1 =
+        RootedPath.toRootedPath(Root.fromPath(pkgRoot2), PathFragment.create("foo/bar"));
+    RootedPath rootedPathB2 =
+        RootedPath.toRootedPath(Root.fromPath(pkgRoot2), PathFragment.create("foo/bar"));
     RootedPath absolutePath2 =
-        RootedPath.toRootedPath(root, PathFragment.create("pkgroot2/foo/bar"));
+        RootedPath.toRootedPath(Root.fromPath(root), PathFragment.create("pkgroot2/foo/bar"));
     new EqualsTester()
       .addEqualityGroup(rootedPathA1, rootedPathA2)
       .addEqualityGroup(rootedPathB1, rootedPathB2)