Split bazel -path functions and clarify docs

Test: go test
Change-Id: I62f58998fc7d52c67ed5acfdb8230d404b2a5472
diff --git a/android/Android.bp b/android/Android.bp
index f5e5606..62d5e20 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -26,6 +26,7 @@
         "arch_list.go",
         "bazel.go",
         "bazel_handler.go",
+        "bazel_paths.go",
         "config.go",
         "csuite_config.go",
         "deapexer.go",
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
new file mode 100644
index 0000000..13f4949
--- /dev/null
+++ b/android/bazel_paths.go
@@ -0,0 +1,353 @@
+// Copyright 2015 Google Inc. 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 android
+
+import (
+	"android/soong/bazel"
+	"fmt"
+	"path/filepath"
+	"strings"
+
+	"github.com/google/blueprint"
+	"github.com/google/blueprint/pathtools"
+)
+
+// bazel_paths contains methods to:
+//   * resolve Soong path and module references into bazel.LabelList
+//   * resolve Bazel path references into Soong-compatible paths
+//
+// There is often a similar method for Bazel as there is for Soong path handling and should be used
+// in similar circumstances
+//
+// Bazel                                Soong
+//
+// BazelLabelForModuleSrc               PathForModuleSrc
+// BazelLabelForModuleSrcExcludes       PathForModuleSrcExcludes
+// BazelLabelForModuleDeps              n/a
+// tbd                                  PathForSource
+// tbd                                  ExistentPathsForSources
+// PathForBazelOut                      PathForModuleOut
+//
+// Use cases:
+//  * Module contains a property (often tagged `android:"path"`) that expects paths *relative to the
+//    module directory*:
+//     * BazelLabelForModuleSrcExcludes, if the module also contains an excludes_<propname> property
+//     * BazelLabelForModuleSrc, otherwise
+//  * Converting references to other modules to Bazel Labels:
+//     BazelLabelForModuleDeps
+//  * Converting a path obtained from bazel_handler cquery results:
+//     PathForBazelOut
+//
+// NOTE: all Soong globs are expanded within Soong rather than being converted to a Bazel glob
+//       syntax. This occurs because Soong does not have a concept of crossing package boundaries,
+//       so the glob as computed by Soong may contain paths that cross package-boundaries. These
+//       would be unknowingly omitted if the glob were handled by Bazel. By expanding globs within
+//       Soong, we support identification and detection (within Bazel) use of paths that cross
+//       package boundaries.
+//
+// Path resolution:
+// * filepath/globs: resolves as itself or is converted to an absolute Bazel label (e.g.
+//   //path/to/dir:<filepath>) if path exists in a separate package or subpackage.
+// * references to other modules (using the ":name{.tag}" syntax). These resolve as a Bazel label
+//   for a target. If the Bazel target is in the local module directory, it will be returned
+//   relative to the current package (e.g.  ":<target>"). Otherwise, it will be returned as an
+//   absolute Bazel label (e.g.  "//path/to/dir:<target>"). If the reference to another module
+//   cannot be resolved,the function will panic. This is often due to the dependency not being added
+//   via an AddDependency* method.
+
+// A subset of the ModuleContext methods which are sufficient to resolve references to paths/deps in
+// order to form a Bazel-compatible label for conversion.
+type BazelConversionPathContext interface {
+	EarlyModulePathContext
+
+	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
+	Module() Module
+	ModuleType() string
+	OtherModuleName(m blueprint.Module) string
+	OtherModuleDir(m blueprint.Module) string
+}
+
+// BazelLabelForModuleDeps expects a list of reference to other modules, ("<module>"
+// or ":<module>") and returns a Bazel-compatible label which corresponds to dependencies on the
+// module within the given ctx.
+func BazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string) bazel.LabelList {
+	var labels bazel.LabelList
+	for _, module := range modules {
+		bpText := module
+		if m := SrcIsModule(module); m == "" {
+			module = ":" + module
+		}
+		if m, t := SrcIsModuleWithTag(module); m != "" {
+			l := getOtherModuleLabel(ctx, m, t)
+			l.Bp_text = bpText
+			labels.Includes = append(labels.Includes, l)
+		} else {
+			ctx.ModuleErrorf("%q, is not a module reference", module)
+		}
+	}
+	return labels
+}
+
+// BazelLabelForModuleSrc expects a list of path (relative to local module directory) and module
+// references (":<module>") and returns a bazel.LabelList{} containing the resolved references in
+// paths, relative to the local module, or Bazel-labels (absolute if in a different package or
+// relative if within the same package).
+// Properties must have been annotated with struct tag `android:"path"` so that dependencies modules
+// will have already been handled by the path_deps mutator.
+func BazelLabelForModuleSrc(ctx BazelConversionPathContext, paths []string) bazel.LabelList {
+	return BazelLabelForModuleSrcExcludes(ctx, paths, []string(nil))
+}
+
+// BazelLabelForModuleSrc expects lists of path and excludes (relative to local module directory)
+// and module references (":<module>") and returns a bazel.LabelList{} containing the resolved
+// references in paths, minus those in excludes, relative to the local module, or Bazel-labels
+// (absolute if in a different package or relative if within the same package).
+// Properties must have been annotated with struct tag `android:"path"` so that dependencies modules
+// will have already been handled by the path_deps mutator.
+func BazelLabelForModuleSrcExcludes(ctx BazelConversionPathContext, paths, excludes []string) bazel.LabelList {
+	excludeLabels := expandSrcsForBazel(ctx, excludes, []string(nil))
+	excluded := make([]string, 0, len(excludeLabels.Includes))
+	for _, e := range excludeLabels.Includes {
+		excluded = append(excluded, e.Label)
+	}
+	labels := expandSrcsForBazel(ctx, paths, excluded)
+	labels.Excludes = excludeLabels.Includes
+	labels = transformSubpackagePaths(ctx, labels)
+	return labels
+}
+
+// Returns true if a prefix + components[:i] + /Android.bp exists
+// TODO(b/185358476) Could check for BUILD file instead of checking for Android.bp file, or ensure BUILD is always generated?
+func directoryHasBlueprint(fs pathtools.FileSystem, prefix string, components []string, componentIndex int) bool {
+	blueprintPath := prefix
+	if blueprintPath != "" {
+		blueprintPath = blueprintPath + "/"
+	}
+	blueprintPath = blueprintPath + strings.Join(components[:componentIndex+1], "/")
+	blueprintPath = blueprintPath + "/Android.bp"
+	if exists, _, _ := fs.Exists(blueprintPath); exists {
+		return true
+	} else {
+		return false
+	}
+}
+
+// Transform a path (if necessary) to acknowledge package boundaries
+//
+// e.g. something like
+//   async_safe/include/async_safe/CHECK.h
+// might become
+//   //bionic/libc/async_safe:include/async_safe/CHECK.h
+// if the "async_safe" directory is actually a package and not just a directory.
+//
+// In particular, paths that extend into packages are transformed into absolute labels beginning with //.
+func transformSubpackagePath(ctx BazelConversionPathContext, path bazel.Label) bazel.Label {
+	var newPath bazel.Label
+
+	// Don't transform Bp_text
+	newPath.Bp_text = path.Bp_text
+
+	if strings.HasPrefix(path.Label, "//") {
+		// Assume absolute labels are already correct (e.g. //path/to/some/package:foo.h)
+		newPath.Label = path.Label
+		return newPath
+	}
+
+	newLabel := ""
+	pathComponents := strings.Split(path.Label, "/")
+	foundBlueprint := false
+	// Check the deepest subdirectory first and work upwards
+	for i := len(pathComponents) - 1; i >= 0; i-- {
+		pathComponent := pathComponents[i]
+		var sep string
+		if !foundBlueprint && directoryHasBlueprint(ctx.Config().fs, ctx.ModuleDir(), pathComponents, i) {
+			sep = ":"
+			foundBlueprint = true
+		} else {
+			sep = "/"
+		}
+		if newLabel == "" {
+			newLabel = pathComponent
+		} else {
+			newLabel = pathComponent + sep + newLabel
+		}
+	}
+	if foundBlueprint {
+		// Ensure paths end up looking like //bionic/... instead of //./bionic/...
+		moduleDir := ctx.ModuleDir()
+		if strings.HasPrefix(moduleDir, ".") {
+			moduleDir = moduleDir[1:]
+		}
+		// Make the path into an absolute label (e.g. //bionic/libc/foo:bar.h instead of just foo:bar.h)
+		if moduleDir == "" {
+			newLabel = "//" + newLabel
+		} else {
+			newLabel = "//" + moduleDir + "/" + newLabel
+		}
+	}
+	newPath.Label = newLabel
+
+	return newPath
+}
+
+// Transform paths to acknowledge package boundaries
+// See transformSubpackagePath() for more information
+func transformSubpackagePaths(ctx BazelConversionPathContext, paths bazel.LabelList) bazel.LabelList {
+	var newPaths bazel.LabelList
+	for _, include := range paths.Includes {
+		newPaths.Includes = append(newPaths.Includes, transformSubpackagePath(ctx, include))
+	}
+	for _, exclude := range paths.Excludes {
+		newPaths.Excludes = append(newPaths.Excludes, transformSubpackagePath(ctx, exclude))
+	}
+	return newPaths
+}
+
+// expandSrcsForBazel returns bazel.LabelList with paths rooted from the module's local source
+// directory and Bazel target labels, excluding those included in the excludes argument (which
+// should already be expanded to resolve references to Soong-modules). Valid elements of paths
+// include:
+// * filepath, relative to local module directory, resolves as a filepath relative to the local
+//   source directory
+// * glob, relative to the local module directory, resolves as filepath(s), relative to the local
+//    module directory. Because Soong does not have a concept of crossing package boundaries, the
+//    glob as computed by Soong may contain paths that cross package-boundaries that would be
+//    unknowingly omitted if the glob were handled by Bazel. To allow identification and detect
+//    (within Bazel) use of paths that cross package boundaries, we expand globs within Soong rather
+//    than converting Soong glob syntax to Bazel glob syntax. **Invalid for excludes.**
+// * other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer
+//    or OutputFileProducer. These resolve as a Bazel label for a target. If the Bazel target is in
+//    the local module directory, it will be returned relative to the current package (e.g.
+//    ":<target>"). Otherwise, it will be returned as an absolute Bazel label (e.g.
+//    "//path/to/dir:<target>"). If the reference to another module cannot be resolved,the function
+//    will panic.
+// Properties passed as the paths or excludes argument must have been annotated with struct tag
+// `android:"path"` so that dependencies on other modules will have already been handled by the
+// path_deps mutator.
+func expandSrcsForBazel(ctx BazelConversionPathContext, paths, expandedExcludes []string) bazel.LabelList {
+	if paths == nil {
+		return bazel.LabelList{}
+	}
+	labels := bazel.LabelList{
+		Includes: []bazel.Label{},
+	}
+	for _, p := range paths {
+		if m, tag := SrcIsModuleWithTag(p); m != "" {
+			l := getOtherModuleLabel(ctx, m, tag)
+			if !InList(l.Label, expandedExcludes) {
+				l.Bp_text = fmt.Sprintf(":%s", m)
+				labels.Includes = append(labels.Includes, l)
+			}
+		} else {
+			var expandedPaths []bazel.Label
+			if pathtools.IsGlob(p) {
+				globbedPaths := GlobFiles(ctx, pathForModuleSrc(ctx, p).String(), expandedExcludes)
+				globbedPaths = PathsWithModuleSrcSubDir(ctx, globbedPaths, "")
+				for _, path := range globbedPaths {
+					s := path.Rel()
+					expandedPaths = append(expandedPaths, bazel.Label{Label: s})
+				}
+			} else {
+				if !InList(p, expandedExcludes) {
+					expandedPaths = append(expandedPaths, bazel.Label{Label: p})
+				}
+			}
+			labels.Includes = append(labels.Includes, expandedPaths...)
+		}
+	}
+	return labels
+}
+
+// getOtherModuleLabel returns a bazel.Label for the given dependency/tag combination for the
+// module. The label will be relative to the current directory if appropriate. The dependency must
+// already be resolved by either deps mutator or path deps mutator.
+func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string) bazel.Label {
+	m, _ := ctx.GetDirectDep(dep)
+	if m == nil {
+		panic(fmt.Errorf(`Cannot get direct dep %q of %q.
+		This is likely because it was not added via AddDependency().
+		This may be due a mutator skipped during bp2build.`, dep, ctx.Module().Name()))
+	}
+	otherLabel := bazelModuleLabel(ctx, m, tag)
+	label := bazelModuleLabel(ctx, ctx.Module(), "")
+	if samePackage(label, otherLabel) {
+		otherLabel = bazelShortLabel(otherLabel)
+	}
+
+	return bazel.Label{
+		Label: otherLabel,
+	}
+}
+
+func bazelModuleLabel(ctx BazelConversionPathContext, module blueprint.Module, tag string) string {
+	// TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets.
+	b, ok := module.(Bazelable)
+	// TODO(b/181155349): perhaps return an error here if the module can't be/isn't being converted
+	if !ok || !b.ConvertedToBazel(ctx) {
+		return bp2buildModuleLabel(ctx, module)
+	}
+	return b.GetBazelLabel(ctx, module)
+}
+
+func bazelShortLabel(label string) string {
+	i := strings.Index(label, ":")
+	return label[i:]
+}
+
+func bazelPackage(label string) string {
+	i := strings.Index(label, ":")
+	return label[0:i]
+}
+
+func samePackage(label1, label2 string) bool {
+	return bazelPackage(label1) == bazelPackage(label2)
+}
+
+func bp2buildModuleLabel(ctx BazelConversionPathContext, module blueprint.Module) string {
+	moduleName := ctx.OtherModuleName(module)
+	moduleDir := ctx.OtherModuleDir(module)
+	return fmt.Sprintf("//%s:%s", moduleDir, moduleName)
+}
+
+// BazelOutPath is a Bazel output path compatible to be used for mixed builds within Soong/Ninja.
+type BazelOutPath struct {
+	OutputPath
+}
+
+var _ Path = BazelOutPath{}
+var _ objPathProvider = BazelOutPath{}
+
+func (p BazelOutPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath {
+	return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
+}
+
+// PathForBazelOut returns a Path representing the paths... under an output directory dedicated to
+// bazel-owned outputs.
+func PathForBazelOut(ctx PathContext, paths ...string) BazelOutPath {
+	execRootPathComponents := append([]string{"execroot", "__main__"}, paths...)
+	execRootPath := filepath.Join(execRootPathComponents...)
+	validatedExecRootPath, err := validatePath(execRootPath)
+	if err != nil {
+		reportPathError(ctx, err)
+	}
+
+	outputPath := OutputPath{basePath{"", ""},
+		ctx.Config().buildDir,
+		ctx.Config().BazelContext.OutputBase()}
+
+	return BazelOutPath{
+		OutputPath: outputPath.withRel(validatedExecRootPath),
+	}
+}
diff --git a/android/paths.go b/android/paths.go
index c303c38..026cb87 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -15,7 +15,6 @@
 package android
 
 import (
-	"android/soong/bazel"
 	"fmt"
 	"io/ioutil"
 	"os"
@@ -356,23 +355,42 @@
 	return ret
 }
 
-// PathsForModuleSrc returns Paths rooted from the module's local source directory.  It expands globs, references to
-// SourceFileProducer modules using the ":name" syntax, and references to OutputFileProducer modules using the
-// ":name{.tag}" syntax.  Properties passed as the paths argument must have been annotated with struct tag
+// PathsForModuleSrc returns a Paths{} containing the resolved references in paths:
+// * filepath, relative to local module directory, resolves as a filepath relative to the local
+//   source directory
+// * glob, relative to the local module directory, resolves as filepath(s), relative to the local
+//  source directory.
+// * other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer
+//    or OutputFileProducer. These resolve as a filepath to an output filepath or generated source
+//    filepath.
+// Properties passed as the paths argument must have been annotated with struct tag
 // `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the
-// path_properties mutator.  If ctx.Config().AllowMissingDependencies() is true then any missing SourceFileProducer or
-// OutputFileProducer dependencies will cause the module to be marked as having missing dependencies.
+// path_deps mutator.
+// If a requested module is not found as a dependency:
+//   * if ctx.Config().AllowMissingDependencies() is true, this module to be marked as having
+//     missing dependencies
+//   * otherwise, a ModuleError is thrown.
 func PathsForModuleSrc(ctx ModuleMissingDepsPathContext, paths []string) Paths {
 	return PathsForModuleSrcExcludes(ctx, paths, nil)
 }
 
-// PathsForModuleSrcExcludes returns Paths rooted from the module's local source directory, excluding paths listed in
-// the excludes arguments.  It expands globs, references to SourceFileProducer modules using the ":name" syntax, and
-// references to OutputFileProducer modules using the ":name{.tag}" syntax.  Properties passed as the paths or excludes
-// argument must have been annotated with struct tag `android:"path"` so that dependencies on SourceFileProducer modules
-// will have already been handled by the path_properties mutator.  If ctx.Config().AllowMissingDependencies() is
-// true then any missing SourceFileProducer or OutputFileProducer dependencies will cause the module to be marked as
-// having missing dependencies.
+// PathsForModuleSrcExcludes returns a Paths{} containing the resolved references in paths, minus
+// those listed in excludes. Elements of paths and excludes are resolved as:
+// * filepath, relative to local module directory, resolves as a filepath relative to the local
+//   source directory
+// * glob, relative to the local module directory, resolves as filepath(s), relative to the local
+//  source directory. Not valid in excludes.
+// * other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer
+//    or OutputFileProducer. These resolve as a filepath to an output filepath or generated source
+//    filepath.
+// excluding the items (similarly resolved
+// Properties passed as the paths argument must have been annotated with struct tag
+// `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the
+// path_deps mutator.
+// If a requested module is not found as a dependency:
+//   * if ctx.Config().AllowMissingDependencies() is true, this module to be marked as having
+//     missing dependencies
+//   * otherwise, a ModuleError is thrown.
 func PathsForModuleSrcExcludes(ctx ModuleMissingDepsPathContext, paths, excludes []string) Paths {
 	ret, missingDeps := PathsAndMissingDepsForModuleSrcExcludes(ctx, paths, excludes)
 	if ctx.Config().AllowMissingDependencies() {
@@ -385,247 +403,6 @@
 	return ret
 }
 
-// A subset of the ModuleContext methods which are sufficient to resolve references to paths/deps in
-// order to form a Bazel-compatible label for conversion.
-type BazelConversionPathContext interface {
-	EarlyModulePathContext
-
-	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
-	Module() Module
-	ModuleType() string
-	OtherModuleName(m blueprint.Module) string
-	OtherModuleDir(m blueprint.Module) string
-}
-
-// BazelLabelForModuleDeps returns a Bazel-compatible label for the requested modules which
-// correspond to dependencies on the module within the given ctx.
-func BazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string) bazel.LabelList {
-	var labels bazel.LabelList
-	for _, module := range modules {
-		bpText := module
-		if m := SrcIsModule(module); m == "" {
-			module = ":" + module
-		}
-		if m, t := SrcIsModuleWithTag(module); m != "" {
-			l := getOtherModuleLabel(ctx, m, t)
-			l.Bp_text = bpText
-			labels.Includes = append(labels.Includes, l)
-		} else {
-			ctx.ModuleErrorf("%q, is not a module reference", module)
-		}
-	}
-	return labels
-}
-
-// Returns true if a prefix + components[:i] + /Android.bp exists
-// TODO(b/185358476) Could check for BUILD file instead of checking for Android.bp file, or ensure BUILD is always generated?
-func directoryHasBlueprint(fs pathtools.FileSystem, prefix string, components []string, componentIndex int) bool {
-	blueprintPath := prefix
-	if blueprintPath != "" {
-		blueprintPath = blueprintPath + "/"
-	}
-	blueprintPath = blueprintPath + strings.Join(components[:componentIndex+1], "/")
-	blueprintPath = blueprintPath + "/Android.bp"
-	if exists, _, _ := fs.Exists(blueprintPath); exists {
-		return true
-	} else {
-		return false
-	}
-}
-
-// Transform a path (if necessary) to acknowledge package boundaries
-//
-// e.g. something like
-//   async_safe/include/async_safe/CHECK.h
-// might become
-//   //bionic/libc/async_safe:include/async_safe/CHECK.h
-// if the "async_safe" directory is actually a package and not just a directory.
-//
-// In particular, paths that extend into packages are transformed into absolute labels beginning with //.
-func transformSubpackagePath(ctx BazelConversionPathContext, path bazel.Label) bazel.Label {
-	var newPath bazel.Label
-
-	// Don't transform Bp_text
-	newPath.Bp_text = path.Bp_text
-
-	if strings.HasPrefix(path.Label, "//") {
-		// Assume absolute labels are already correct (e.g. //path/to/some/package:foo.h)
-		newPath.Label = path.Label
-		return newPath
-	}
-
-	newLabel := ""
-	pathComponents := strings.Split(path.Label, "/")
-	foundBlueprint := false
-	// Check the deepest subdirectory first and work upwards
-	for i := len(pathComponents) - 1; i >= 0; i-- {
-		pathComponent := pathComponents[i]
-		var sep string
-		if !foundBlueprint && directoryHasBlueprint(ctx.Config().fs, ctx.ModuleDir(), pathComponents, i) {
-			sep = ":"
-			foundBlueprint = true
-		} else {
-			sep = "/"
-		}
-		if newLabel == "" {
-			newLabel = pathComponent
-		} else {
-			newLabel = pathComponent + sep + newLabel
-		}
-	}
-	if foundBlueprint {
-		// Ensure paths end up looking like //bionic/... instead of //./bionic/...
-		moduleDir := ctx.ModuleDir()
-		if strings.HasPrefix(moduleDir, ".") {
-			moduleDir = moduleDir[1:]
-		}
-		// Make the path into an absolute label (e.g. //bionic/libc/foo:bar.h instead of just foo:bar.h)
-		if moduleDir == "" {
-			newLabel = "//" + newLabel
-		} else {
-			newLabel = "//" + moduleDir + "/" + newLabel
-		}
-	}
-	newPath.Label = newLabel
-
-	return newPath
-}
-
-// Transform paths to acknowledge package boundaries
-// See transformSubpackagePath() for more information
-func transformSubpackagePaths(ctx BazelConversionPathContext, paths bazel.LabelList) bazel.LabelList {
-	var newPaths bazel.LabelList
-	for _, include := range paths.Includes {
-		newPaths.Includes = append(newPaths.Includes, transformSubpackagePath(ctx, include))
-	}
-	for _, exclude := range paths.Excludes {
-		newPaths.Excludes = append(newPaths.Excludes, transformSubpackagePath(ctx, exclude))
-	}
-	return newPaths
-}
-
-// BazelLabelForModuleSrc returns bazel.LabelList with paths rooted from the module's local source
-// directory. It expands globs, and resolves references to modules using the ":name" syntax to
-// bazel-compatible labels.  Properties passed as the paths or excludes argument must have been
-// annotated with struct tag `android:"path"` so that dependencies on other modules will have
-// already been handled by the path_properties mutator.
-//
-// With expanded globs, we can catch package boundaries problem instead of
-// silently failing to potentially missing files from Bazel's globs.
-func BazelLabelForModuleSrc(ctx BazelConversionPathContext, paths []string) bazel.LabelList {
-	return BazelLabelForModuleSrcExcludes(ctx, paths, []string(nil))
-}
-
-// BazelLabelForModuleSrcExcludes returns bazel.LabelList with paths rooted from the module's local
-// source directory, excluding labels included in the excludes argument. It expands globs, and
-// resolves references to modules using the ":name" syntax to bazel-compatible labels. Properties
-// passed as the paths or excludes argument must have been annotated with struct tag
-// `android:"path"` so that dependencies on other modules will have already been handled by the
-// path_properties mutator.
-//
-// With expanded globs, we can catch package boundaries problem instead of
-// silently failing to potentially missing files from Bazel's globs.
-func BazelLabelForModuleSrcExcludes(ctx BazelConversionPathContext, paths, excludes []string) bazel.LabelList {
-	excludeLabels := expandSrcsForBazel(ctx, excludes, []string(nil))
-	excluded := make([]string, 0, len(excludeLabels.Includes))
-	for _, e := range excludeLabels.Includes {
-		excluded = append(excluded, e.Label)
-	}
-	labels := expandSrcsForBazel(ctx, paths, excluded)
-	labels.Excludes = excludeLabels.Includes
-	labels = transformSubpackagePaths(ctx, labels)
-	return labels
-}
-
-// expandSrcsForBazel returns bazel.LabelList with paths rooted from the module's local
-// source directory, excluding labels included in the excludes argument. It expands globs, and
-// resolves references to modules using the ":name" syntax to bazel-compatible labels.  Properties
-// passed as the paths or excludes argument must have been annotated with struct tag
-// `android:"path"` so that dependencies on other modules will have already been handled by the
-// path_properties mutator.
-func expandSrcsForBazel(ctx BazelConversionPathContext, paths, expandedExcludes []string) bazel.LabelList {
-	if paths == nil {
-		return bazel.LabelList{}
-	}
-	labels := bazel.LabelList{
-		Includes: []bazel.Label{},
-	}
-	for _, p := range paths {
-		if m, tag := SrcIsModuleWithTag(p); m != "" {
-			l := getOtherModuleLabel(ctx, m, tag)
-			if !InList(l.Label, expandedExcludes) {
-				l.Bp_text = fmt.Sprintf(":%s", m)
-				labels.Includes = append(labels.Includes, l)
-			}
-		} else {
-			var expandedPaths []bazel.Label
-			if pathtools.IsGlob(p) {
-				globbedPaths := GlobFiles(ctx, pathForModuleSrc(ctx, p).String(), expandedExcludes)
-				globbedPaths = PathsWithModuleSrcSubDir(ctx, globbedPaths, "")
-				for _, path := range globbedPaths {
-					s := path.Rel()
-					expandedPaths = append(expandedPaths, bazel.Label{Label: s})
-				}
-			} else {
-				if !InList(p, expandedExcludes) {
-					expandedPaths = append(expandedPaths, bazel.Label{Label: p})
-				}
-			}
-			labels.Includes = append(labels.Includes, expandedPaths...)
-		}
-	}
-	return labels
-}
-
-// getOtherModuleLabel returns a bazel.Label for the given dependency/tag combination for the
-// module. The label will be relative to the current directory if appropriate. The dependency must
-// already be resolved by either deps mutator or path deps mutator.
-func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string) bazel.Label {
-	m, _ := ctx.GetDirectDep(dep)
-	if m == nil {
-		panic(fmt.Errorf("cannot get direct dep %s of %s", dep, ctx.Module().Name()))
-	}
-	otherLabel := bazelModuleLabel(ctx, m, tag)
-	label := bazelModuleLabel(ctx, ctx.Module(), "")
-	if samePackage(label, otherLabel) {
-		otherLabel = bazelShortLabel(otherLabel)
-	}
-
-	return bazel.Label{
-		Label: otherLabel,
-	}
-}
-
-func bazelModuleLabel(ctx BazelConversionPathContext, module blueprint.Module, tag string) string {
-	// TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets.
-	b, ok := module.(Bazelable)
-	// TODO(b/181155349): perhaps return an error here if the module can't be/isn't being converted
-	if !ok || !b.ConvertedToBazel(ctx) {
-		return bp2buildModuleLabel(ctx, module)
-	}
-	return b.GetBazelLabel(ctx, module)
-}
-
-func bazelShortLabel(label string) string {
-	i := strings.Index(label, ":")
-	return label[i:]
-}
-
-func bazelPackage(label string) string {
-	i := strings.Index(label, ":")
-	return label[0:i]
-}
-
-func samePackage(label1, label2 string) bool {
-	return bazelPackage(label1) == bazelPackage(label2)
-}
-
-func bp2buildModuleLabel(ctx BazelConversionPathContext, module blueprint.Module) string {
-	moduleName := ctx.OtherModuleName(module)
-	moduleDir := ctx.OtherModuleDir(module)
-	return fmt.Sprintf("//%s:%s", moduleDir, moduleName)
-}
-
 // OutputPaths is a slice of OutputPath objects, with helpers to operate on the collection.
 type OutputPaths []OutputPath
 
