Change allowedRuleClasses/mandatoryProviders semantics to "either-or" instead of "and".

Also allow native rules to require declared providers on their
dependencies.

--
MOS_MIGRATED_REVID=135454750
diff --git a/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java
index ec184b4..347c728 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java
@@ -27,6 +27,9 @@
 import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor.Key;
+import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.syntax.ClassObject;
 import com.google.devtools.build.lib.syntax.EvalException;
@@ -75,6 +78,18 @@
     return actual == null ? null : actual.get(providerKey);
   }
 
+  @Nullable
+  @Override
+  public SkylarkClassObject get(Key providerKey) {
+    return actual == null ? null : actual.get(providerKey);
+  }
+
+  @Nullable
+  @Override
+  public Object get(SkylarkProviderIdentifier id) {
+    return actual == null ? null : actual.get(id);
+  }
+
   @Override
   public Object getIndex(Object key, Location loc) throws EvalException {
     return actual == null ? null : actual.getIndex(key, loc);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
index 015b0f0..71f176d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.rules;
 
+import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
@@ -26,6 +27,7 @@
 import com.google.devtools.build.lib.packages.Attribute.SkylarkComputedDefaultTemplate;
 import com.google.devtools.build.lib.packages.BuildType;
 import com.google.devtools.build.lib.packages.SkylarkAspect;
+import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
 import com.google.devtools.build.lib.skylarkinterface.Param;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
@@ -258,7 +260,7 @@
         }
       }
       if (isSingleListOfStr) {
-        builder.mandatoryProviders(((SkylarkList<?>) obj).getContents(String.class, PROVIDERS_ARG));
+        builder.mandatoryProviders(getSkylarkProviderIdentifiers((SkylarkList<?>) obj));
       } else {
         builder.mandatoryProvidersList(getProvidersList((SkylarkList) obj));
       }
@@ -283,8 +285,20 @@
     return builder;
   }
 
-  private static List<List<String>> getProvidersList(SkylarkList skylarkList) throws EvalException {
-    List<List<String>> providersList = new ArrayList<>();
+  private static Iterable<SkylarkProviderIdentifier> getSkylarkProviderIdentifiers(
+      SkylarkList<?> obj) throws EvalException {
+    return Iterables.transform(obj.getContents(String.class, PROVIDERS_ARG),
+        new Function<String, SkylarkProviderIdentifier>() {
+          @Override
+          public SkylarkProviderIdentifier apply(String s) {
+            return SkylarkProviderIdentifier.forLegacy(s);
+          }
+        });
+  }
+
+  private static List<Iterable<SkylarkProviderIdentifier>> getProvidersList(
+      SkylarkList<?> skylarkList) throws EvalException {
+    List<Iterable<SkylarkProviderIdentifier>> providersList = new ArrayList<>();
     String errorMsg = "Illegal argument: element in '%s' is of unexpected type. "
         + "Should be list of string, but got %s. "
         + "Notice: one single list of string as 'providers' is still supported.";
@@ -300,7 +314,7 @@
                   + EvalUtils.getDataTypeNameFromClass(value.getClass())));
         }
       }
-      providersList.add(((SkylarkList<?>) o).getContents(String.class, PROVIDERS_ARG));
+      providersList.add(getSkylarkProviderIdentifiers((SkylarkList<?>) o));
     }
     return providersList;
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
index 50133da..6ac83f5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
@@ -311,7 +311,9 @@
         SkylarkClassObject declaredProvider = SkylarkType.cast(o, SkylarkClassObject.class, loc,
             "A return value of rule implementation function should be "
                 + "a sequence of declared providers");
-        builder.addSkylarkDeclaredProvider(declaredProvider, declaredProvider.getCreationLoc());
+        Location creationLoc = declaredProvider.getCreationLocOrNull();
+        builder.addSkylarkDeclaredProvider(declaredProvider,
+            creationLoc != null ? creationLoc : loc);
       }
     }