Load the prelude file as a module

The prelude file is now implicitly loaded by BUILD files using the same machinery as for ordinary explicit loads. Prelude-specific error codes are eliminated in favor of their bzl equivalent.

Previously, the unusual dialect of the prelude file could be described as the intersection of 1) things that statically validate as bzl code with 2) things that dynamically execute as BUILD code. Now it's strictly a bzl module, except that its filename does not typically end in .bzl.

This is a breaking change in theory, but in practice we expect most users -- if they're using the prelude at all -- to be using it just for load() statements.

ASTFileLookupValue:
- The key now records what kind of lookup this is -- normal, prelude, or default prelude. The latter is used to produce a synthetic ASTFileLookupValue when we want to bypass looking up the physical prelude file due to its package not existing. (Another alternative was to statically construct the synthetic ASTFileLookupValue, but that seemed more prone to duplicating logic with ASTFileLookupFunction.)

ASTFileLookupFunction:
- Move statements out of try block. Move all StarlarkFile construction logic to after the find-the-bytes logic.
- Put find-the-bytes logic in a big if that branches on whether we want the default prelude.
- Inline getDigest...() helper that had one usage.

BzlLoadFunction:
- Request the default prelude AST when loading a prelude file whose package doesn't exist.

PackageFunction:
- Delete prelude AST retrieval, pass along the prelude label in place of its statements.
- Request the prelude using the same code path as other bzl deps.
- Reintroduce the BzlLoadResult value class for distinguishing real loaded bzls from the prelude. (This avoids having to create a synthetic load label for the prelude.)
- Inline makeBzlLoadFailedException, so its symmetry and differences to the other exceptional cases is more obvious.
- Added adonovan@ TODOs from prior draft CL.

PackageFactory:
- Thread the prelude module from PackageFunction to where the environment is populated.

failure_details.proto:
- Delete PRELUDE_FILE_READ_ERROR as a valid error code during package loading.

PackageFunctionTest:
- Invert some tests corresponding to behavioral changes (prelude symbols are now frozen, prelude content can now access bzl predeclareds).
- Add a test case.

Other:
- Make some error string formatting more readable.

Work toward flat Starlark environments.

RELNOTES: The prelude file (//tools/build_rules:prelude_bazel) is now processed as a Starlark module, rather than being sourced into the BUILD file textually. This may cause slight breakages depending on the content of the prelude file. (Use of the prelude file is discouraged as it will be removed in the long term.)
PiperOrigin-RevId: 325595853
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
index 6221689..9fd6880 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
@@ -1453,39 +1453,36 @@
       assertContainsEvent("FOO");
     }
 
-    // TODO(brandjon): Invert this test once the prelude is a module instead of a syntactic
-    // mutation on BUILD files.
     @Test
-    public void testPreludeSymbolCanBeMutated() throws Exception {
+    public void testPreludeSymbolCannotBeMutated() throws Exception {
       scratch.file("tools/build_rules/BUILD");
       scratch.file(
           "tools/build_rules/test_prelude", //
           "foo = ['FOO']");
       scratch.file(
           "pkg/BUILD", //
-          "foo.append('BAR')",
-          "print(foo)");
-
-      getConfiguredTarget("//pkg:BUILD");
-      assertContainsEvent("[\"FOO\", \"BAR\"]");
-    }
-
-    // TODO(brandjon): Invert this test once the prelude is a module instead of a syntactic
-    // mutation on BUILD files.
-    @Test
-    public void testPreludeCannotAccessBzlDialectSymbols() throws Exception {
-      scratch.file("tools/build_rules/BUILD");
-      scratch.file(
-          "tools/build_rules/test_prelude", //
-          "v = native.glob()",
-          "foo = 'FOO'");
-      scratch.file(
-          "pkg/BUILD", //
-          "print(foo)");
+          "foo.append('BAR')");
 
       reporter.removeHandler(failFastHandler);
       getConfiguredTarget("//pkg:BUILD");
-      assertContainsEvent("name 'native' is not defined");
+      assertContainsEvent("trying to mutate a frozen list value");
+    }
+
+    @Test
+    public void testPreludeCanAccessBzlDialectFeatures() throws Exception {
+      scratch.file("tools/build_rules/BUILD");
+      // Test both bzl symbols and syntax (e.g. function defs).
+      scratch.file(
+          "tools/build_rules/test_prelude", //
+          "def foo():",
+          "    return native.glob");
+      scratch.file(
+          "pkg/BUILD", //
+          "print(foo())");
+
+      getConfiguredTarget("//pkg:BUILD");
+      // Prelude can access native.glob (though only a BUILD thread can call it).
+      assertContainsEvent("<built-in function glob>");
     }
 
     @Test
@@ -1499,6 +1496,17 @@
     }
 
     @Test
+    public void testPreludeNeedNotBePresent_evenWhenPackageIs() throws Exception {
+      scratch.file("tools/build_rules/BUILD");
+      scratch.file(
+          "pkg/BUILD", //
+          "print('FOO')");
+
+      getConfiguredTarget("//pkg:BUILD");
+      assertContainsEvent("FOO");
+    }
+
+    @Test
     public void testPreludeFileNotRecognizedWithoutPackage() throws Exception {
       scratch.file(
           "tools/build_rules/test_prelude", //