bazel syntax: rename ParserInput{Source,}

Also:
- make it concrete and final
- hide the getContent method, to allow the possibility of a scanner
  using code points or UTF-8 bytes, not UTF-16 chars.

This is necessarily a breaking API change for copybara.

RELNOTES: N/A
PiperOrigin-RevId: 269623736
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
index a39c91c..3a0ea5b 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
@@ -674,13 +674,12 @@
         substitutionsUnchecked
             .getContents(String.class, String.class, "substitutions")
             .entrySet()) {
-      // ParserInputSource.create(Path) uses Latin1 when reading BUILD files, which might
+      // ParserInput.create(Path) uses Latin1 when reading BUILD files, which might
       // contain UTF-8 encoded symbols as part of template substitution.
       // As a quick fix, the substitution values are corrected before being passed on.
-      // In the long term, fixing ParserInputSource.create(Path) would be a better approach.
+      // In the long term, fixing ParserInput.create(Path) would be a better approach.
       substitutionsBuilder.add(
-          Substitution.of(
-              substitution.getKey(), convertLatin1ToUtf8(substitution.getValue())));
+          Substitution.of(substitution.getKey(), convertLatin1ToUtf8(substitution.getValue())));
     }
     TemplateExpansionAction action =
         new TemplateExpansionAction(
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index 7acd90b..39f135b 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -63,7 +63,7 @@
 import com.google.devtools.build.lib.syntax.Mutability;
 import com.google.devtools.build.lib.syntax.Node;
 import com.google.devtools.build.lib.syntax.NodeVisitor;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.Runtime;
 import com.google.devtools.build.lib.syntax.SkylarkDict;
 import com.google.devtools.build.lib.syntax.SkylarkList;
@@ -1347,7 +1347,7 @@
       String workspaceName,
       PackageIdentifier packageId,
       RootedPath buildFile,
-      ParserInputSource input,
+      ParserInput input,
       List<Statement> preludeStatements,
       Map<String, Extension> imports,
       ImmutableList<Label> skylarkFileDependencies,
@@ -1382,7 +1382,7 @@
 
   public static BuildFileAST parseBuildFile(
       PackageIdentifier packageId,
-      ParserInputSource input,
+      ParserInput input,
       List<Statement> preludeStatements,
       ImmutableMap<RepositoryName, RepositoryName> repositoryMapping,
       ExtendedEventHandler eventHandler) {
@@ -1492,8 +1492,8 @@
 
     Globber globber =
         createLegacyGlobber(buildFile.asPath().getParentDirectory(), packageId, locator);
-    ParserInputSource input =
-        ParserInputSource.create(
+    ParserInput input =
+        ParserInput.create(
             FileSystemUtils.convertFromLatin1(buildFileBytes), buildFile.asPath().asFragment());
 
     Package result =
diff --git a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
index 90d0d4f..cedf212 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
@@ -39,7 +39,7 @@
 import com.google.devtools.build.lib.syntax.FuncallExpression;
 import com.google.devtools.build.lib.syntax.FunctionSignature;
 import com.google.devtools.build.lib.syntax.Mutability;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.Runtime;
 import com.google.devtools.build.lib.syntax.SkylarkUtils;
 import com.google.devtools.build.lib.syntax.SkylarkUtils.Phase;
@@ -126,7 +126,7 @@
 
   @VisibleForTesting
   void parseForTesting(
-      ParserInputSource source,
+      ParserInput source,
       StarlarkSemantics starlarkSemantics,
       @Nullable StoredEventHandler localReporter)
       throws BuildFileContainsErrorsException, InterruptedException {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/ResolvedFileFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/ResolvedFileFunction.java
index b5906ef..56a2baa 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/ResolvedFileFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/ResolvedFileFunction.java
@@ -25,7 +25,7 @@
 import com.google.devtools.build.lib.skyframe.PrecomputedValue;
 import com.google.devtools.build.lib.syntax.BuildFileAST;
 import com.google.devtools.build.lib.syntax.Mutability;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.StarlarkSemantics;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import com.google.devtools.build.skyframe.SkyFunction;
@@ -64,8 +64,7 @@
                 key.getPath().asPath(), key.getPath().asPath().getFileSize());
         BuildFileAST ast =
             BuildFileAST.parse(
-                ParserInputSource.create(bytes, key.getPath().asPath().asFragment()),
-                env.getListener());
+                ParserInput.create(bytes, key.getPath().asPath().asFragment()), env.getListener());
         if (ast.containsErrors()) {
           throw new ResolvedFileFunctionException(
               new BuildFileContainsErrorsException(
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java
index d54dabf..0197b90 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java
@@ -22,7 +22,7 @@
 import com.google.devtools.build.lib.packages.RuleClassProvider;
 import com.google.devtools.build.lib.syntax.BuildFileAST;
 import com.google.devtools.build.lib.syntax.Mutability;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.StarlarkSemantics;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import com.google.devtools.build.lib.vfs.Path;
@@ -125,7 +125,7 @@
                 /*importMap=*/ null,
                 /*repoMapping=*/ ImmutableMap.of());
         byte[] bytes = FileSystemUtils.readWithKnownFileSize(path, astFileSize);
-        ParserInputSource input = ParserInputSource.create(bytes, path.asFragment());
+        ParserInput input = ParserInput.create(bytes, path.asFragment());
         file = BuildFileAST.parseWithDigest(input, path.getDigest(), env.getListener());
         file = file.validate(validationEnv, /*isBuildFile=*/ false, env.getListener());
       }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
index b9e4ecb..bb28a3f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
@@ -61,7 +61,7 @@
 import com.google.devtools.build.lib.syntax.BuildFileAST;
 import com.google.devtools.build.lib.syntax.Environment.Extension;
 import com.google.devtools.build.lib.syntax.EvalException;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.SkylarkImport;
 import com.google.devtools.build.lib.syntax.StarlarkSemantics;
 import com.google.devtools.build.lib.syntax.Statement;
@@ -1152,7 +1152,7 @@
         if (showLoadingProgress.get()) {
           env.getListener().handle(Event.progress("Loading package: " + packageId));
         }
-        ParserInputSource input;
+        ParserInput input;
         Preconditions.checkNotNull(buildFileValue, packageId);
         byte[] buildFileBytes = null;
         try {
@@ -1175,7 +1175,7 @@
           // See the javadoc for ActionOnIOExceptionReadingBuildFile.
         }
         input =
-            ParserInputSource.create(
+            ParserInput.create(
                 FileSystemUtils.convertFromLatin1(buildFileBytes), inputFile.asFragment());
         StoredEventHandler astParsingEventHandler = new StoredEventHandler();
         BuildFileAST ast =
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java
index 976a2a1..14650fa 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java
@@ -30,7 +30,7 @@
 import com.google.devtools.build.lib.rules.repository.ResolvedFileValue;
 import com.google.devtools.build.lib.syntax.BuildFileAST;
 import com.google.devtools.build.lib.syntax.LoadStatement;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.Printer;
 import com.google.devtools.build.lib.syntax.Statement;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
@@ -84,7 +84,7 @@
     try {
       BuildFileAST file =
           BuildFileAST.parse(
-              ParserInputSource.create(
+              ParserInput.create(
                   ruleClassProvider.getDefaultWorkspacePrefix(),
                   PathFragment.create("/DEFAULT.WORKSPACE")),
               env.getListener());
@@ -98,7 +98,7 @@
       if (newWorkspaceFileContents != null) {
         file =
             BuildFileAST.parseVirtualBuildFile(
-                ParserInputSource.create(
+                ParserInput.create(
                     newWorkspaceFileContents, resolvedFile.get().asPath().asFragment()),
                 file.getStatements(),
                 /* repositoryMapping= */ ImmutableMap.of(),
@@ -108,7 +108,7 @@
             FileSystemUtils.readWithKnownFileSize(repoWorkspace, repoWorkspace.getFileSize());
         file =
             BuildFileAST.parseWithPrelude(
-                ParserInputSource.create(bytes, repoWorkspace.asFragment()),
+                ParserInput.create(bytes, repoWorkspace.asFragment()),
                 file.getStatements(),
                 /* repositoryMapping= */ ImmutableMap.of(),
                 env.getListener());
@@ -121,7 +121,7 @@
       }
       file =
           BuildFileAST.parseWithPrelude(
-              ParserInputSource.create(
+              ParserInput.create(
                   resolvedFile.isPresent() ? "" : ruleClassProvider.getDefaultWorkspaceSuffix(),
                   PathFragment.create("/DEFAULT.WORKSPACE.SUFFIX")),
               file.getStatements(),
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkdebug/server/ThreadHandler.java b/src/main/java/com/google/devtools/build/lib/skylarkdebug/server/ThreadHandler.java
index ac8c217..378a16a 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkdebug/server/ThreadHandler.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkdebug/server/ThreadHandler.java
@@ -30,7 +30,7 @@
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.EvalUtils;
 import com.google.devtools.build.lib.syntax.Expression;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.Runtime;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import java.util.Collection;
@@ -306,8 +306,7 @@
       // the logic below.
       // The result of evaluating a Statement is None.
 
-      ParserInputSource input =
-          ParserInputSource.create(content, PathFragment.create("<debug eval>"));
+      ParserInput input = ParserInput.create(content, PathFragment.create("<debug eval>"));
 
       // Try parsing as an expression.
       EventSensor sensor = new EventSensor(EventKind.ERRORS);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BUILD b/src/main/java/com/google/devtools/build/lib/syntax/BUILD
index d306931..a6237ab 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BUILD
@@ -28,7 +28,7 @@
 # This should eventually include all AST nodes plus the lexer and parser.
 FRONTEND_FILES = [
     "LineNumberTable.java",
-    "ParserInputSource.java",
+    "ParserInput.java",
     "SkylarkImport.java",
     "StarlarkSemantics.java",
     "Token.java",
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java b/src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java
index 9455cd9..bacb239 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java
@@ -300,7 +300,7 @@
    * event handler.
    */
   public static BuildFileAST parseWithPrelude(
-      ParserInputSource input,
+      ParserInput input,
       List<Statement> preludeStatements,
       ImmutableMap<RepositoryName, RepositoryName> repositoryMapping,
       EventHandler eventHandler) {
@@ -315,7 +315,7 @@
    * the event handler.
    */
   public static BuildFileAST parseVirtualBuildFile(
-      ParserInputSource input,
+      ParserInput input,
       List<Statement> preludeStatements,
       ImmutableMap<RepositoryName, RepositoryName> repositoryMapping,
       EventHandler eventHandler) {
@@ -330,7 +330,7 @@
   }
 
   public static BuildFileAST parseWithDigest(
-      ParserInputSource input, byte[] digest, EventHandler eventHandler) throws IOException {
+      ParserInput input, byte[] digest, EventHandler eventHandler) throws IOException {
     Parser.ParseResult result = Parser.parseFile(input, eventHandler);
     return create(
         /* preludeStatements= */ ImmutableList.of(),
@@ -340,7 +340,7 @@
         eventHandler);
   }
 
-  public static BuildFileAST parse(ParserInputSource input, EventHandler eventHandler) {
+  public static BuildFileAST parse(ParserInput input, EventHandler eventHandler) {
     Parser.ParseResult result = Parser.parseFile(input, eventHandler);
     return create(
         /* preludeStatements= */ ImmutableList.<Statement>of(),
@@ -354,8 +354,7 @@
    * Parse the specified file but avoid the validation of the imports, returning its AST. All errors
    * during scanning or parsing will be reported to the event handler.
    */
-  public static BuildFileAST parseWithoutImports(
-      ParserInputSource input, EventHandler eventHandler) {
+  public static BuildFileAST parseWithoutImports(ParserInput input, EventHandler eventHandler) {
     ParseResult result = Parser.parseFile(input, eventHandler);
     return new BuildFileAST(
         ImmutableList.copyOf(result.statements),
@@ -425,7 +424,7 @@
   // Note: uses Starlark (not BUILD) validation semantics.
   // TODO(adonovan): move to EvalUtils; see other eval function.
   @Nullable
-  public static Object eval(ParserInputSource input, Environment env)
+  public static Object eval(ParserInput input, Environment env)
       throws EvalException, InterruptedException {
     BuildFileAST ast = parseAndValidateSkylark(input, env);
     return ast.eval(env);
@@ -436,7 +435,7 @@
    * it throws an EvalException. Uses Starlark (not BUILD) validation semantics.
    */
   // TODO(adonovan): move to EvalUtils; see above.
-  public static BuildFileAST parseAndValidateSkylark(ParserInputSource input, Environment env)
+  public static BuildFileAST parseAndValidateSkylark(ParserInput input, Environment env)
       throws EvalException {
     BuildFileAST file = parse(input, env.getEventHandler());
     file.replayLexerEvents(env, env.getEventHandler());
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 8d84321..f2cff04 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
@@ -1234,7 +1234,7 @@
 
   /** Evaluates a Skylark statement in this environment. (Debugger API) */
   // TODO(adonovan): push this up into the debugger once the eval API is finalized.
-  public Object debugEval(ParserInputSource input) throws EvalException, InterruptedException {
+  public Object debugEval(ParserInput input) throws EvalException, InterruptedException {
     EvalEventHandler handler = new EvalEventHandler();
     Expression expr = Expression.parse(input, handler);
     if (!handler.messages.isEmpty()) {
@@ -1246,7 +1246,7 @@
 
   /** Executes a Skylark file (sequence of statements) in this environment. (Debugger API) */
   // TODO(adonovan): push this up into the debugger once the exec API is finalized.
-  public void debugExec(ParserInputSource input) throws EvalException, InterruptedException {
+  public void debugExec(ParserInput input) throws EvalException, InterruptedException {
     EvalEventHandler handler = new EvalEventHandler();
     BuildFileAST file = BuildFileAST.parse(input, handler);
     if (!handler.messages.isEmpty()) {
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Expression.java b/src/main/java/com/google/devtools/build/lib/syntax/Expression.java
index 76256e1..807f8d1 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Expression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Expression.java
@@ -121,7 +121,7 @@
   // errors,
   // and generally it is useful to keep both around, so if we put the errors in the root of the AST,
   // then client can deal with them however they like, e.g. by sending them to the event handler.
-  public static Expression parse(ParserInputSource input, EventHandler eventHandler) {
+  public static Expression parse(ParserInput input, EventHandler eventHandler) {
     return Parser.parseExpression(input, eventHandler);
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Lexer.java b/src/main/java/com/google/devtools/build/lib/syntax/Lexer.java
index ab0a5de..fc35657 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Lexer.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Lexer.java
@@ -118,8 +118,7 @@
    * Constructs a lexer which tokenizes the contents of the specified InputBuffer. Any errors during
    * lexing are reported on "handler".
    */
-  public Lexer(
-      ParserInputSource input, EventHandler eventHandler, LineNumberTable lineNumberTable) {
+  public Lexer(ParserInput input, EventHandler eventHandler, LineNumberTable lineNumberTable) {
     this.buffer = input.getContent();
     this.pos = 0;
     this.eventHandler = eventHandler;
@@ -132,7 +131,7 @@
     indentStack.push(0);
   }
 
-  public Lexer(ParserInputSource input, EventHandler eventHandler) {
+  public Lexer(ParserInput input, EventHandler eventHandler) {
     this(input, eventHandler, LineNumberTable.create(input.getContent(), input.getPath()));
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
index 5986408..46f5913 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
@@ -192,7 +192,7 @@
   }
 
   // Main entry point for parsing a file.
-  static ParseResult parseFile(ParserInputSource input, EventHandler eventHandler) {
+  static ParseResult parseFile(ParserInput input, EventHandler eventHandler) {
     Lexer lexer = new Lexer(input, eventHandler);
     Parser parser = new Parser(lexer, eventHandler);
     List<Statement> statements;
@@ -211,7 +211,7 @@
   }
 
   /** Parses a sequence of statements, possibly followed by newline tokens. */
-  static List<Statement> parseStatements(ParserInputSource input, EventHandler eventHandler) {
+  static List<Statement> parseStatements(ParserInput input, EventHandler eventHandler) {
     Lexer lexer = new Lexer(input, eventHandler);
     Parser parser = new Parser(lexer, eventHandler);
     List<Statement> result = new ArrayList<>();
@@ -229,7 +229,7 @@
    * @throws IllegalArgumentException if the number of parsed statements was not exactly one
    */
   @VisibleForTesting
-  static Statement parseStatement(ParserInputSource input, EventHandler eventHandler) {
+  static Statement parseStatement(ParserInput input, EventHandler eventHandler) {
     List<Statement> stmts = parseStatements(input, eventHandler);
     return Iterables.getOnlyElement(stmts);
   }
@@ -255,7 +255,7 @@
 
   /** Parses an expression, possibly followed by newline tokens. */
   @VisibleForTesting
-  static Expression parseExpression(ParserInputSource input, EventHandler eventHandler) {
+  static Expression parseExpression(ParserInput input, EventHandler eventHandler) {
     Lexer lexer = new Lexer(input, eventHandler);
     Parser parser = new Parser(lexer, eventHandler);
     Expression result = parser.parseExpression();
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ParserInput.java b/src/main/java/com/google/devtools/build/lib/syntax/ParserInput.java
new file mode 100644
index 0000000..99d62ee
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ParserInput.java
@@ -0,0 +1,86 @@
+// Copyright 2014 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.syntax;
+
+import com.google.common.base.Joiner;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import java.io.IOException;
+import javax.annotation.Nullable;
+
+/** The apparent name and contents of a source file, for consumption by the parser. */
+public final class ParserInput {
+
+  private final char[] content;
+  private final PathFragment path;
+
+  private ParserInput(char[] content, @Nullable PathFragment path) {
+    this.content = content;
+    this.path = path == null ? PathFragment.EMPTY_FRAGMENT : path;
+  }
+
+  /** Returns the content of the input source. Callers must not modify the result. */
+  char[] getContent() {
+    return content;
+  }
+
+  /**
+   * Returns the (non-null) apparent file name of the input source, for use in error messages; the
+   * file will not be opened.
+   */
+  // TODO(adonovan): use Strings, to avoid dependency on vfs; but first we need to avoid depending
+  // on events.Location.
+  public PathFragment getPath() {
+    return path;
+  }
+
+  /** Returns an unnamed input source that reads from a list of strings, joined by newlines. */
+  public static ParserInput fromLines(String... lines) {
+    return create(Joiner.on("\n").join(lines), null);
+  }
+
+  /**
+   * Returns an import source that reads from a Latin-1 encoded byte array. The path specifies the
+   * name of the file, for use in source locations and error messages; a null path implies the empty
+   * string.
+   */
+  public static ParserInput create(byte[] bytes, @Nullable PathFragment path) throws IOException {
+    char[] content = convertFromLatin1(bytes);
+    return new ParserInput(content, path);
+  }
+
+  /**
+   * Create an input source from the given content, and associate path with this source. Path will
+   * be used in error messages etc. but we will *never* attempt to read the content from path. A
+   * null path implies the empty string.
+   */
+  public static ParserInput create(String content, @Nullable PathFragment path) {
+    return create(content.toCharArray(), path);
+  }
+
+  /**
+   * Create an input source from the given content, and associate path with this source. Path will
+   * be used in error messages etc. but we will *never* attempt to read the content from path.
+   */
+  public static ParserInput create(char[] content, PathFragment path) {
+    return new ParserInput(content, path);
+  }
+
+  private static char[] convertFromLatin1(byte[] content) {
+    char[] latin1 = new char[content.length];
+    for (int i = 0; i < latin1.length; i++) { // yeah, latin1 is this easy! :-)
+      latin1[i] = (char) (0xff & content[i]);
+    }
+    return latin1;
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ParserInputSource.java b/src/main/java/com/google/devtools/build/lib/syntax/ParserInputSource.java
deleted file mode 100644
index 4ea0b46..0000000
--- a/src/main/java/com/google/devtools/build/lib/syntax/ParserInputSource.java
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2014 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package com.google.devtools.build.lib.syntax;
-
-import com.google.common.base.Joiner;
-import com.google.devtools.build.lib.vfs.PathFragment;
-import java.io.IOException;
-import javax.annotation.Nullable;
-
-/** An abstraction for reading input from a file or taking it as a pre-cooked char[] or String. */
-// TODO(adonovan): make this final and concrete;
-// create returns the only implementation that matters.
-// TODO(adonovan): rename to "ParserInput".
-public abstract class ParserInputSource {
-
-  protected ParserInputSource() {}
-
-  /** Returns the content of the input source. */
-  public abstract char[] getContent();
-
-  /**
-   * Returns the (non-null) path of the input source. Note: Once constructed, this object will never
-   * re-read the content from path.
-   */
-  // TODO(adonovan): use Strings, to avoid dependency on vfs; but first we need to avoid depending
-  // on events.Location.
-  public abstract PathFragment getPath();
-
-  /** Returns an unnamed input source that reads from a list of strings, joined by newlines. */
-  public static ParserInputSource fromLines(String... lines) {
-    return create(Joiner.on("\n").join(lines), null);
-  }
-
-  /**
-   * Returns an import source that reads from a Latin-1 encoded byte array. The path specifies the
-   * name of the file, for use in source locations and error messages; a null path implies the empty
-   * string.
-   */
-  public static ParserInputSource create(byte[] bytes, @Nullable PathFragment path)
-      throws IOException {
-    char[] content = convertFromLatin1(bytes);
-    return create(content, path);
-  }
-
-  /**
-   * Create an input source from the given content, and associate path with this source. Path will
-   * be used in error messages etc. but we will *never* attempt to read the content from path. A
-   * null path implies the empty string.
-   */
-  public static ParserInputSource create(String content, @Nullable PathFragment path) {
-    return create(content.toCharArray(), path);
-  }
-
-  /**
-   * Create an input source from the given content, and associate path with
-   * this source.  Path will be used in error messages etc. but we will *never*
-   * attempt to read the content from path.
-   */
-  public static ParserInputSource create(final char[] content, final PathFragment path) {
-    return new ParserInputSource() {
-      @Override
-      public char[] getContent() {
-        return content;
-      }
-
-      @Override
-      public PathFragment getPath() {
-        return path == null ? PathFragment.EMPTY_FRAGMENT : path;
-      }
-    };
-  }
-
-  private static char[] convertFromLatin1(byte[] content) {
-    char[] latin1 = new char[content.length];
-    for (int i = 0; i < latin1.length; i++) { // yeah, latin1 is this easy! :-)
-      latin1[i] = (char) (0xff & content[i]);
-    }
-    return latin1;
-  }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java
index f69e903..250625b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java
@@ -258,7 +258,7 @@
                   .setEventHandler(Environment.FAIL_FAST_HANDLER)
                   .build()
                   .update("unbound", Runtime.UNBOUND);
-          defaultValue = BuildFileAST.eval(ParserInputSource.fromLines(paramDefaultValue), env);
+          defaultValue = BuildFileAST.eval(ParserInput.fromLines(paramDefaultValue), env);
           defaultValueCache.put(paramDefaultValue, defaultValue);
           return defaultValue;
         }
diff --git a/src/main/java/com/google/devtools/build/skydoc/FilesystemFileAccessor.java b/src/main/java/com/google/devtools/build/skydoc/FilesystemFileAccessor.java
index 2b1bd91..9f6e4a4 100644
--- a/src/main/java/com/google/devtools/build/skydoc/FilesystemFileAccessor.java
+++ b/src/main/java/com/google/devtools/build/skydoc/FilesystemFileAccessor.java
@@ -14,7 +14,7 @@
 
 package com.google.devtools.build.skydoc;
 
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import java.io.IOException;
 import java.nio.file.Files;
@@ -26,9 +26,9 @@
 public class FilesystemFileAccessor implements SkylarkFileAccessor {
 
   @Override
-  public ParserInputSource inputSource(String pathString) throws IOException {
+  public ParserInput inputSource(String pathString) throws IOException {
     byte[] content = Files.readAllBytes(Paths.get(pathString));
-    return ParserInputSource.create(content, PathFragment.create(pathString));
+    return ParserInput.create(content, PathFragment.create(pathString));
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
index 8980630..021df19 100644
--- a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
+++ b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
@@ -61,7 +61,7 @@
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.MethodLibrary;
 import com.google.devtools.build.lib.syntax.Mutability;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.Runtime;
 import com.google.devtools.build.lib.syntax.SkylarkImport;
 import com.google.devtools.build.lib.syntax.StarlarkFunction;
@@ -426,7 +426,7 @@
     }
     pending.add(path);
 
-    ParserInputSource parserInputSource = getInputSource(path.toString());
+    ParserInput parserInputSource = getInputSource(path.toString());
     BuildFileAST buildFileAST = BuildFileAST.parse(parserInputSource, eventHandler);
 
     moduleDocMap.put(label, getModuleDoc(buildFileAST));
@@ -472,7 +472,7 @@
     return Paths.get(workspacePrefix + label.toPathFragment());
   }
 
-  private ParserInputSource getInputSource(String bzlWorkspacePath) throws IOException {
+  private ParserInput getInputSource(String bzlWorkspacePath) throws IOException {
     for (String rootPath : depRoots) {
       if (fileAccessor.fileExists(rootPath + "/" + bzlWorkspacePath)) {
         return fileAccessor.inputSource(rootPath + "/" + bzlWorkspacePath);
diff --git a/src/main/java/com/google/devtools/build/skydoc/SkylarkFileAccessor.java b/src/main/java/com/google/devtools/build/skydoc/SkylarkFileAccessor.java
index d4039c4..5f890af 100644
--- a/src/main/java/com/google/devtools/build/skydoc/SkylarkFileAccessor.java
+++ b/src/main/java/com/google/devtools/build/skydoc/SkylarkFileAccessor.java
@@ -14,7 +14,7 @@
 
 package com.google.devtools.build.skydoc;
 
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import java.io.IOException;
 
 /**
@@ -23,11 +23,8 @@
  */
 public interface SkylarkFileAccessor {
 
-  /**
-   * Returns a {@link ParserInputSource} for accessing the content of the given absolute path
-   * string.
-   */
-  ParserInputSource inputSource(String pathString) throws IOException;
+  /** Returns a {@link ParserInput} for accessing the content of the given absolute path string. */
+  ParserInput inputSource(String pathString) throws IOException;
 
   /** Returns true if a file exists at the current path. */
   boolean fileExists(String pathString);
diff --git a/src/main/java/com/google/devtools/starlark/Starlark.java b/src/main/java/com/google/devtools/starlark/Starlark.java
index 55d91d3..1f5abdb 100644
--- a/src/main/java/com/google/devtools/starlark/Starlark.java
+++ b/src/main/java/com/google/devtools/starlark/Starlark.java
@@ -20,7 +20,7 @@
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.Mutability;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.Printer;
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -91,7 +91,7 @@
     String line;
     while ((line = prompt()) != null) {
       try {
-        Object result = BuildFileAST.eval(ParserInputSource.fromLines(line), env);
+        Object result = BuildFileAST.eval(ParserInput.fromLines(line), env);
         if (result != null) {
           System.out.println(Printer.repr(result));
         }
@@ -116,7 +116,7 @@
   /** Execute a Starlark command. */
   public int execute(String content) {
     try {
-      ParserInputSource input = ParserInputSource.create(content, null);
+      ParserInput input = ParserInput.create(content, null);
       BuildFileAST.eval(input, env);
       return 0;
     } catch (EvalException e) {
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContextTest.java b/src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContextTest.java
index 278e659..eb6cbe5 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContextTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContextTest.java
@@ -39,7 +39,7 @@
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.Expression;
 import com.google.devtools.build.lib.syntax.FuncallExpression;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.testutil.Scratch;
 import com.google.devtools.build.lib.testutil.TestConstants;
 import com.google.devtools.build.lib.vfs.Path;
@@ -102,7 +102,7 @@
             RootedPath.toRootedPath(root, workspaceFile),
             "runfiles");
     ExtendedEventHandler listener = Mockito.mock(ExtendedEventHandler.class);
-    ParserInputSource input = ParserInputSource.fromLines("test()");
+    ParserInput input = ParserInput.fromLines("test()");
     FuncallExpression ast = (FuncallExpression) Expression.parse(input, listener);
     Rule rule =
         WorkspaceFactoryHelper.createAndAddRepositoryRule(
diff --git a/src/test/java/com/google/devtools/build/lib/packages/PackageFactoryTest.java b/src/test/java/com/google/devtools/build/lib/packages/PackageFactoryTest.java
index bdb9c8f..e88bf80 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/PackageFactoryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/PackageFactoryTest.java
@@ -29,7 +29,7 @@
 import com.google.devtools.build.lib.packages.util.PackageFactoryApparatus;
 import com.google.devtools.build.lib.packages.util.PackageFactoryTestBase;
 import com.google.devtools.build.lib.syntax.BuildFileAST;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.testutil.TestUtils;
 import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.build.lib.vfs.PathFragment;
@@ -1208,7 +1208,7 @@
     GlobPatternExtractor globPatternExtractor = new GlobPatternExtractor();
     globPatternExtractor.visit(
         BuildFileAST.parse(
-            ParserInputSource.fromLines(
+            ParserInput.fromLines(
                 "pattern = '*'",
                 "some_variable = glob([",
                 "  '**/*',",
diff --git a/src/test/java/com/google/devtools/build/lib/packages/WorkspaceFactoryTestHelper.java b/src/test/java/com/google/devtools/build/lib/packages/WorkspaceFactoryTestHelper.java
index 2e529bc..910f9ed 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/WorkspaceFactoryTestHelper.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/WorkspaceFactoryTestHelper.java
@@ -21,7 +21,7 @@
 import com.google.devtools.build.lib.events.Event;
 import com.google.devtools.build.lib.events.StoredEventHandler;
 import com.google.devtools.build.lib.syntax.Mutability;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.StarlarkSemantics;
 import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
@@ -82,7 +82,7 @@
       byte[] bytes =
           FileSystemUtils.readWithKnownFileSize(workspaceFilePath, workspaceFilePath.getFileSize());
       factory.parseForTesting(
-          ParserInputSource.create(bytes, workspaceFilePath.asFragment()),
+          ParserInput.create(bytes, workspaceFilePath.asFragment()),
           starlarkSemantics,
           eventHandler);
     } catch (BuildFileContainsErrorsException e) {
diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/PackageFactoryApparatus.java b/src/test/java/com/google/devtools/build/lib/packages/util/PackageFactoryApparatus.java
index 7919033..cc33b98 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/util/PackageFactoryApparatus.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/util/PackageFactoryApparatus.java
@@ -33,7 +33,7 @@
 import com.google.devtools.build.lib.packages.StarlarkSemanticsOptions;
 import com.google.devtools.build.lib.syntax.BuildFileAST;
 import com.google.devtools.build.lib.syntax.Environment.Extension;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.StarlarkSemantics;
 import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
 import com.google.devtools.build.lib.testutil.TestUtils;
@@ -141,7 +141,7 @@
    */
   public BuildFileAST ast(Path buildFile) throws IOException {
     byte[] bytes = FileSystemUtils.readWithKnownFileSize(buildFile, buildFile.getFileSize());
-    ParserInputSource input = ParserInputSource.create(bytes, buildFile.asFragment());
+    ParserInput input = ParserInput.create(bytes, buildFile.asFragment());
     return BuildFileAST.parse(input, eventHandler);
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
index ee94110..1a4b40a 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
@@ -53,7 +53,7 @@
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.EvalUtils;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.SkylarkDict;
 import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
 import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
@@ -703,7 +703,7 @@
   }
 
   protected void evalAndExport(String... lines) throws Exception {
-    ParserInputSource input = ParserInputSource.fromLines(lines);
+    ParserInput input = ParserInput.fromLines(lines);
     BuildFileAST file = BuildFileAST.parseAndValidateSkylark(input, ev.getEnvironment());
     SkylarkImportLookupFunction.execAndExport(
         file, FAKE_LABEL, ev.getEventHandler(), ev.getEnvironment());
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
index 78ab2ed..ff354c5 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
@@ -823,7 +823,7 @@
    * parameter of the template_action function contains a hack that assumes its input is a UTF-8
    * encoded string which has been ingested as Latin 1. The hack converts the string to its
    * "correct" UTF-8 value. Once {@link
-   * com.google.devtools.build.lib.syntax.ParserInputSource#create(byte[],
+   * com.google.devtools.build.lib.syntax.ParserInput#create(byte[],
    * com.google.devtools.build.lib.vfs.PathFragment)} parses files using UTF-8 and the hack for the
    * substituations parameter is removed, this test will fail.
    */
diff --git a/src/test/java/com/google/devtools/build/lib/skylarkdebug/server/SkylarkDebugServerTest.java b/src/test/java/com/google/devtools/build/lib/skylarkdebug/server/SkylarkDebugServerTest.java
index f082f4e..4d98f40 100644
--- a/src/test/java/com/google/devtools/build/lib/skylarkdebug/server/SkylarkDebugServerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylarkdebug/server/SkylarkDebugServerTest.java
@@ -41,7 +41,7 @@
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalUtils;
 import com.google.devtools.build.lib.syntax.Mutability;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.Runtime;
 import com.google.devtools.build.lib.syntax.SkylarkList;
 import com.google.devtools.build.lib.testutil.Scratch;
@@ -766,7 +766,7 @@
   private BuildFileAST parseBuildFile(String path, String... lines) throws IOException {
     Path file = scratch.file(path, lines);
     byte[] bytes = FileSystemUtils.readWithKnownFileSize(file, file.getFileSize());
-    ParserInputSource inputSource = ParserInputSource.create(bytes, file.asFragment());
+    ParserInput inputSource = ParserInput.create(bytes, file.asFragment());
     return BuildFileAST.parse(inputSource, events.reporter());
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java b/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java
index 505e366..87bb632 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java
@@ -47,7 +47,7 @@
   private BuildFileAST parseBuildFile(String... lines) throws IOException {
     Path file = scratch.file("/a/build/file/BUILD", lines);
     byte[] bytes = FileSystemUtils.readWithKnownFileSize(file, file.getFileSize());
-    ParserInputSource input = ParserInputSource.create(bytes, file.asFragment());
+    ParserInput input = ParserInput.create(bytes, file.asFragment());
     return BuildFileAST.parse(input, getEventHandler());
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentDebuggingTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentDebuggingTest.java
index 2c87598..f7d803d 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentDebuggingTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentDebuggingTest.java
@@ -190,7 +190,7 @@
     Environment env = newEnvironment();
     env.update("a", 1);
 
-    Object result = env.debugEval(ParserInputSource.create("a", null));
+    Object result = env.debugEval(ParserInput.create("a", null));
 
     assertThat(result).isEqualTo(1);
   }
@@ -201,7 +201,7 @@
     env.update("a", 1);
 
     EvalException e =
-        assertThrows(EvalException.class, () -> env.debugEval(ParserInputSource.create("b", null)));
+        assertThrows(EvalException.class, () -> env.debugEval(ParserInput.create("b", null)));
     assertThat(e).hasMessageThat().isEqualTo("name 'b' is not defined");
   }
 
@@ -211,12 +211,12 @@
     env.update("a", "string");
 
     Object result =
-        env.debugEval(ParserInputSource.create("a.startswith('str')", PathFragment.EMPTY_FRAGMENT));
+        env.debugEval(ParserInput.create("a.startswith('str')", PathFragment.EMPTY_FRAGMENT));
     assertThat(result).isEqualTo(Boolean.TRUE);
 
-    env.debugExec(ParserInputSource.create("a = 1", PathFragment.EMPTY_FRAGMENT));
+    env.debugExec(ParserInput.create("a = 1", PathFragment.EMPTY_FRAGMENT));
 
-    result = env.debugEval(ParserInputSource.create("a", PathFragment.EMPTY_FRAGMENT));
+    result = env.debugEval(ParserInput.create("a", PathFragment.EMPTY_FRAGMENT));
     assertThat(result).isEqualTo(1);
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
index 2c1f926..5be58ad 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
@@ -190,7 +190,7 @@
   @Test
   public void testBuiltinsCanBeShadowed() throws Exception {
     Environment env = newEnvironmentWithSkylarkOptions().setup("special_var", 42);
-    BuildFileAST.eval(ParserInputSource.fromLines("special_var = 41"), env);
+    BuildFileAST.eval(ParserInput.fromLines("special_var = 41"), env);
     assertThat(env.moduleLookup("special_var")).isEqualTo(41);
   }
 
@@ -199,8 +199,7 @@
     Environment env = newSkylarkEnvironment().update("global_var", 666);
     try {
       BuildFileAST.eval(
-          ParserInputSource.fromLines(
-              "def foo(x): x += global_var; global_var = 36; return x", "foo(1)"),
+          ParserInput.fromLines("def foo(x): x += global_var; global_var = 36; return x", "foo(1)"),
           env);
       throw new AssertionError("failed to fail");
     } catch (EvalExceptionWithStackTrace e) {
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/LValueBoundNamesTest.java b/src/test/java/com/google/devtools/build/lib/syntax/LValueBoundNamesTest.java
index 8832f9c..6be86ce 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/LValueBoundNamesTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/LValueBoundNamesTest.java
@@ -51,7 +51,7 @@
   }
 
   private static void assertBoundNames(String assignment, String... expectedBoundNames) {
-    ParserInputSource input = ParserInputSource.fromLines(assignment);
+    ParserInput input = ParserInput.fromLines(assignment);
     BuildFileAST file = BuildFileAST.parse(input, Environment.FAIL_FAST_HANDLER);
     Expression lhs = ((AssignmentStatement) file.getStatements().get(0)).getLHS();
     Set<String> boundNames =
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/LexerTest.java b/src/test/java/com/google/devtools/build/lib/syntax/LexerTest.java
index 77d237a..74bba9b 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/LexerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/LexerTest.java
@@ -42,7 +42,7 @@
    */
   private Lexer createLexer(String input) {
     PathFragment somePath = PathFragment.create("/some/path.txt");
-    ParserInputSource inputSource = ParserInputSource.create(input, somePath);
+    ParserInput inputSource = ParserInput.create(input, somePath);
     Reporter reporter = new Reporter(new EventBus());
     reporter.addHandler(new EventHandler() {
       @Override
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/NodeVisitorTest.java b/src/test/java/com/google/devtools/build/lib/syntax/NodeVisitorTest.java
index 09d1a62..1310076 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/NodeVisitorTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/NodeVisitorTest.java
@@ -27,7 +27,7 @@
 public final class NodeVisitorTest {
 
   private BuildFileAST parse(String... lines) throws IOException {
-    ParserInputSource input = ParserInputSource.fromLines(lines);
+    ParserInput input = ParserInput.fromLines(lines);
     return BuildFileAST.parse(input, Environment.FAIL_FAST_HANDLER);
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ParserInputSourceTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ParserInputTest.java
similarity index 81%
rename from src/test/java/com/google/devtools/build/lib/syntax/ParserInputSourceTest.java
rename to src/test/java/com/google/devtools/build/lib/syntax/ParserInputTest.java
index ce90e28..7871fb2 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/ParserInputSourceTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ParserInputTest.java
@@ -26,9 +26,9 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
-/** A test case for {@link ParserInputSource}. */
+/** A test case for {@link ParserInput}. */
 @RunWith(JUnit4.class)
-public class ParserInputSourceTest {
+public class ParserInputTest {
 
   private Scratch scratch = new Scratch();
 
@@ -37,7 +37,7 @@
     String content = joinLines("Line 1", "Line 2", "Line 3", "");
     Path file = scratch.file("/tmp/my/file.txt", content.getBytes(StandardCharsets.UTF_8));
     byte[] bytes = FileSystemUtils.readWithKnownFileSize(file, file.getFileSize());
-    ParserInputSource input = ParserInputSource.create(bytes, file.asFragment());
+    ParserInput input = ParserInput.create(bytes, file.asFragment());
     assertThat(new String(input.getContent())).isEqualTo(content);
     assertThat(input.getPath().toString()).isEqualTo("/tmp/my/file.txt");
   }
@@ -46,7 +46,7 @@
   public void testCreateFromString() {
     String content = "Content provided as a string.";
     String pathName = "/the/name/of/the/content.txt";
-    ParserInputSource input = ParserInputSource.create(content, PathFragment.create(pathName));
+    ParserInput input = ParserInput.create(content, PathFragment.create(pathName));
     assertThat(new String(input.getContent())).isEqualTo(content);
     assertThat(input.getPath().toString()).isEqualTo(pathName);
   }
@@ -56,20 +56,19 @@
     String content = "Content provided as a string.";
     String pathName = "/the/name/of/the/content.txt";
     char[] contentChars = content.toCharArray();
-    ParserInputSource input = ParserInputSource.create(contentChars, PathFragment.create(pathName));
+    ParserInput input = ParserInput.create(contentChars, PathFragment.create(pathName));
     assertThat(new String(input.getContent())).isEqualTo(content);
     assertThat(input.getPath().toString()).isEqualTo(pathName);
   }
 
   @Test
   public void testWillNotTryToReadInputFileIfContentProvidedAsString() {
-    ParserInputSource.create(
-        "Content provided as string.", PathFragment.create("/will/not/try/to/read"));
+    ParserInput.create("Content provided as string.", PathFragment.create("/will/not/try/to/read"));
   }
 
   @Test
   public void testWillNotTryToReadInputFileIfContentProvidedAsChars() {
     char[] content = "Content provided as char array.".toCharArray();
-    ParserInputSource.create(content, PathFragment.create("/will/not/try/to/read"));
+    ParserInput.create(content, PathFragment.create("/will/not/try/to/read"));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
index 349aaae..36ef855 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
@@ -37,7 +37,7 @@
 
   // Joins the lines, parses, and returns the file. No validation.
   private BuildFileAST parseFileWithComments(String... lines) {
-    ParserInputSource input = ParserInputSource.fromLines(lines);
+    ParserInput input = ParserInput.fromLines(lines);
     return BuildFileAST.parse(input, getEventHandler());
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java b/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java
index 37a7ce8..44fa80c 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java
@@ -33,7 +33,7 @@
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.Expression;
 import com.google.devtools.build.lib.syntax.Mutability;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.SkylarkUtils;
 import com.google.devtools.build.lib.syntax.SkylarkUtils.Phase;
 import com.google.devtools.build.lib.syntax.Statement;
@@ -159,7 +159,7 @@
   }
 
   protected final BuildFileAST parseBuildFileASTWithoutValidation(String... lines) {
-    ParserInputSource input = ParserInputSource.fromLines(lines);
+    ParserInput input = ParserInput.fromLines(lines);
     return BuildFileAST.parse(input, getEventHandler());
   }
 
@@ -183,7 +183,7 @@
 
   /** Parses an expression. */
   protected final Expression parseExpression(String... lines) {
-    return Expression.parse(ParserInputSource.fromLines(lines), getEventHandler());
+    return Expression.parse(ParserInput.fromLines(lines), getEventHandler());
   }
 
   public EvaluationTestCase update(String varname, Object value) throws Exception {
@@ -196,7 +196,7 @@
   }
 
   public Object eval(String... lines) throws Exception {
-    ParserInputSource input = ParserInputSource.fromLines(lines);
+    ParserInput input = ParserInput.fromLines(lines);
     if (testMode == TestMode.SKYLARK) {
       // TODO(adonovan): inline this call and factor with 'else' case.
       return BuildFileAST.eval(input, env);
diff --git a/src/test/java/com/google/devtools/build/skydoc/SkydocTest.java b/src/test/java/com/google/devtools/build/skydoc/SkydocTest.java
index fba1bdc..b71d34b0 100644
--- a/src/test/java/com/google/devtools/build/skydoc/SkydocTest.java
+++ b/src/test/java/com/google/devtools/build/skydoc/SkydocTest.java
@@ -22,7 +22,7 @@
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.skylark.util.SkylarkTestCase;
-import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.ParserInput;
 import com.google.devtools.build.lib.syntax.StarlarkFunction;
 import com.google.devtools.build.lib.syntax.StarlarkSemantics;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
@@ -60,10 +60,10 @@
             new SkylarkFileAccessor() {
 
               @Override
-              public ParserInputSource inputSource(String pathString) throws IOException {
+              public ParserInput inputSource(String pathString) throws IOException {
                 Path path = fileSystem.getPath("/" + pathString);
                 byte[] bytes = FileSystemUtils.asByteSource(path).read();
-                return ParserInputSource.create(bytes, path.asFragment());
+                return ParserInput.create(bytes, path.asFragment());
               }
 
               @Override