PiperOrigin-RevId: 163848560
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/ActionReuser.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/ActionReuser.java
index 6862280..3972163 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/ActionReuser.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/ActionReuser.java
@@ -20,6 +20,7 @@
 import static com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode.TARGET;
 import static com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType.BOTH;
 import static com.google.devtools.build.lib.rules.java.proto.JplCcLinkParams.createCcLinkParamsStore;
+import static com.google.devtools.build.lib.rules.java.proto.StrictDepsUtils.createNonStrictCompilationArgsProvider;
 
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.actions.Artifact;
@@ -100,9 +101,11 @@
             .add(compilationArgsProvider)
             .add(createCcLinkParamsStore(ruleContext, javaApi.getProtoRuntimeImmutable()));
 
+    Iterable<JavaProtoLibraryAspectProvider> javaProtoLibraryAspectProviders =
+        ruleContext.getPrerequisites("deps", TARGET, JavaProtoLibraryAspectProvider.class);
+
     NestedSetBuilder<Artifact> transitiveOutputJars = NestedSetBuilder.stableOrder();
-    for (JavaProtoLibraryAspectProvider provider :
-        ruleContext.getPrerequisites("deps", TARGET, JavaProtoLibraryAspectProvider.class)) {
+    for (JavaProtoLibraryAspectProvider provider : javaProtoLibraryAspectProviders) {
       transitiveOutputJars.addTransitive(provider.getJars());
     }
     transitiveOutputJars.add(outputJar);
@@ -113,7 +116,13 @@
             JavaSkylarkApiProvider.PROTO_NAME.getLegacyId(),
             JavaSkylarkApiProvider.fromProviderMap(javaProviders))
         .addProviders(
-            new JavaProtoLibraryAspectProvider(javaProviders, transitiveOutputJars.build()));
+            new JavaProtoLibraryAspectProvider(
+                javaProviders,
+                transitiveOutputJars.build(),
+                createNonStrictCompilationArgsProvider(
+                    javaProtoLibraryAspectProviders,
+                    JavaCompilationArgs.builder().merge(directJars).build(),
+                    javaApi.getProtoRuntimeImmutable())));
     return true;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java
index 531fd91..93da480 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java
@@ -22,6 +22,7 @@
 import static com.google.devtools.build.lib.packages.Attribute.attr;
 import static com.google.devtools.build.lib.packages.BuildType.LABEL;
 import static com.google.devtools.build.lib.rules.java.proto.JplCcLinkParams.createCcLinkParamsStore;
+import static com.google.devtools.build.lib.rules.java.proto.StrictDepsUtils.createNonStrictCompilationArgsProvider;
 
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.actions.Artifact;
@@ -229,7 +230,13 @@
               JavaSkylarkApiProvider.PROTO_NAME.getLegacyId(),
               JavaSkylarkApiProvider.fromProviderMap(javaProviders))
           .addProvider(
-              new JavaProtoLibraryAspectProvider(javaProviders, transitiveOutputJars.build()));
+              new JavaProtoLibraryAspectProvider(
+                  javaProviders,
+                  transitiveOutputJars.build(),
+                  createNonStrictCompilationArgsProvider(
+                      javaProtoLibraryAspectProviders,
+                      generatedCompilationArgsProvider.getJavaCompilationArgs(),
+                      getProtoRuntimeDeps())));
     }
 
     private void createProtoCompileAction(Artifact sourceJar) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoLibrary.java
index 1efbe83..1331ff5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoLibrary.java
@@ -19,6 +19,7 @@
 import static com.google.devtools.build.lib.collect.nestedset.Order.STABLE_ORDER;
 import static com.google.devtools.build.lib.rules.java.proto.JavaLiteProtoAspect.PROTO_TOOLCHAIN_ATTR;
 import static com.google.devtools.build.lib.rules.java.proto.JplCcLinkParams.createCcLinkParamsStore;
+import static com.google.devtools.build.lib.rules.java.proto.StrictDepsUtils.constructJcapFromAspectDeps;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMultimap;
@@ -57,13 +58,7 @@
         ruleContext.getPrerequisites("deps", Mode.TARGET, JavaProtoLibraryAspectProvider.class);
 
     JavaCompilationArgsProvider dependencyArgsProviders =
-        JavaCompilationArgsProvider.merge(
-            WrappingProvider.Helper.unwrapProviders(
-                javaProtoLibraryAspectProviders, JavaCompilationArgsProvider.class));
-
-    if (!StrictDepsUtils.isStrictDepsJavaProtoLibrary(ruleContext)) {
-      dependencyArgsProviders = StrictDepsUtils.makeNonStrict(dependencyArgsProviders);
-    }
+        constructJcapFromAspectDeps(ruleContext, javaProtoLibraryAspectProviders);
 
     Runfiles runfiles =
         new Runfiles.Builder(ruleContext.getWorkspaceName())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
