Aspect-side compatibility with pending external workspace changes.

PiperOrigin-RevId: 152979269
diff --git a/tools/ide/intellij_info_impl.bzl b/tools/ide/intellij_info_impl.bzl
index 89ce97f..e375288 100644
--- a/tools/ide/intellij_info_impl.bzl
+++ b/tools/ide/intellij_info_impl.bzl
@@ -48,39 +48,66 @@
   if f == None:
     return None
 
-  return struct_omit_none(
-      relative_path = get_relative_path(f),
-      is_source = f.is_source,
-      is_external = is_external(f.owner),
-      root_execution_path_fragment = f.root.path if not f.is_source else None,
+  return to_artifact_location(
+      f.path,
+      f.root.path if not f.is_source else "",
+      f.is_source,
+      is_external_artifact(f.owner),
   )
 
-def is_external(label):
+def to_artifact_location(exec_path, root_exec_path_fragment, is_source, is_external):
+  """Derives workspace path from other path fragments, and creates an ArtifactLocation proto."""
+  # Bazel 0.4.4 has directory structure:
+  # exec_path = (root_fragment)? + (external/repo_name)? + relative_path
+  # Bazel 0.4.5 has planned directory structure:
+  # exec_path = (../repo_name)? + (root_fragment)? + relative_path
+  # Handle both cases by trying to strip the external workspace prefix before and after removing
+  # root_exec_path_fragment.
+  relative_path = strip_external_workspace_prefix(exec_path)
+  relative_path = strip_root_exec_path_fragment(relative_path, root_exec_path_fragment)
+  # Remove this line when Bazel 0.4.4 and earlier no longer need to be supported.
+  relative_path = strip_external_workspace_prefix(relative_path)
+
+  root_exec_path_fragment = exec_path[:-(len("/" + relative_path))]
+
+  return struct_omit_none(
+      relative_path = relative_path,
+      is_source = is_source,
+      is_external = is_external,
+      root_execution_path_fragment = root_exec_path_fragment,
+      is_new_external_version = True,
+  )
+
+def strip_root_exec_path_fragment(path, root_fragment):
+  if root_fragment and path.startswith(root_fragment + "/"):
+    return path[len(root_fragment + "/"):]
+  return path
+
+def strip_external_workspace_prefix(path):
+  """Either 'external/workspace_name/' or '../workspace_name/'."""
+  # Label.EXTERNAL_PATH_PREFIX is due to change from 'external' to '..' in Bazel 0.4.5.
+  # This code is for forwards and backwards compatibility.
+  # Remove the 'external/' check when Bazel 0.4.4 and earlier no longer need to be supported.
+  if path.startswith("../") or path.startswith("external/"):
+    return "/".join(path.split("/")[2:])
+  return path
+
+def is_external_artifact(label):
   """Determines whether a label corresponds to an external artifact."""
-  return label.workspace_root.startswith("external")
-
-def get_relative_path(artifact):
-  """A temporary workaround to find the root-relative path from an artifact.
-
-  This is required because 'short_path' is incorrect for external source artifacts.
-
-  Args:
-    artifact: the input artifact
-  Returns:
-    string: the root-relative path for this artifact.
-  """
-  # TODO(bazel-team): remove this workaround when Artifact::short_path is fixed.
-  if is_external(artifact.owner) and artifact.short_path.startswith(".."):
-    # short_path is '../repo_name/path', we want 'external/repo_name/path'
-    return "external" + artifact.short_path[2:]
-  return artifact.short_path
+  # Label.EXTERNAL_PATH_PREFIX is due to change from 'external' to '..' in Bazel 0.4.5.
+  # This code is for forwards and backwards compatibility.
+  # Remove the 'external' check when Bazel 0.4.4 and earlier no longer need to be supported.
+  return label.workspace_root.startswith("external") or label.workspace_root.startswith("..")
 
 def source_directory_tuple(resource_file):
-  """Creates a tuple of (source directory, is_source, root execution path)."""
+  """Creates a tuple of (exec_path, root_exec_path_fragment, is_source, is_external)."""
+  relative_path = str(android_common.resource_source_directory(resource_file))
+  root_exec_path_fragment = resource_file.root.path if not resource_file.is_source else None
   return (
-      str(android_common.resource_source_directory(resource_file)),
+      relative_path if resource_file.is_source else root_exec_path_fragment + relative_path,
+      root_exec_path_fragment,
       resource_file.is_source,
-      resource_file.root.path if not resource_file.is_source else None
+      is_external_artifact(resource_file.owner)
   )
 
 def all_unique_source_directories(resources):
@@ -88,17 +115,20 @@
   # Sets can contain tuples, but cannot contain structs.
   # Use set of tuples to unquify source directories.
   source_directory_tuples = set([source_directory_tuple(f) for f in resources])
-  return [struct_omit_none(relative_path = relative_path,
-                           is_source = is_source,
-                           root_execution_path_fragment = root_execution_path_fragment)
-          for (relative_path, is_source, root_execution_path_fragment) in source_directory_tuples]
+  return [to_artifact_location(
+      exec_path,
+      root_path_fragment,
+      is_source,
+      is_external)
+          for (exec_path, root_path_fragment, is_source, is_external) in source_directory_tuples]
 
 def build_file_artifact_location(ctx):
   """Creates an ArtifactLocation proto representing a location of a given BUILD file."""
-  return struct(
-      relative_path = ctx.build_file_path,
-      is_source = True,
-      is_external = is_external(ctx.label)
+  return to_artifact_location(
+      ctx.build_file_path,
+      ctx.build_file_path,
+      True,
+      is_external_artifact(ctx.label)
   )
 
 def library_artifact(java_output):
@@ -343,7 +373,9 @@
   return (java_ide_info, ide_info_files, intellij_resolve_files)
 
 def _package_manifest_file_argument(f):
-  return f.root.path + "," + f.short_path + "," + ("1" if is_external(f.owner) else "0")
+  artifact = artifact_location(f)
+  is_external = "1" if is_external_artifact(f.owner) else "0"
+  return artifact.root_execution_path_fragment + "," + artifact.relative_path + "," + is_external
 
 def build_java_package_manifest(ctx, target, source_files, suffix):
   """Builds the java package manifest for the given source files."""