@@ -679,14 +456,19 @@
 	}
 }
 
-// PathsAndMissingDepsForModuleSrcExcludes returns Paths rooted from the module's local source directory, excluding
-// paths listed in the excludes arguments, and a list of missing dependencies.  It expands globs, references to
-// SourceFileProducer modules using the ":name" syntax, and references to OutputFileProducer modules using the
-// ":name{.tag}" syntax.  Properties passed as the paths or excludes argument must have been annotated with struct tag
+// PathsAndMissingDepsForModuleSrcExcludes returns a Paths{} containing the resolved references in
+// paths, minus those listed in excludes. Elements of paths and excludes are resolved as:
+// * filepath, relative to local module directory, resolves as a filepath relative to the local
+//   source directory
+// * glob, relative to the local module directory, resolves as filepath(s), relative to the local
+//  source directory. Not valid in excludes.
+// * other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer
+//    or OutputFileProducer. These resolve as a filepath to an output filepath or generated source
+//    filepath.
+// and a list of the module names of missing module dependencies are returned as the second return.
+// Properties passed as the paths argument must have been annotated with struct tag
 // `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the
-// path_properties mutator.  If ctx.Config().AllowMissingDependencies() is true then any missing SourceFileProducer or
-// OutputFileProducer dependencies will be returned, and they will NOT cause the module to be marked as having missing
-// dependencies.
+// path_deps mutator.
 func PathsAndMissingDepsForModuleSrcExcludes(ctx ModuleWithDepsPathContext, paths, excludes []string) (Paths, []string) {
 	prefix := pathForModuleSrc(ctx).String()
 
@@ -1566,17 +1348,6 @@
 	return PathForOutput(ctx, ".intermediates", ctx.ModuleDir(), ctx.ModuleName(), ctx.ModuleSubDir())
 }
 