index 3a49aeb..fb73faf 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
@@ -22,6 +22,7 @@
 import static com.google.devtools.build.lib.packages.Attribute.attr;
 import static com.google.devtools.build.lib.packages.BuildType.LABEL;
 import static com.google.devtools.build.lib.rules.java.proto.JplCcLinkParams.createCcLinkParamsStore;
+import static com.google.devtools.build.lib.rules.java.proto.StrictDepsUtils.createNonStrictCompilationArgsProvider;
 
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.actions.Artifact;
@@ -245,7 +246,13 @@
               JavaSkylarkApiProvider.PROTO_NAME.getLegacyId(),
               JavaSkylarkApiProvider.fromProviderMap(javaProviders))
           .addProvider(
-              new JavaProtoLibraryAspectProvider(javaProviders, transitiveOutputJars.build()));
+              new JavaProtoLibraryAspectProvider(
+                  javaProviders,
+                  transitiveOutputJars.build(),
+                  createNonStrictCompilationArgsProvider(
+                      javaProtoLibraryAspectProviders,
+                      generatedCompilationArgsProvider.getJavaCompilationArgs(),
+                      getProtoRuntimeDeps())));
     }
 
     /**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java
index 8dcd605..395c025 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java
@@ -17,6 +17,7 @@
 import static com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode.TARGET;
 import static com.google.devtools.build.lib.collect.nestedset.Order.STABLE_ORDER;
 import static com.google.devtools.build.lib.rules.java.proto.JplCcLinkParams.createCcLinkParamsStore;
+import static com.google.devtools.build.lib.rules.java.proto.StrictDepsUtils.constructJcapFromAspectDeps;
 
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.actions.Artifact;
@@ -48,13 +49,7 @@
         ruleContext.getPrerequisites("deps", TARGET, JavaProtoLibraryAspectProvider.class);
 
     JavaCompilationArgsProvider dependencyArgsProviders =
-        JavaCompilationArgsProvider.merge(
-            WrappingProvider.Helper.unwrapProviders(
-                javaProtoLibraryAspectProviders, JavaCompilationArgsProvider.class));
-
-    if (!StrictDepsUtils.isStrictDepsJavaProtoLibrary(ruleContext)) {
-      dependencyArgsProviders = StrictDepsUtils.makeNonStrict(dependencyArgsProviders);
-    }
+        constructJcapFromAspectDeps(ruleContext, javaProtoLibraryAspectProviders);
 
     Runfiles runfiles =
         new Runfiles.Builder(ruleContext.getWorkspaceName())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryAspectProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryAspectProvider.java
index 3124e54..8998ac1 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryAspectProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryAspectProvider.java
@@ -18,16 +18,28 @@
 import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap;
 import com.google.devtools.build.lib.analysis.WrappingProvider;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.rules.java.JavaCompilationArgs;
 
 /** A provider used to communicate information between java_proto_library and its aspect. */
 public class JavaProtoLibraryAspectProvider implements WrappingProvider {
   private final TransitiveInfoProviderMap transitiveInfoProviderMap;
   private final NestedSet<Artifact> jars;
 
+  /**
+   * List of jars to be used as "direct" when java_xxx_proto_library.strict_deps = 0.
+   *
+   * <p>Contains all transitively generated protos and all proto runtimes (but not the runtime's own
+   * dependencies).
+   */
+  private final JavaCompilationArgs nonStrictCompArgs;
+
   public JavaProtoLibraryAspectProvider(
-      TransitiveInfoProviderMap transitiveInfoProviderMap, NestedSet<Artifact> jars) {
+      TransitiveInfoProviderMap transitiveInfoProviderMap,
+      NestedSet<Artifact> jars,
+      JavaCompilationArgs nonStrictCompArgs) {
     this.transitiveInfoProviderMap = transitiveInfoProviderMap;
     this.jars = jars;
+    this.nonStrictCompArgs = nonStrictCompArgs;
   }
 
   @Override
@@ -38,4 +50,8 @@
   public NestedSet<Artifact> getJars() {
     return jars;
   }
+
+  public JavaCompilationArgs getNonStrictCompArgs() {
+    return nonStrictCompArgs;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/StrictDepsUtils.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/StrictDepsUtils.java
index 8b9d5c2..fdacd71 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/StrictDepsUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/StrictDepsUtils.java
@@ -16,14 +16,74 @@
 
 import static com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType.BOTH;
 
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
+import com.google.devtools.build.lib.analysis.WrappingProvider;
 import com.google.devtools.build.lib.rules.java.JavaCompilationArgs;
 import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
 import com.google.devtools.build.lib.rules.java.JavaConfiguration;
+import com.google.devtools.build.lib.rules.proto.ProtoConfiguration;
 
 public class StrictDepsUtils {
 
   /**
+   * Used in JavaXXXProtoLibrary.java files to construct a JCAP from 'deps', where those were
+   * populated by the Aspect it injected.
+   *
+   * <p>Takes care of strict deps.
+   */
+  public static JavaCompilationArgsProvider constructJcapFromAspectDeps(
+      RuleContext ruleContext,
+      Iterable<JavaProtoLibraryAspectProvider> javaProtoLibraryAspectProviders) {
+    JavaCompilationArgsProvider strictCompProvider =
+        JavaCompilationArgsProvider.merge(
+            WrappingProvider.Helper.unwrapProviders(
+                javaProtoLibraryAspectProviders, JavaCompilationArgsProvider.class));
+    if (StrictDepsUtils.isStrictDepsJavaProtoLibrary(ruleContext)) {
+      return strictCompProvider;
+    } else if (ruleContext
+        .getConfiguration()
+        .getFragment(ProtoConfiguration.class)
+        .jplNonStrictDepsLikePl()) {
+      JavaCompilationArgs.Builder nonStrictDirectJars = JavaCompilationArgs.builder();
+      for (JavaProtoLibraryAspectProvider p : javaProtoLibraryAspectProviders) {
+        nonStrictDirectJars.addTransitiveArgs(p.getNonStrictCompArgs(), BOTH);
+      }
+      return JavaCompilationArgsProvider.create(
+          nonStrictDirectJars.build(),
+          strictCompProvider.getRecursiveJavaCompilationArgs(),
+          strictCompProvider.getCompileTimeJavaDependencyArtifacts(),
+          strictCompProvider.getRunTimeJavaDependencyArtifacts());
+    } else {
+      return StrictDepsUtils.makeNonStrict(strictCompProvider);
+    }
+  }
+
+  /**
+   * Creates a JavaCompilationArgsProvider that's used when java_proto_library sets strict_deps=0.
+   * It contains the jars a proto_library (or the proto aspect) produced, as well as all transitive
+   * proto jars, and the proto runtime jars, all described as direct dependencies.
+   */
+  public static JavaCompilationArgs createNonStrictCompilationArgsProvider(
+      Iterable<JavaProtoLibraryAspectProvider> deps,
+      JavaCompilationArgs directJars,
+      ImmutableList<TransitiveInfoCollection> protoRuntimes) {
+    JavaCompilationArgs.Builder result = JavaCompilationArgs.builder();
+    for (JavaProtoLibraryAspectProvider p : deps) {
+      result.addTransitiveArgs(p.getNonStrictCompArgs(), BOTH);
+    }
+    result.addTransitiveArgs(directJars, BOTH);
+    for (TransitiveInfoCollection t : protoRuntimes) {
+      JavaCompilationArgsProvider p = t.getProvider(JavaCompilationArgsProvider.class);
+      if (p != null) {
+        result.addTransitiveArgs(p.getJavaCompilationArgs(), BOTH);
+      }
+    }
+    return result.build();
+  }
+
+  /**
    * Returns true iff 'ruleContext' should enforce strict-deps.
    *
    * <p>Using this method requires requesting the JavaConfiguration fragment.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java
index daf8e48..d36504b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java
@@ -167,6 +167,19 @@
     )
     public boolean correctRollupTransitiveProtoRuntimes;
 
+    @Option(
+      name = "jplNonStrictDepsLikePl",
+      defaultValue = "false",
+      category = "rollout",
+      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+      effectTags = {OptionEffectTag.AFFECTS_OUTPUTS, OptionEffectTag.LOADING_AND_ANALYSIS},
+      metadataTags = {OptionMetadataTag.INCOMPATIBLE_CHANGE},
+      help =
+          "Roll-out flag for changing behavior of non-strict java_xxx_proto_library. "
+              + "See commit description for details. DO NOT USE."
+    )
+    public boolean jplNonStrictDepsLikePl;
+
     @Override
     public FragmentOptions getHost(boolean fallback) {
       Options host = (Options) super.getHost(fallback);
@@ -181,6 +194,7 @@
       host.ccProtoLibraryHeaderSuffixes = ccProtoLibraryHeaderSuffixes;
       host.ccProtoLibrarySourceSuffixes = ccProtoLibrarySourceSuffixes;
       host.correctRollupTransitiveProtoRuntimes = correctRollupTransitiveProtoRuntimes;
+      host.jplNonStrictDepsLikePl = jplNonStrictDepsLikePl;
       return host;
     }
   }
@@ -262,4 +276,8 @@
   public boolean correctRollupTransitiveProtoRuntimes() {
     return options.correctRollupTransitiveProtoRuntimes;
   }
+
+  public boolean jplNonStrictDepsLikePl() {
+    return options.jplNonStrictDepsLikePl;
+  }
 }