public record Label()

in og/shared/src/main/java/com/google/idea/blaze/common/Label.java [37:132]


public record Label(String workspace, String buildPackage, String name) {

  public static final String ROOT_WORKSPACE = "";

  public static Label of(String label) {
    Preconditions.checkArgument(!label.isBlank(), "Empty label");
    Preconditions.checkArgument(!label.contains("\\"), "Label contains backslashes: " + label);
    final var workspacePosition = label.startsWith("@") ? (label.startsWith("@@") ? 2 : 1) : 0;
    final var workspaceEnd = label.indexOf("//", workspacePosition);
    final var buildPackagePosition = workspaceEnd + 2;
    Preconditions.checkArgument(buildPackagePosition >= 2, "Invalid label: " + label);
    final var buildPackageEnd = label.indexOf(":", buildPackagePosition);
    final var namePosition = buildPackageEnd + 1;
    Preconditions.checkArgument(namePosition >= 1, "Invalid label: " + label);

    final var workspace = label.substring(workspacePosition, workspaceEnd);
    final var buildPackage = label.substring(buildPackagePosition, buildPackageEnd);
    final var name = label.substring(namePosition);
    return new Label(
        Interners.STRING.intern(workspace),
        Interners.STRING.intern(buildPackage),
        Interners.STRING.intern(name));
  }

  public static Label fromWorkspacePackageAndName(String workspace, Path packagePath, Path name) {
    String packageWithForwardSlashes = withForwardSlashes(packagePath);
    String nameWithForwardSlashes = withForwardSlashes(name);
    if (workspace.isEmpty()) {
      return Label.of(String.format("//%s:%s", packageWithForwardSlashes, nameWithForwardSlashes));
    } else {
      return Label.of(
          String.format(
              "@@%s//%s:%s", workspace, packageWithForwardSlashes, nameWithForwardSlashes));
    }
  }

  private static String withForwardSlashes(Path p) {
    StringBuilder res = new StringBuilder();
    p.iterator().forEachRemaining(part -> res.append(part).append("/"));
    // Remove the trailing slash
    return res.isEmpty() ? "" : res.substring(0, res.length() - 1);
  }

  public static Label fromWorkspacePackageAndName(String workspace, Path packagePath, String name) {
    return fromWorkspacePackageAndName(workspace, packagePath, Path.of(name));
  }

  public static ImmutableList<Label> toLabelList(List<String> labels) {
    return labels.stream().map(Label::of).collect(toImmutableList());
  }

  public Path getPackage() {
    return Path.of(buildPackage);
  }

  public Path getName() {
    return Path.of(name);
  }

  public String getWorkspaceName() {
    return workspace;
  }

  public Label siblingWithName(String name) {
    return fromWorkspacePackageAndName(getWorkspaceName(), getPackage(), name);
  }

  public Label siblingWithPathAndName(String pathAndName) {
    int colonPos = pathAndName.indexOf(':');
    Preconditions.checkArgument(colonPos > 0, pathAndName);
    return fromWorkspacePackageAndName(
        getWorkspaceName(),
        getPackage().resolve(pathAndName.substring(0, colonPos)),
        pathAndName.substring(colonPos + 1));
  }

  /** When this label refers to a source file, returns the workspace relative path to that file. */
  public Path toFilePath() {
    return getPackage().resolve(getName());
  }

  @Override
  public String toString() {
    final var result =
        new StringBuilder(5 + workspace.length() + buildPackage.length() + name.length());
    if (!workspace.isEmpty()) {
      result.append("@@");
      result.append(workspace);
    }
    result.append("//");
    result.append(buildPackage);
    result.append(":");
    result.append(name);
    return result.toString();
  }
}