Handle .proto files in different package for filegroups

Followup to aosp/2693190, this CL adds the support to filegroups.
<mod>__bp2build_converted is now an alias to a proto_library
target <mod>_proto. This proto_library will be created in a different
package if the .proto file exists in a different package.

Test: bp2build unit tests
Test: TH
Bug: 292583584
Change-Id: I8ca452aacf1a86dfc9e218464e38aab89afa5a29
diff --git a/android/filegroup.go b/android/filegroup.go
index 3b86655..6cc9232 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -24,6 +24,7 @@
 	"android/soong/ui/metrics/bp2build_metrics_proto"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/proptools"
 )
 
 func init() {
@@ -141,8 +142,14 @@
 			attrs)
 	} else {
 		if fg.ShouldConvertToProtoLibrary(ctx) {
+			pkgToSrcs := partitionSrcsByPackage(ctx.ModuleDir(), bazel.MakeLabelList(srcs.Value.Includes))
+			if len(pkgToSrcs) > 1 {
+				ctx.ModuleErrorf("TODO: Add bp2build support for multiple package .protosrcs in filegroup")
+				return
+			}
+			pkg := SortedKeys(pkgToSrcs)[0]
 			attrs := &ProtoAttrs{
-				Srcs:                srcs,
+				Srcs:                bazel.MakeLabelListAttribute(pkgToSrcs[pkg]),
 				Strip_import_prefix: fg.properties.Path,
 			}
 
@@ -151,13 +158,39 @@
 				// TODO(b/246997908): we can remove this tag if we could figure out a solution for this bug.
 				"manual",
 			}
+			if pkg != ctx.ModuleDir() {
+				// Since we are creating the proto_library in a subpackage, create an import_prefix relative to the current package
+				if rel, err := filepath.Rel(ctx.ModuleDir(), pkg); err != nil {
+					ctx.ModuleErrorf("Could not get relative path for %v %v", pkg, err)
+				} else if rel != "." {
+					attrs.Import_prefix = &rel
+					// Strip the package prefix
+					attrs.Strip_import_prefix = proptools.StringPtr("")
+				}
+			}
+
 			ctx.CreateBazelTargetModule(
 				bazel.BazelTargetModuleProperties{Rule_class: "proto_library"},
 				CommonAttributes{
-					Name: fg.Name() + convertedProtoLibrarySuffix,
+					Name: fg.Name() + "_proto",
+					Dir:  proptools.StringPtr(pkg),
 					Tags: bazel.MakeStringListAttribute(tags),
 				},
 				attrs)
+
+			// Create an alias in the current dir. The actual target might exist in a different package, but rdeps
+			// can reliabily use this alias
+			ctx.CreateBazelTargetModule(
+				bazel.BazelTargetModuleProperties{Rule_class: "alias"},
+				CommonAttributes{
+					Name: fg.Name() + convertedProtoLibrarySuffix,
+					// TODO(b/246997908): we can remove this tag if we could figure out a solution for this bug.
+					Tags: bazel.MakeStringListAttribute(tags),
+				},
+				&bazelAliasAttributes{
+					Actual: bazel.MakeLabelAttribute("//" + pkg + ":" + fg.Name() + "_proto"),
+				},
+			)
 		}
 
 		// TODO(b/242847534): Still convert to a filegroup because other unconverted
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 496a482..cac604b 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -2434,12 +2434,18 @@
 			}), MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
 				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":a_cc_proto_lite"]`,
-			}), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_bp2build_converted", AttrNameToString{
+			}), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_proto", AttrNameToString{
 				"srcs": `["a_fg.proto"]`,
 				"tags": `[
         "apex_available=//apex_available:anyapex",
         "manual",
     ]`,
+			}), MakeBazelTargetNoRestrictions("alias", "a_fg_proto_bp2build_converted", AttrNameToString{
+				"actual": `"//.:a_fg_proto_proto"`,
+				"tags": `[
+        "apex_available=//apex_available:anyapex",
+        "manual",
+    ]`,
 			}), MakeBazelTargetNoRestrictions("filegroup", "a_fg_proto", AttrNameToString{
 				"srcs": `["a_fg.proto"]`,
 			}),
@@ -2476,12 +2482,18 @@
 			}), MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
 				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":a_cc_proto_lite"]`,
-			}), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_bp2build_converted", AttrNameToString{
+			}), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_proto", AttrNameToString{
 				"srcs": `["a_fg.proto"]`,
 				"tags": `[
         "apex_available=//apex_available:anyapex",
         "manual",
     ]`,
+			}), MakeBazelTargetNoRestrictions("alias", "a_fg_proto_bp2build_converted", AttrNameToString{
+				"actual": `"//.:a_fg_proto_proto"`,
+				"tags": `[
+        "apex_available=//apex_available:anyapex",
+        "manual",
+    ]`,
 			}), MakeBazelTargetNoRestrictions("filegroup", "a_fg_proto", AttrNameToString{
 				"srcs": `["a_fg.proto"]`,
 			}),
diff --git a/bp2build/filegroup_conversion_test.go b/bp2build/filegroup_conversion_test.go
index 7ce559d..cb2e207 100644
--- a/bp2build/filegroup_conversion_test.go
+++ b/bp2build/filegroup_conversion_test.go
@@ -137,7 +137,7 @@
 		path: "proto",
 }`,
 		ExpectedBazelTargets: []string{
-			MakeBazelTargetNoRestrictions("proto_library", "foo_bp2build_converted", AttrNameToString{
+			MakeBazelTargetNoRestrictions("proto_library", "foo_proto", AttrNameToString{
 				"srcs":                `["proto/foo.proto"]`,
 				"strip_import_prefix": `"proto"`,
 				"tags": `[
@@ -145,6 +145,13 @@
         "manual",
     ]`,
 			}),
+			MakeBazelTargetNoRestrictions("alias", "foo_bp2build_converted", AttrNameToString{
+				"actual": `"//.:foo_proto"`,
+				"tags": `[
+        "apex_available=//apex_available:anyapex",
+        "manual",
+    ]`,
+			}),
 			MakeBazelTargetNoRestrictions("filegroup", "foo", AttrNameToString{
 				"srcs": `["proto/foo.proto"]`}),
 		}})
@@ -170,3 +177,27 @@
     ]`}),
 		}})
 }
+
+func TestFilegroupWithProtoInDifferentPackage(t *testing.T) {
+	runFilegroupTestCase(t, Bp2buildTestCase{
+		Description: "filegroup with .proto in different package",
+		Filesystem: map[string]string{
+			"subdir/Android.bp": "",
+		},
+		Blueprint: `
+filegroup {
+    name: "foo",
+    srcs: ["subdir/foo.proto"],
+}`,
+		Dir: "subdir", // check in subdir
+		ExpectedBazelTargets: []string{
+			MakeBazelTargetNoRestrictions("proto_library", "foo_proto", AttrNameToString{
+				"srcs":                `["//subdir:foo.proto"]`,
+				"import_prefix":       `"subdir"`,
+				"strip_import_prefix": `""`,
+				"tags": `[
+        "apex_available=//apex_available:anyapex",
+        "manual",
+    ]`}),
+		}})
+}