Merge "Generate android_certificate_directory" into main
diff --git a/bp2build/java_proto_conversion_test.go b/bp2build/java_proto_conversion_test.go
index 5d6b088..dfef697 100644
--- a/bp2build/java_proto_conversion_test.go
+++ b/bp2build/java_proto_conversion_test.go
@@ -137,3 +137,50 @@
 		},
 	})
 }
+
+func TestJavaLibsAndOnlyProtoSrcs(t *testing.T) {
+	runJavaProtoTestCase(t, Bp2buildTestCase{
+		Description: "java_library that has only proto srcs",
+		Blueprint: `java_library_static {
+    name: "java-protos",
+    srcs: ["a.proto"],
+    libs: ["java-lib"],
+    java_version: "7",
+    sdk_version: "current",
+}
+
+java_library_static {
+    name: "java-lib",
+    bazel_module: { bp2build_available: false },
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("proto_library", "java-protos_proto", AttrNameToString{
+				"srcs": `["a.proto"]`,
+			}),
+			MakeBazelTarget(
+				"java_lite_proto_library",
+				"java-protos_java_proto_lite",
+				AttrNameToString{
+					"deps":         `[":java-protos_proto"]`,
+					"java_version": `"7"`,
+					"sdk_version":  `"current"`,
+				}),
+			MakeBazelTarget("java_library", "java-protos", AttrNameToString{
+				"exports": `[
+        ":java-protos_java_proto_lite",
+        ":java-lib-neverlink",
+    ]`,
+				"java_version": `"7"`,
+				"sdk_version":  `"current"`,
+			}),
+			MakeNeverlinkDuplicateTargetWithAttrs(
+				"java_library",
+				"java-protos",
+				AttrNameToString{
+					"java_version": `"7"`,
+					"sdk_version":  `"current"`,
+				}),
+		},
+	})
+}
diff --git a/cc/stl.go b/cc/stl.go
index 8f92dcb..a31a585 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -172,6 +172,7 @@
 		// The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
 		// its own includes. The includes are handled in CCBase.Flags().
 		deps.SharedLibs = append([]string{"libstdc++"}, deps.SharedLibs...)
+		deps.HeaderLibs = append([]string{"ndk_system"}, deps.HeaderLibs...)
 	case "ndk_libc++_shared", "ndk_libc++_static":
 		if stl.Properties.SelectedStl == "ndk_libc++_shared" {
 			deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
@@ -219,8 +220,7 @@
 	case "libstdc++":
 		// Nothing
 	case "ndk_system":
-		ndkSrcRoot := android.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include")
-		flags.Local.CFlags = append(flags.Local.CFlags, "-isystem "+ndkSrcRoot.String())
+		// Nothing: The exports of ndk_system will be added automatically to the local cflags
 	case "ndk_libc++_shared", "ndk_libc++_static":
 		if ctx.Arch().ArchType == android.Arm {
 			// Make sure the _Unwind_XXX symbols are not re-exported.
diff --git a/java/droidstubs.go b/java/droidstubs.go
index f05ef1f..1d5dd76 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -539,7 +539,7 @@
 
 	// Force metalava to sort overloaded methods by their order in the source code.
 	// See b/285312164 for more information.
-	cmd.FlagWithArg("--api-overloaded-method-order ", "source")
+	cmd.FlagWithArg("--format-defaults ", "overloaded-method-order=source")
 
 	return cmd
 }
diff --git a/java/java.go b/java/java.go
index 99bb1b3..270f456 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1798,6 +1798,7 @@
 		Flag("-jar").
 		Flag("-write_if_changed").
 		Flag("-ignore_missing_files").
+		Flag("-quiet").
 		FlagWithArg("-C ", unzippedSrcJarDir.String()).
 		FlagWithInput("-l ", classFilesList).
 		FlagWithOutput("-o ", al.stubsJarWithoutStaticLibs)
@@ -2885,8 +2886,9 @@
 // depending on the module type.
 type bp2BuildJavaInfo struct {
 	// separates dependencies into dynamic dependencies and static dependencies.
-	DepLabels *javaDependencyLabels
-	hasKotlin bool
+	DepLabels       *javaDependencyLabels
+	hasKotlin       bool
+	onlyProtoInSrcs bool
 }
 
 func javaXsdTargetName(xsd android.XsdConfigBp2buildTargets) string {
@@ -2949,6 +2951,9 @@
 
 	staticDeps.Append(srcPartitions[xsdSrcPartition])
 
+	_, protoInSrcs := srcPartitions[protoSrcPartition]
+	onlyProtoInSrcs := protoInSrcs && len(srcPartitions) == 1
+
 	if !srcPartitions[logtagSrcPartition].IsEmpty() {
 		logtagsLibName := m.Name() + "_logtags"
 		ctx.CreateBazelTargetModule(
@@ -3086,8 +3091,9 @@
 	}
 
 	bp2BuildInfo := &bp2BuildJavaInfo{
-		DepLabels: depLabels,
-		hasKotlin: hasKotlin,
+		DepLabels:       depLabels,
+		hasKotlin:       hasKotlin,
+		onlyProtoInSrcs: onlyProtoInSrcs,
 	}
 
 	return commonAttrs, bp2BuildInfo, true
@@ -3127,16 +3133,29 @@
 	depLabels := bp2BuildInfo.DepLabels
 
 	deps := depLabels.Deps
+	exports := depLabels.StaticDeps
 	if !commonAttrs.Srcs.IsEmpty() {
-		deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them
+		deps.Append(exports) // we should only append these if there are sources to use them
 	} else if !deps.IsEmpty() {
-		ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.")
+		if bp2BuildInfo.onlyProtoInSrcs {
+			// java_library does not accept deps when there are no srcs because
+			// there is no compilation happening, but it accepts exports.
+			// bp2build converts this module to 2 java_libraries + java_xx_proto_library + proto_library
+			// the non-empty deps here are not necessary for compiling the protos, in which case
+			// they're unnecessary as deps on the java_library as well since they aren't
+			// being propagated to any dependencies.
+			// so we can put the deps to exports and drop deps here.
+			exports.Append(deps)
+			deps = bazel.LabelListAttribute{}
+		} else {
+			ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.")
+		}
 	}
 	var props bazel.BazelTargetModuleProperties
 	attrs := &javaLibraryAttributes{
 		javaCommonAttributes: commonAttrs,
 		Deps:                 deps,
-		Exports:              depLabels.StaticDeps,
+		Exports:              exports,
 	}
 	name := m.Name()
 
diff --git a/zip/cmd/main.go b/zip/cmd/main.go
index 5231fae..37537ab 100644
--- a/zip/cmd/main.go
+++ b/zip/cmd/main.go
@@ -174,6 +174,7 @@
 	traceFile := flags.String("trace", "", "write trace to file")
 	sha256Checksum := flags.Bool("sha256", false, "add a zip header to each file containing its SHA256 digest")
 	doNotWrite := flags.Bool("n", false, "Nothing is written to disk -- all other work happens")
+	quiet := flags.Bool("quiet", false, "do not print warnings to console")
 
 	flags.Var(&rootPrefix{}, "P", "path prefix within the zip at which to place files")
 	flags.Var(&listFiles{}, "l", "file containing list of files to zip")
@@ -238,6 +239,7 @@
 		IgnoreMissingFiles:       *ignoreMissingFiles,
 		Sha256Checksum:           *sha256Checksum,
 		DoNotWrite:               *doNotWrite,
+		Quiet:                    *quiet,
 	})
 	if err != nil {
 		fmt.Fprintln(os.Stderr, "error:", err.Error())
diff --git a/zip/zip.go b/zip/zip.go
index 30a2ee7..f91a5f2 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -283,6 +283,7 @@
 	IgnoreMissingFiles       bool
 	Sha256Checksum           bool
 	DoNotWrite               bool
+	Quiet                    bool
 
 	Stderr     io.Writer
 	Filesystem pathtools.FileSystem
@@ -340,7 +341,9 @@
 					Err:  os.ErrNotExist,
 				}
 				if args.IgnoreMissingFiles {
-					fmt.Fprintln(z.stderr, "warning:", err)
+					if !args.Quiet {
+						fmt.Fprintln(z.stderr, "warning:", err)
+					}
 				} else {
 					return err
 				}
@@ -357,7 +360,9 @@
 					Err:  os.ErrNotExist,
 				}
 				if args.IgnoreMissingFiles {
-					fmt.Fprintln(z.stderr, "warning:", err)
+					if !args.Quiet {
+						fmt.Fprintln(z.stderr, "warning:", err)
+					}
 				} else {
 					return err
 				}
@@ -368,7 +373,9 @@
 					Err:  syscall.ENOTDIR,
 				}
 				if args.IgnoreMissingFiles {
-					fmt.Fprintln(z.stderr, "warning:", err)
+					if !args.Quiet {
+						fmt.Fprintln(z.stderr, "warning:", err)
+					}
 				} else {
 					return err
 				}