PiperOrigin-RevId: 203352511
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index b6ffe9f..5d7b548 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -1031,6 +1031,7 @@
         "rules/java/JavaSkylarkApiProvider.java",
         "rules/java/JavaSkylarkCommon.java",
         "rules/java/JavaSourceJarsProvider.java",
+        "rules/java/JavaStrictCompilationArgsProvider.java",
         "rules/java/JavaTargetAttributes.java",
         "rules/java/JavaToolchainProvider.java",
         "rules/java/JavaUtil.java",
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java
index baa8687..6f2fbff 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java
@@ -856,4 +856,9 @@
       throws InterruptedException {
     return null;
   }
+
+  @Override
+  public boolean isJavaProtoLibraryStrictDeps(RuleContext ruleContext) {
+    return false;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java
index 1ade2c4c..db528fc 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java
@@ -253,16 +253,20 @@
    */
   public JavaCompilationArgsProvider collectJavaCompilationArgs(
       boolean isNeverLink, boolean srcLessDepsExport) {
+    boolean javaProtoLibraryStrictDeps = semantics.isJavaProtoLibraryStrictDeps(ruleContext);
     return collectJavaCompilationArgs(
         /* isNeverLink= */ isNeverLink,
         /* srcLessDepsExport= */ srcLessDepsExport,
         getJavaCompilationArtifacts(),
         ImmutableList.of(
             JavaCompilationArgsProvider.legacyFromTargets(
-                targetsTreatedAsDeps(ClasspathType.COMPILE_ONLY))),
+                targetsTreatedAsDeps(ClasspathType.COMPILE_ONLY), javaProtoLibraryStrictDeps)),
         ImmutableList.of(
-            JavaCompilationArgsProvider.legacyFromTargets(getRuntimeDeps(ruleContext))),
-        ImmutableList.of(JavaCompilationArgsProvider.legacyFromTargets(getExports(ruleContext))));
+            JavaCompilationArgsProvider.legacyFromTargets(
+                getRuntimeDeps(ruleContext), javaProtoLibraryStrictDeps)),
+        ImmutableList.of(
+            JavaCompilationArgsProvider.legacyFromTargets(
+                getExports(ruleContext), javaProtoLibraryStrictDeps)));
   }
 
   static JavaCompilationArgsProvider collectJavaCompilationArgs(
@@ -745,7 +749,8 @@
     List<TransitiveInfoCollection> runtimeDepInfo = getRuntimeDeps(ruleContext);
     checkRuntimeDeps(ruleContext, runtimeDepInfo);
     JavaCompilationArgsProvider provider =
-        JavaCompilationArgsProvider.legacyFromTargets(runtimeDepInfo);
+        JavaCompilationArgsProvider.legacyFromTargets(
+            runtimeDepInfo, semantics.isJavaProtoLibraryStrictDeps(ruleContext));
     attributes.addRuntimeClassPathEntries(provider.getRuntimeJars());
     attributes.addInstrumentationMetadataEntries(provider.getInstrumentationMetadata());
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgsProvider.java
index 5127bbf..a2d30d3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgsProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgsProvider.java
@@ -129,10 +129,26 @@
   @Deprecated
   public static JavaCompilationArgsProvider legacyFromTargets(
       Iterable<? extends TransitiveInfoCollection> infos) {
+    return legacyFromTargets(infos, /* javaProtoLibraryStrictDeps= */ false);
+  }
+
+  @Deprecated
+  public static JavaCompilationArgsProvider legacyFromTargets(
+      Iterable<? extends TransitiveInfoCollection> infos, boolean javaProtoLibraryStrictDeps) {
     Builder argsBuilder = builder();
     for (TransitiveInfoCollection info : infos) {
-      JavaCompilationArgsProvider provider =
-          JavaInfo.getProvider(JavaCompilationArgsProvider.class, info);
+      JavaCompilationArgsProvider provider = null;
+
+      if (javaProtoLibraryStrictDeps) {
+        JavaStrictCompilationArgsProvider strictCompilationArgsProvider =
+            JavaInfo.getProvider(JavaStrictCompilationArgsProvider.class, info);
+        if (strictCompilationArgsProvider != null) {
+          provider = strictCompilationArgsProvider.getJavaCompilationArgsProvider();
+        }
+      }
+      if (provider == null) {
+        provider = JavaInfo.getProvider(JavaCompilationArgsProvider.class, info);
+      }
       if (provider != null) {
         argsBuilder.addExports(provider);
       } else {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
index 42cb0d7..388c55e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
@@ -70,6 +70,8 @@
   private final ImmutableList<Artifact> additionalJavaBaseInputs;
   private final StrictDepsMode strictJavaDeps;
   private final String fixDepsTool;
+  // TODO(twerth): Remove after java_proto_library.strict_deps migration is done.
+  private final boolean javaProtoLibraryStrictDeps;
 
   private static final String DEFAULT_ATTRIBUTES_SUFFIX = "";
   private static final PathFragment JAVAC = PathFragment.create("_javac");
@@ -94,6 +96,7 @@
         ? StrictDepsMode.OFF
         : getJavaConfiguration().getFilteredStrictJavaDeps();
     this.fixDepsTool = getJavaConfiguration().getFixDepsTool();
+    this.javaProtoLibraryStrictDeps = semantics.isJavaProtoLibraryStrictDeps(ruleContext);
   }
 
   public JavaCompilationHelper(RuleContext ruleContext, JavaSemantics semantics,
@@ -721,7 +724,8 @@
 
   private NestedSet<Artifact> getNonRecursiveCompileTimeJarsFromCollection(
       Iterable<? extends TransitiveInfoCollection> deps) {
-    return JavaCompilationArgsProvider.legacyFromTargets(deps).getDirectCompileTimeJars();
+    return JavaCompilationArgsProvider.legacyFromTargets(deps, javaProtoLibraryStrictDeps)
+        .getDirectCompileTimeJars();
   }
 
   static void addDependencyArtifactsToAttributes(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java
index 63dfa45..e6aa290 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java
@@ -69,15 +69,15 @@
 
   private static final ImmutableSet<Class<? extends TransitiveInfoProvider>> ALLOWED_PROVIDERS =
       ImmutableSet.of(
-        JavaCompilationArgsProvider.class,
-        JavaSourceJarsProvider.class,
-        JavaRuleOutputJarsProvider.class,
-        JavaRunfilesProvider.class,
-        JavaPluginInfoProvider.class,
-        JavaGenJarsProvider.class,
-        JavaExportsProvider.class,
-        JavaCompilationInfoProvider.class
-      );
+          JavaCompilationArgsProvider.class,
+          JavaSourceJarsProvider.class,
+          JavaRuleOutputJarsProvider.class,
+          JavaRunfilesProvider.class,
+          JavaPluginInfoProvider.class,
+          JavaGenJarsProvider.class,
+          JavaExportsProvider.class,
+          JavaCompilationInfoProvider.class,
+          JavaStrictCompilationArgsProvider.class);
 
   private final TransitiveInfoProviderMap providers;
 
@@ -118,6 +118,8 @@
   public static JavaInfo merge(List<JavaInfo> providers) {
     List<JavaCompilationArgsProvider> javaCompilationArgsProviders =
         JavaInfo.fetchProvidersFromList(providers, JavaCompilationArgsProvider.class);
+    List<JavaStrictCompilationArgsProvider> javaStrictCompilationArgsProviders =
+        JavaInfo.fetchProvidersFromList(providers, JavaStrictCompilationArgsProvider.class);
     List<JavaSourceJarsProvider> javaSourceJarsProviders =
         JavaInfo.fetchProvidersFromList(providers, JavaSourceJarsProvider.class);
     List<JavaRunfilesProvider> javaRunfilesProviders =
@@ -139,7 +141,10 @@
             JavaCompilationArgsProvider.class,
             JavaCompilationArgsProvider.merge(javaCompilationArgsProviders))
         .addProvider(
-          JavaSourceJarsProvider.class, JavaSourceJarsProvider.merge(javaSourceJarsProviders))
+            JavaStrictCompilationArgsProvider.class,
+            JavaStrictCompilationArgsProvider.merge(javaStrictCompilationArgsProviders))
+        .addProvider(
+            JavaSourceJarsProvider.class, JavaSourceJarsProvider.merge(javaSourceJarsProviders))
         // When a rule merges multiple JavaProviders, its purpose is to pass on information, so
         // it doesn't have any output jars.
         .addProvider(JavaRuleOutputJarsProvider.class, JavaRuleOutputJarsProvider.builder().build())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
index e5bb229..292e5d3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
@@ -523,4 +523,10 @@
       throws InterruptedException;
 
   Artifact getObfuscatedConstantStringMap(RuleContext ruleContext) throws InterruptedException;
+
+  /**
+   * Checks if dependency errors coming from java_proto_library rules should be treated as errors
+   * even if the java_proto_library rule sets strict_deps = 0.
+   */
+  boolean isJavaProtoLibraryStrictDeps(RuleContext ruleContext);
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaStrictCompilationArgsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaStrictCompilationArgsProvider.java
new file mode 100644
index 0000000..7eac0f1
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaStrictCompilationArgsProvider.java
@@ -0,0 +1,51 @@
+// Copyright 2018 The Bazel Authors. 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 com.google.devtools.build.lib.rules.java;
+
+import com.google.common.collect.Streams;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+/**
+ * This class just wraps a JavaCompilationArgsProvider.
+ *
+ * <p>It is used to enforce strict_deps from a downstream java_library to an upstream
+ * java_proto_library.
+ *
+ * <p>TODO(twerth): Remove this class once we finished migration.
+ */
+public class JavaStrictCompilationArgsProvider implements TransitiveInfoProvider {
+  private final JavaCompilationArgsProvider javaCompilationArgsProvider;
+
+  public JavaStrictCompilationArgsProvider(
+      JavaCompilationArgsProvider javaCompilationArgsProvider) {
+    this.javaCompilationArgsProvider = javaCompilationArgsProvider;
+  }
+
+  public JavaCompilationArgsProvider getJavaCompilationArgsProvider() {
+    return javaCompilationArgsProvider;
+  }
+
+  public static JavaStrictCompilationArgsProvider merge(
+      Collection<JavaStrictCompilationArgsProvider> providers) {
+    Collection<JavaCompilationArgsProvider> javaCompilationArgsProviders =
+        Streams.stream(providers)
+            .map(x -> x.getJavaCompilationArgsProvider())
+            .collect(Collectors.toList());
+    return new JavaStrictCompilationArgsProvider(
+        JavaCompilationArgsProvider.merge(javaCompilationArgsProviders));
+  }
+}
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 2a0a4ec..9e21d34 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
@@ -38,6 +38,7 @@
 import com.google.devtools.build.lib.rules.java.JavaRunfilesProvider;
 import com.google.devtools.build.lib.rules.java.JavaSkylarkApiProvider;
 import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider;
+import com.google.devtools.build.lib.rules.java.JavaStrictCompilationArgsProvider;
 
 /** Implementation of the java_proto_library rule. */
 public class JavaProtoLibrary implements RuleConfiguredTargetFactory {
@@ -51,6 +52,10 @@
 
     JavaCompilationArgsProvider dependencyArgsProviders =
         constructJcapFromAspectDeps(ruleContext, javaProtoLibraryAspectProviders);
+    JavaStrictCompilationArgsProvider strictDependencyArgsProviders =
+        new JavaStrictCompilationArgsProvider(
+            constructJcapFromAspectDeps(
+                ruleContext, javaProtoLibraryAspectProviders, /* alwaysStrict= */ true));
 
     // We assume that the runtime jars will not have conflicting artifacts
     // with the same root relative path
@@ -77,6 +82,7 @@
     JavaInfo javaInfo =
         JavaInfo.Builder.create()
             .addProvider(JavaCompilationArgsProvider.class, dependencyArgsProviders)
+            .addProvider(JavaStrictCompilationArgsProvider.class, strictDependencyArgsProviders)
             .addProvider(JavaSourceJarsProvider.class, sourceJarsProvider)
             .addProvider(JavaRuleOutputJarsProvider.class, JavaRuleOutputJarsProvider.EMPTY)
             .addProvider(JavaRunfilesProvider.class, javaRunfilesProvider)
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 08daa22..283a410 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
@@ -34,11 +34,19 @@
   public static JavaCompilationArgsProvider constructJcapFromAspectDeps(
       RuleContext ruleContext,
       Iterable<JavaProtoLibraryAspectProvider> javaProtoLibraryAspectProviders) {
+    return constructJcapFromAspectDeps(
+        ruleContext, javaProtoLibraryAspectProviders, /* alwaysStrict= */ false);
+  }
+
+  public static JavaCompilationArgsProvider constructJcapFromAspectDeps(
+      RuleContext ruleContext,
+      Iterable<JavaProtoLibraryAspectProvider> javaProtoLibraryAspectProviders,
+      boolean alwaysStrict) {
     JavaCompilationArgsProvider strictCompProvider =
         JavaCompilationArgsProvider.merge(
             WrappingProvider.Helper.unwrapProviders(
                 javaProtoLibraryAspectProviders, JavaCompilationArgsProvider.class));
-    if (StrictDepsUtils.isStrictDepsJavaProtoLibrary(ruleContext)) {
+    if (alwaysStrict || StrictDepsUtils.isStrictDepsJavaProtoLibrary(ruleContext)) {
       return strictCompProvider;
     } else {
       JavaCompilationArgsProvider.Builder nonStrictDirectJars =