-type BazelOutPath struct {
-	OutputPath
-}
-
-var _ Path = BazelOutPath{}
-var _ objPathProvider = BazelOutPath{}
-
-func (p BazelOutPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath {
-	return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
-}
-
 // PathForVndkRefAbiDump returns an OptionalPath representing the path of the
 // reference abi dump for the given module. This is not guaranteed to be valid.
 func PathForVndkRefAbiDump(ctx ModuleInstallPathContext, version, fileName string,
@@ -1615,25 +1386,6 @@
 		fileName+ext)
 }
 
-// PathForBazelOut returns a Path representing the paths... under an output directory dedicated to
-// bazel-owned outputs.
-func PathForBazelOut(ctx PathContext, paths ...string) BazelOutPath {
-	execRootPathComponents := append([]string{"execroot", "__main__"}, paths...)
-	execRootPath := filepath.Join(execRootPathComponents...)
-	validatedExecRootPath, err := validatePath(execRootPath)
-	if err != nil {
-		reportPathError(ctx, err)
-	}
-
-	outputPath := OutputPath{basePath{"", ""},
-		ctx.Config().buildDir,
-		ctx.Config().BazelContext.OutputBase()}
-
-	return BazelOutPath{
-		OutputPath: outputPath.withRel(validatedExecRootPath),
-	}
-}
-
 // PathForModuleOut returns a Path representing the paths... under the module's
 // output directory.
 func PathForModuleOut(ctx ModuleOutPathContext, paths ...string) ModuleOutPath {