Use a new pattern for builtin Provider objects with @SkylarkCallable.

This deprecates the old NativeProvider pattern.
The new pattern is demonstrated using AppleStaticLibraryInfo.

RELNOTES: None.
PiperOrigin-RevId: 194956883
diff --git a/src/main/java/com/google/devtools/build/lib/packages/BuiltinProvider.java b/src/main/java/com/google/devtools/build/lib/packages/BuiltinProvider.java
new file mode 100644
index 0000000..bb12ae3
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/BuiltinProvider.java
@@ -0,0 +1,91 @@
+// 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.packages;
+
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.NativeProvider.NativeKey;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
+import javax.annotation.Nullable;
+
+/**
+ * Base class for declared providers {@see Provider} defined in native code.
+ *
+ * <p>Every subclass of {@link BuiltinProvider} corresponds to a single declared
+ * provider. This is enforced by final {@link #equals(Object)} and {@link #hashCode()}.
+ *
+ * <p>Implementations of native declared providers should subclass this class, and define a method
+ * in the subclass definition to create instances of its corresponding Info object. The method
+ * should be annotated with {@link SkylarkCallable} with {@link SkylarkCallable#selfCall} set to
+ * true, and with {@link SkylarkConstructor} for the info type it constructs.
+ */
+@Immutable
+public abstract class BuiltinProvider<T extends Info> implements Provider {
+  private final NativeKey key;
+  private final String name;
+  private final Class<T> valueClass;
+
+  public Class<T> getValueClass() {
+    return valueClass;
+  }
+
+  public BuiltinProvider(String name, Class<T> valueClass) {
+    @SuppressWarnings("unchecked")
+    Class<? extends BuiltinProvider<?>> clazz = (Class<? extends BuiltinProvider<?>>) getClass();
+    key = new NativeKey(name, clazz);
+    this.name = name;
+    this.valueClass = valueClass;
+  }
+
+  /**
+   * equals() implements singleton class semantics.
+   */
+  @Override
+  public final boolean equals(@Nullable Object other) {
+    return other != null && this.getClass().equals(other.getClass());
+  }
+
+  /**
+   * hashCode() implements singleton class semantics.
+   */
+  @Override
+  public final int hashCode() {
+    return getClass().hashCode();
+  }
+
+  @Override
+  public boolean isExported() {
+    return true;
+  }
+
+  @Override
+  public NativeKey getKey() {
+    return key;
+  }
+
+  @Override
+  public Location getLocation() {
+    return Location.BUILTIN;
+  }
+
+  @Override
+  public String getPrintableName() {
+    return name;
+  }
+
+  @Override
+  public void repr(SkylarkPrinter printer) {
+    printer.append("<function " + getPrintableName() + ">");
+  }
+}