Expose XcodeConfigProvider to Starlark.

RELNOTES: None.
PiperOrigin-RevId: 280518028
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
index 99a47c7..92ec5c5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
@@ -98,8 +98,7 @@
   }
 
   /** Returns the SDK frameworks directory inside of Xcode for a given configuration. */
-  public static String sdkFrameworkDir(
-      ApplePlatform targetPlatform, XcodeConfigProvider xcodeConfig) {
+  public static String sdkFrameworkDir(ApplePlatform targetPlatform, XcodeConfigInfo xcodeConfig) {
     String relativePath;
     switch (targetPlatform) {
       case IOS_DEVICE:
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java
index 19a2a99..ec35110 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java
@@ -93,12 +93,17 @@
     DottedVersion macosMinimumOsVersion = (appleOptions.macosMinimumOs != null)
         ? DottedVersion.maybeUnwrap(appleOptions.macosMinimumOs) : macosSdkVersion;
 
-    XcodeConfigProvider xcodeVersions = new XcodeConfigProvider(
-        iosSdkVersion, iosMinimumOsVersion,
-        watchosSdkVersion, watchosMinimumOsVersion,
-        tvosSdkVersion, tvosMinimumOsVersion,
-        macosSdkVersion, macosMinimumOsVersion,
-        xcodeVersionProperties.getXcodeVersion().orNull());
+    XcodeConfigInfo xcodeVersions =
+        new XcodeConfigInfo(
+            iosSdkVersion,
+            iosMinimumOsVersion,
+            watchosSdkVersion,
+            watchosMinimumOsVersion,
+            tvosSdkVersion,
+            tvosMinimumOsVersion,
+            macosSdkVersion,
+            macosMinimumOsVersion,
+            xcodeVersionProperties.getXcodeVersion().orNull());
 
     AppleBitcodeMode bitcodeMode = appleConfig.getBitcodeMode();
     DottedVersion xcodeVersion = xcodeVersions.getXcodeVersion();
@@ -249,10 +254,10 @@
             alias, Joiner.on(", ").join(labelsContainingAlias.build())));
   }
 
-  public static XcodeConfigProvider getXcodeConfigProvider(RuleContext ruleContext) {
+  public static XcodeConfigInfo getXcodeConfigInfo(RuleContext ruleContext) {
     return ruleContext.getPrerequisite(
         XcodeConfigRule.XCODE_CONFIG_ATTR_NAME,
         RuleConfiguredTarget.Mode.TARGET,
-        XcodeConfigProvider.PROVIDER);
+        XcodeConfigInfo.PROVIDER);
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigProvider.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigInfo.java
similarity index 62%
rename from src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigProvider.java
rename to src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigInfo.java
index 2607806..dbc82d9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigInfo.java
@@ -17,23 +17,24 @@
 import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.packages.BuiltinProvider;
 import com.google.devtools.build.lib.packages.NativeInfo;
-import com.google.devtools.build.lib.packages.NativeProvider;
-import com.google.devtools.build.lib.skylarkbuildapi.apple.XcodeConfigProviderApi;
+import com.google.devtools.build.lib.rules.apple.ApplePlatform.PlatformType;
+import com.google.devtools.build.lib.skylarkbuildapi.apple.XcodeConfigInfoApi;
+import com.google.devtools.build.lib.syntax.EvalException;
 import javax.annotation.Nullable;
 
 /**
  * The set of Apple versions computed from command line options and the {@code xcode_config} rule.
  */
 @Immutable
-public class XcodeConfigProvider extends NativeInfo
-    implements XcodeConfigProviderApi<ApplePlatform, ApplePlatform.PlatformType> {
+public class XcodeConfigInfo extends NativeInfo
+    implements XcodeConfigInfoApi<ApplePlatform, PlatformType> {
   /** Skylark name for this provider. */
   public static final String SKYLARK_NAME = "XcodeVersionConfig";
 
-  /** Provider identifier for {@link XcodeConfigProvider}. */
-  public static final NativeProvider<XcodeConfigProvider> PROVIDER =
-      new NativeProvider<XcodeConfigProvider>(XcodeConfigProvider.class, SKYLARK_NAME) {};
+  /** Provider identifier for {@link XcodeConfigInfo}. */
+  public static final BuiltinProvider<XcodeConfigInfo> PROVIDER = new XcodeConfigProvider();
 
   private final DottedVersion iosSdkVersion;
   private final DottedVersion iosMinimumOsVersion;
@@ -45,11 +46,15 @@
   private final DottedVersion macosMinimumOsVersion;
   @Nullable private final DottedVersion xcodeVersion;
 
-  public XcodeConfigProvider(
-      DottedVersion iosSdkVersion, DottedVersion iosMinimumOsVersion,
-      DottedVersion watchosSdkVersion, DottedVersion watchosMinimumOsVersion,
-      DottedVersion tvosSdkVersion, DottedVersion tvosMinimumOsVersion,
-      DottedVersion macosSdkVersion, DottedVersion macosMinimumOsVersion,
+  public XcodeConfigInfo(
+      DottedVersion iosSdkVersion,
+      DottedVersion iosMinimumOsVersion,
+      DottedVersion watchosSdkVersion,
+      DottedVersion watchosMinimumOsVersion,
+      DottedVersion tvosSdkVersion,
+      DottedVersion tvosMinimumOsVersion,
+      DottedVersion macosSdkVersion,
+      DottedVersion macosMinimumOsVersion,
       DottedVersion xcodeVersion) {
     super(PROVIDER);
     this.iosSdkVersion = Preconditions.checkNotNull(iosSdkVersion);
@@ -63,6 +68,43 @@
     this.xcodeVersion = xcodeVersion;
   }
 
+  /** Provider for class {@link XcodeConfigInfo} objects. */
+  private static class XcodeConfigProvider extends BuiltinProvider<XcodeConfigInfo>
+      implements XcodeConfigProviderApi {
+    XcodeConfigInfo xcodeConfigInfo;
+
+    private XcodeConfigProvider() {
+      super(SKYLARK_NAME, XcodeConfigInfo.class);
+    }
+
+    @Override
+    public XcodeConfigInfoApi<?, ?> xcodeConfigInfo(
+        String iosSdkVersion,
+        String iosMinimumOsVersion,
+        String watchosSdkVersion,
+        String watchosMinimumOsVersion,
+        String tvosSdkVersion,
+        String tvosMinimumOsVersion,
+        String macosSdkVersion,
+        String macosMinimumOsVersion,
+        String xcodeVersion)
+        throws EvalException {
+      try {
+        return new XcodeConfigInfo(
+            DottedVersion.fromString(iosSdkVersion),
+            DottedVersion.fromString(iosMinimumOsVersion),
+            DottedVersion.fromString(watchosSdkVersion),
+            DottedVersion.fromString(watchosMinimumOsVersion),
+            DottedVersion.fromString(tvosSdkVersion),
+            DottedVersion.fromString(tvosMinimumOsVersion),
+            DottedVersion.fromString(macosSdkVersion),
+            DottedVersion.fromString(macosMinimumOsVersion),
+            DottedVersion.fromString(xcodeVersion));
+      } catch (DottedVersion.InvalidDottedVersionException e) {
+        throw new EvalException(null, e);
+      }
+    }
+  }
   /**
    * Returns the value of the xcode version, if available. This is determined based on a combination
    * of the {@code --xcode_version} build flag and the {@code xcode_config} target defined in the
@@ -90,9 +132,8 @@
         return watchosMinimumOsVersion;
       case MACOS:
         return macosMinimumOsVersion;
-      default:
-        throw new IllegalArgumentException("Unhandled platform type: " + platformType);
     }
+    throw new IllegalArgumentException("Unhandled platform type: " + platformType);
   }
 
   /**
@@ -113,13 +154,12 @@
         return watchosSdkVersion;
       case MACOS:
         return macosSdkVersion;
-      default:
-        throw new IllegalArgumentException("Unhandled platform: " + platform);
     }
+    throw new IllegalArgumentException("Unhandled platform: " + platform);
   }
 
-  public static XcodeConfigProvider fromRuleContext(RuleContext ruleContext) {
+  public static XcodeConfigInfo fromRuleContext(RuleContext ruleContext) {
     return ruleContext.getPrerequisite(
-        XcodeConfigRule.XCODE_CONFIG_ATTR_NAME, Mode.TARGET, XcodeConfigProvider.PROVIDER);
+        XcodeConfigRule.XCODE_CONFIG_ATTR_NAME, Mode.TARGET, XcodeConfigInfo.PROVIDER);
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/cpp/AppleCcToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/apple/cpp/AppleCcToolchain.java
index d5dbb91..08b1e37 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/cpp/AppleCcToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/cpp/AppleCcToolchain.java
@@ -22,7 +22,7 @@
 import com.google.devtools.build.lib.rules.apple.ApplePlatform;
 import com.google.devtools.build.lib.rules.apple.AppleToolchain;
 import com.google.devtools.build.lib.rules.apple.XcodeConfig;
-import com.google.devtools.build.lib.rules.apple.XcodeConfigProvider;
+import com.google.devtools.build.lib.rules.apple.XcodeConfigInfo;
 import com.google.devtools.build.lib.rules.cpp.CcToolchain;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainVariables;
 import java.io.Serializable;
@@ -57,20 +57,20 @@
   protected AdditionalBuildVariablesComputer getAdditionalBuildVariablesComputer(
       RuleContext ruleContextPossiblyInHostConfiguration) {
     // xcode config is shared between target and host configuration therefore we can use it.
-    XcodeConfigProvider xcodeConfig =
-        XcodeConfig.getXcodeConfigProvider(ruleContextPossiblyInHostConfiguration);
+    XcodeConfigInfo xcodeConfig =
+        XcodeConfig.getXcodeConfigInfo(ruleContextPossiblyInHostConfiguration);
     return getAdditionalBuildVariablesComputer(xcodeConfig);
   }
 
   /** Returns {@link AdditionalBuildVariablesComputer} lambda without capturing instance state. */
   private static AdditionalBuildVariablesComputer getAdditionalBuildVariablesComputer(
-      XcodeConfigProvider xcodeConfig) {
+      XcodeConfigInfo xcodeConfig) {
     return (AdditionalBuildVariablesComputer & Serializable)
         (BuildOptions buildOptions) -> computeCcToolchainVariables(xcodeConfig, buildOptions);
   }
 
   private static CcToolchainVariables computeCcToolchainVariables(
-      XcodeConfigProvider xcodeConfig, BuildOptions buildOptions) {
+      XcodeConfigInfo xcodeConfig, BuildOptions buildOptions) {
     AppleConfiguration.Loader appleConfigurationLoader = new AppleConfiguration.Loader();
     AppleConfiguration appleConfiguration = appleConfigurationLoader.create(buildOptions);
     ApplePlatform platform = appleConfiguration.getSingleArchPlatform();
@@ -123,7 +123,7 @@
   }
 
   private static ImmutableMap<String, String> getEnvironmentBuildVariables(
-      XcodeConfigProvider xcodeConfig, String cpu) {
+      XcodeConfigInfo xcodeConfig, String cpu) {
     Map<String, String> builder = new LinkedHashMap<>();
     builder.putAll(AppleConfiguration.getXcodeVersionEnv(xcodeConfig.getXcodeVersion()));
     if (ApplePlatform.isApplePlatform(cpu)) {
@@ -142,7 +142,7 @@
 
   @Override
   protected void validateToolchain(RuleContext ruleContext) throws RuleErrorException {
-    if (XcodeConfig.getXcodeConfigProvider(ruleContext).getXcodeVersion() == null) {
+    if (XcodeConfig.getXcodeConfigInfo(ruleContext).getXcodeVersion() == null) {
       ruleContext.throwWithRuleError(
           "Xcode version must be specified to use an Apple CROSSTOOL. If your Xcode version has "
               + "changed recently, verify that \"xcode-select -p\" is correct and then try: "
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
index 6767018..25eea64 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
@@ -35,7 +35,7 @@
 import com.google.devtools.build.lib.rules.apple.ApplePlatform.PlatformType;
 import com.google.devtools.build.lib.rules.apple.AppleToolchain;
 import com.google.devtools.build.lib.rules.apple.DottedVersion;
-import com.google.devtools.build.lib.rules.apple.XcodeConfigProvider;
+import com.google.devtools.build.lib.rules.apple.XcodeConfigInfo;
 import com.google.devtools.build.lib.rules.apple.XcodeVersionProperties;
 import com.google.devtools.build.lib.rules.objc.AppleBinary.AppleBinaryOutput;
 import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key;
@@ -52,11 +52,9 @@
 import java.util.Map;
 import javax.annotation.Nullable;
 
-/**
- * A class that exposes apple rule implementation internals to skylark.
- */
+/** A class that exposes apple rule implementation internals to skylark. */
 public class AppleSkylarkCommon
-    implements AppleCommonApi<Artifact, ObjcProvider, XcodeConfigProvider, ApplePlatform> {
+    implements AppleCommonApi<Artifact, ObjcProvider, XcodeConfigInfo, ApplePlatform> {
 
   @VisibleForTesting
   public static final String BAD_KEY_ERROR = "Argument %s not a recognized key, 'providers',"
@@ -118,7 +116,7 @@
 
   @Override
   public Provider getXcodeVersionConfigConstructor() {
-    return XcodeConfigProvider.PROVIDER;
+    return XcodeConfigInfo.PROVIDER;
   }
 
   @Override
@@ -157,14 +155,14 @@
   }
 
   @Override
-  public ImmutableMap<String, String> getAppleHostSystemEnv(XcodeConfigProvider xcodeConfig) {
+  public ImmutableMap<String, String> getAppleHostSystemEnv(XcodeConfigInfo xcodeConfig) {
     return AppleConfiguration.getXcodeVersionEnv(xcodeConfig.getXcodeVersion());
   }
 
   @Override
   public ImmutableMap<String, String> getTargetAppleEnvironment(
-      XcodeConfigProvider xcodeConfigApi, ApplePlatform platformApi) {
-    XcodeConfigProvider xcodeConfig = (XcodeConfigProvider) xcodeConfigApi;
+      XcodeConfigInfo xcodeConfigApi, ApplePlatform platformApi) {
+    XcodeConfigInfo xcodeConfig = xcodeConfigApi;
     ApplePlatform platform = (ApplePlatform) platformApi;
     return AppleConfiguration.appleTargetPlatformEnv(
         platform, xcodeConfig.getSdkVersionForPlatform(platform));
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
index 5f76fca..5719156 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
@@ -87,7 +87,7 @@
 import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions.AppleBitcodeMode;
 import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
 import com.google.devtools.build.lib.rules.apple.XcodeConfig;
-import com.google.devtools.build.lib.rules.apple.XcodeConfigProvider;
+import com.google.devtools.build.lib.rules.apple.XcodeConfigInfo;
 import com.google.devtools.build.lib.rules.cpp.CcCommon;
 import com.google.devtools.build.lib.rules.cpp.CcCompilationContext;
 import com.google.devtools.build.lib.rules.cpp.CcCompilationHelper;
@@ -608,7 +608,7 @@
     // components in the version number.
     activatedCrosstoolSelectables.add(
         XCODE_VERSION_FEATURE_NAME_PREFIX
-            + XcodeConfig.getXcodeConfigProvider(ruleContext)
+            + XcodeConfig.getXcodeConfigInfo(ruleContext)
                 .getXcodeVersion()
                 .toStringWithComponents(2));
 
@@ -1491,7 +1491,7 @@
 
       ruleContext.registerAction(
           ObjcRuleClasses.spawnAppleEnvActionBuilder(
-                  XcodeConfigProvider.fromRuleContext(ruleContext),
+                  XcodeConfigInfo.fromRuleContext(ruleContext),
                   appleConfiguration.getSingleArchPlatform())
               .setMnemonic("DummyPruner")
               .setExecutable(pruner)
@@ -1606,7 +1606,7 @@
 
     ruleContext.registerAction(
         ObjcRuleClasses.spawnAppleEnvActionBuilder(
-                XcodeConfigProvider.fromRuleContext(ruleContext),
+                XcodeConfigInfo.fromRuleContext(ruleContext),
                 appleConfiguration.getSingleArchPlatform())
             .setMnemonic("ObjcBinarySymbolStrip")
             .setExecutable(xcrunwrapper(ruleContext))
@@ -1846,12 +1846,12 @@
             .add("--platform", appleConfiguration.getSingleArchPlatform().getLowerCaseNameInPlist())
             .add(
                 "--sdk_version",
-                XcodeConfig.getXcodeConfigProvider(ruleContext)
+                XcodeConfig.getXcodeConfigInfo(ruleContext)
                     .getSdkVersionForPlatform(appleConfiguration.getSingleArchPlatform())
                     .toStringWithMinimumComponents(2))
             .add(
                 "--xcode_version",
-                XcodeConfig.getXcodeConfigProvider(ruleContext)
+                XcodeConfig.getXcodeConfigInfo(ruleContext)
                     .getXcodeVersion()
                     .toStringWithMinimumComponents(2))
             .add("--");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/LipoSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/LipoSupport.java
index 456acc6..d921d88 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/LipoSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/LipoSupport.java
@@ -21,7 +21,7 @@
 import com.google.devtools.build.lib.analysis.actions.SymlinkAction;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.rules.apple.ApplePlatform;
-import com.google.devtools.build.lib.rules.apple.XcodeConfigProvider;
+import com.google.devtools.build.lib.rules.apple.XcodeConfigInfo;
 
 /**
  * Support for registering actions using the Apple tool "lipo", which combines artifacts of
@@ -48,7 +48,7 @@
     if (inputBinaries.toList().size() > 1) {
       ruleContext.registerAction(
           ObjcRuleClasses.spawnAppleEnvActionBuilder(
-                  XcodeConfigProvider.fromRuleContext(ruleContext), platform)
+                  XcodeConfigInfo.fromRuleContext(ruleContext), platform)
               .setMnemonic("ObjcCombiningArchitectures")
               .addTransitiveInputs(inputBinaries)
               .addOutput(outputBinary)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
index 4c55dc0..35a06dd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
@@ -50,7 +50,7 @@
 import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
 import com.google.devtools.build.lib.rules.apple.ApplePlatform;
 import com.google.devtools.build.lib.rules.apple.AppleToolchain.RequiresXcodeConfigRule;
-import com.google.devtools.build.lib.rules.apple.XcodeConfigProvider;
+import com.google.devtools.build.lib.rules.apple.XcodeConfigInfo;
 import com.google.devtools.build.lib.rules.cpp.CcToolchain;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider;
 import com.google.devtools.build.lib.rules.cpp.CppModuleMap.UmbrellaHeaderStrategy;
@@ -146,18 +146,19 @@
    * which contain information about the target and host architectures.
    */
   static SpawnAction.Builder spawnAppleEnvActionBuilder(
-      XcodeConfigProvider xcodeConfigProvider, ApplePlatform targetPlatform) {
+      XcodeConfigInfo xcodeConfigInfo, ApplePlatform targetPlatform) {
     return spawnOnDarwinActionBuilder()
-        .setEnvironment(appleToolchainEnvironment(xcodeConfigProvider, targetPlatform));
+        .setEnvironment(appleToolchainEnvironment(xcodeConfigInfo, targetPlatform));
   }
 
   /** Returns apple environment variables that are typically needed by the apple toolchain. */
   static ImmutableMap<String, String> appleToolchainEnvironment(
-      XcodeConfigProvider xcodeConfigProvider, ApplePlatform targetPlatform) {
+      XcodeConfigInfo xcodeConfigInfo, ApplePlatform targetPlatform) {
     return ImmutableMap.<String, String>builder()
-        .putAll(AppleConfiguration.appleTargetPlatformEnv(
-            targetPlatform, xcodeConfigProvider.getSdkVersionForPlatform(targetPlatform)))
-        .putAll(AppleConfiguration.getXcodeVersionEnv(xcodeConfigProvider.getXcodeVersion()))
+        .putAll(
+            AppleConfiguration.appleTargetPlatformEnv(
+                targetPlatform, xcodeConfigInfo.getSdkVersionForPlatform(targetPlatform)))
+        .putAll(AppleConfiguration.getXcodeVersionEnv(xcodeConfigInfo.getXcodeVersion()))
         .build();
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/apple/AppleCommonApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/apple/AppleCommonApi.java
index 4ef083d..57d0867 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/apple/AppleCommonApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/apple/AppleCommonApi.java
@@ -39,7 +39,7 @@
 public interface AppleCommonApi<
         FileApiT extends FileApi,
         ObjcProviderApiT extends ObjcProviderApi<?>,
-        XcodeConfigProviderApiT extends XcodeConfigProviderApi<?, ?>,
+        XcodeConfigInfoApiT extends XcodeConfigInfoApi<?, ?>,
         ApplePlatformApiT extends ApplePlatformApi>
     extends SkylarkValue {
 
@@ -222,13 +222,10 @@
             name = "xcode_config",
             positional = true,
             named = false,
-            type = XcodeConfigProviderApi.class,
-            doc = "A provider containing information about the xcode configuration."
-        ),
-      }
-  )
-  public ImmutableMap<String, String> getAppleHostSystemEnv(
-      XcodeConfigProviderApiT xcodeConfig);
+            type = XcodeConfigInfoApi.class,
+            doc = "A provider containing information about the xcode configuration."),
+      })
+  public ImmutableMap<String, String> getAppleHostSystemEnv(XcodeConfigInfoApiT xcodeConfig);
 
   @SkylarkCallable(
       name = "target_apple_env",
@@ -242,20 +239,17 @@
             name = "xcode_config",
             positional = true,
             named = false,
-            type = XcodeConfigProviderApi.class,
-            doc = "A provider containing information about the xcode configuration."
-        ),
+            type = XcodeConfigInfoApi.class,
+            doc = "A provider containing information about the xcode configuration."),
         @Param(
             name = "platform",
             positional = true,
             named = false,
             type = ApplePlatformApi.class,
-            doc = "The apple platform."
-        ),
-      }
-  )
+            doc = "The apple platform."),
+      })
   public ImmutableMap<String, String> getTargetAppleEnvironment(
-      XcodeConfigProviderApiT xcodeConfig, ApplePlatformApiT platform);
+      XcodeConfigInfoApiT xcodeConfig, ApplePlatformApiT platform);
 
   @SkylarkCallable(
       name = "multi_arch_split",
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/apple/XcodeConfigInfoApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/apple/XcodeConfigInfoApi.java
new file mode 100644
index 0000000..39e9998
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/apple/XcodeConfigInfoApi.java
@@ -0,0 +1,151 @@
+// 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.skylarkbuildapi.apple;
+
+import com.google.devtools.build.lib.skylarkbuildapi.ProviderApi;
+import com.google.devtools.build.lib.skylarkbuildapi.StructApi;
+import com.google.devtools.build.lib.skylarkinterface.Param;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkConstructor;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
+import com.google.devtools.build.lib.syntax.EvalException;
+
+/**
+ * An interface for an info type containing the set of Apple versions computed from command line
+ * options and the {@code xcode_config} rule.
+ */
+@SkylarkModule(
+    name = "XcodeVersionConfig",
+    category = SkylarkModuleCategory.PROVIDER,
+    doc = "The set of Apple versions computed from command line options and the xcode_config rule.")
+public interface XcodeConfigInfoApi<
+        ApplePlatformApiT extends ApplePlatformApi,
+        ApplePlatformTypeApiT extends ApplePlatformTypeApi>
+    extends StructApi {
+
+  @SkylarkCallable(
+      name = "xcode_version",
+      doc =
+          "Returns the Xcode version that is being used to build.<p>"
+              + "This will return <code>None</code> if no Xcode versions are available.",
+      allowReturnNones = true)
+  public DottedVersionApi<?> getXcodeVersion();
+
+  @SkylarkCallable(
+      name = "minimum_os_for_platform_type",
+      doc =
+          "The minimum compatible OS version for target simulator and devices for a particular "
+              + "platform type.",
+      parameters = {
+        @Param(
+            name = "platform_type",
+            positional = true,
+            named = false,
+            type = ApplePlatformTypeApi.class,
+            doc = "The apple platform type."),
+      })
+  public DottedVersionApi<?> getMinimumOsForPlatformType(ApplePlatformTypeApiT platformType);
+
+  @SkylarkCallable(
+      name = "sdk_version_for_platform",
+      doc =
+          "The version of the platform SDK that will be used to build targets for the given "
+              + "platform.",
+      parameters = {
+        @Param(
+            name = "platform",
+            positional = true,
+            named = false,
+            type = ApplePlatformApi.class,
+            doc = "The apple platform."),
+      })
+  public DottedVersionApi<?> getSdkVersionForPlatform(ApplePlatformApiT platform);
+
+  /** An interface for the provider of {@link XcodeConfigInfoApi}. */
+  @SkylarkModule(
+      name = "Provider",
+      category = SkylarkModuleCategory.PROVIDER,
+      documented = false,
+      doc = "")
+  public interface XcodeConfigProviderApi extends ProviderApi {
+
+    @SkylarkCallable(
+        name = "XcodeVersionConfig",
+        doc = "Returns the Xcode info that is associated with this target",
+        parameters = {
+          @Param(
+              name = "iosSdkVersion",
+              named = true,
+              positional = false,
+              doc = "The ios SDK version."),
+          @Param(
+              name = "iosMinimumOsVersion",
+              named = true,
+              positional = false,
+              doc = "The ios minimum os version."),
+          @Param(
+              name = "watchosSdkVersion",
+              named = true,
+              positional = false,
+              doc = "The watchos SDK version."),
+          @Param(
+              name = "watchosMinimumOsVersion",
+              named = true,
+              positional = false,
+              doc = "The watchos minimum os version."),
+          @Param(
+              name = "tvosSdkVersion",
+              named = true,
+              positional = false,
+              doc = "The tvos SDK version."),
+          @Param(
+              name = "tvosMinimumOsVersion",
+              named = true,
+              positional = false,
+              doc = "The tvos minimum os version."),
+          @Param(
+              name = "macosSdkVersion",
+              named = true,
+              positional = false,
+              doc = "The macos SDK version."),
+          @Param(
+              name = "macosMinimumOsVersion",
+              named = true,
+              positional = false,
+              doc = "The macos minimum os version."),
+          @Param(
+              name = "xcodeVersion",
+              named = true,
+              positional = false,
+              doc = "The selected Xcode version from this config."),
+        },
+        selfCall = true)
+    @SkylarkConstructor(
+        objectType = XcodeConfigInfoApi.class,
+        receiverNameForDoc = "XcodeConfigInfo")
+    public XcodeConfigInfoApi<?, ?> xcodeConfigInfo(
+        String iosSdkVersion,
+        String iosMinimumOsVersion,
+        String watchosSdkVersion,
+        String watchosMinimumOsVersion,
+        String tvosSdkVersion,
+        String tvosMinimumOsVersion,
+        String macosSdkVersion,
+        String macosMinimumOsVersion,
+        String xcodeVersion)
+        throws EvalException;
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/apple/XcodeConfigProviderApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/apple/XcodeConfigProviderApi.java
deleted file mode 100644
index 2d04a4a..0000000
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/apple/XcodeConfigProviderApi.java
+++ /dev/null
@@ -1,72 +0,0 @@
-// 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.skylarkbuildapi.apple;
-
-import com.google.devtools.build.lib.skylarkbuildapi.StructApi;
-import com.google.devtools.build.lib.skylarkinterface.Param;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
-
-/**
- * An interface for an info type containing the set of Apple versions computed from command line
- * options and the {@code xcode_config} rule.
- */
-@SkylarkModule(
-    name = "XcodeVersionConfig",
-    category = SkylarkModuleCategory.PROVIDER,
-    doc = "The set of Apple versions computed from command line options and the xcode_config rule.")
-public interface XcodeConfigProviderApi<
-        ApplePlatformApiT extends ApplePlatformApi,
-        ApplePlatformTypeApiT extends ApplePlatformTypeApi>
-    extends StructApi {
-
-  @SkylarkCallable(name = "xcode_version",
-      doc = "Returns the Xcode version that is being used to build.<p>"
-          + "This will return <code>None</code> if no Xcode versions are available.",
-      allowReturnNones = true)
-  public DottedVersionApi<?> getXcodeVersion();
-
-  @SkylarkCallable(
-      name = "minimum_os_for_platform_type",
-      doc = "The minimum compatible OS version for target simulator and devices for a particular "
-          + "platform type.",
-      parameters = {
-        @Param(
-            name = "platform_type",
-            positional = true,
-            named = false,
-            type = ApplePlatformTypeApi.class,
-            doc = "The apple platform type."
-        ),
-      }
-  )
-  public DottedVersionApi<?> getMinimumOsForPlatformType(ApplePlatformTypeApiT platformType);
-
-  @SkylarkCallable(
-      name = "sdk_version_for_platform",
-      doc = "The version of the platform SDK that will be used to build targets for the given "
-          + "platform.",
-      parameters = {
-        @Param(
-            name = "platform",
-            positional = true,
-            named = false,
-            type = ApplePlatformApi.class,
-            doc = "The apple platform."
-        ),
-      })
-  public DottedVersionApi<?> getSdkVersionForPlatform(ApplePlatformApiT platform);
-}
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/apple/FakeAppleCommon.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/apple/FakeAppleCommon.java
index 441593c..438ef1b 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/apple/FakeAppleCommon.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/apple/FakeAppleCommon.java
@@ -28,7 +28,7 @@
 import com.google.devtools.build.lib.skylarkbuildapi.apple.AppleToolchainApi;
 import com.google.devtools.build.lib.skylarkbuildapi.apple.DottedVersionApi;
 import com.google.devtools.build.lib.skylarkbuildapi.apple.ObjcProviderApi;
-import com.google.devtools.build.lib.skylarkbuildapi.apple.XcodeConfigProviderApi;
+import com.google.devtools.build.lib.skylarkbuildapi.apple.XcodeConfigInfoApi;
 import com.google.devtools.build.lib.syntax.Dict;
 import com.google.devtools.build.lib.syntax.Sequence;
 import com.google.devtools.build.lib.syntax.StarlarkThread;
@@ -38,14 +38,10 @@
 import com.google.devtools.build.skydoc.fakebuildapi.FakeStructApi;
 import com.google.devtools.build.skydoc.fakebuildapi.apple.FakeAppleStaticLibraryInfo.FakeAppleStaticLibraryInfoProvider;
 
-/**
- * Fake implementation of {@link AppleCommonApi}.
- */
-public class FakeAppleCommon implements AppleCommonApi<
-    FileApi,
-    ObjcProviderApi<?>,
-    XcodeConfigProviderApi<?, ?>,
-    ApplePlatformApi> {
+/** Fake implementation of {@link AppleCommonApi}. */
+public class FakeAppleCommon
+    implements AppleCommonApi<
+        FileApi, ObjcProviderApi<?>, XcodeConfigInfoApi<?, ?>, ApplePlatformApi> {
 
   @Override
   public AppleToolchainApi<?> getAppleToolchain() {
@@ -153,14 +149,12 @@
 
   @Override
   public ImmutableMap<String, String> getTargetAppleEnvironment(
-      XcodeConfigProviderApi<?, ?> xcodeConfig,
-      ApplePlatformApi platform) {
+      XcodeConfigInfoApi<?, ?> xcodeConfig, ApplePlatformApi platform) {
     return ImmutableMap.of();
   }
 
   @Override
-  public ImmutableMap<String, String> getAppleHostSystemEnv(
-      XcodeConfigProviderApi<?, ?> xcodeConfig) {
+  public ImmutableMap<String, String> getAppleHostSystemEnv(XcodeConfigInfoApi<?, ?> xcodeConfig) {
     return ImmutableMap.of();
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/rules/apple/XcodeConfigTest.java b/src/test/java/com/google/devtools/build/lib/rules/apple/XcodeConfigTest.java
index dd0ed8c..89affe7 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/apple/XcodeConfigTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/apple/XcodeConfigTest.java
@@ -15,6 +15,7 @@
 package com.google.devtools.build.lib.rules.apple;
 
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
@@ -23,6 +24,7 @@
 import com.google.devtools.build.lib.packages.ConfiguredAttributeMapper;
 import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.packages.SkylarkProvider;
+import com.google.devtools.build.lib.packages.SkylarkProvider.SkylarkKey;
 import com.google.devtools.build.lib.packages.StructImpl;
 import com.google.devtools.build.lib.packages.Type;
 import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
@@ -71,6 +73,103 @@
   }
 
   @Test
+  public void xcodeVersionConfig_isFunction() throws Exception {
+    scratch.file(
+        "foo/extension.bzl",
+        "result = provider()",
+        "def _impl(ctx):",
+        "  return [result(xcode_version ="
+            + " apple_common.XcodeVersionConfig("
+            + " iosSdkVersion='1.1',"
+            + " iosMinimumOsVersion='1.2',"
+            + " watchosSdkVersion='1.3',"
+            + " watchosMinimumOsVersion='1.4',"
+            + " tvosSdkVersion='1.5',"
+            + " tvosMinimumOsVersion='1.6',"
+            + " macosSdkVersion='1.7',"
+            + " macosMinimumOsVersion='1.8',"
+            + " xcodeVersion='1.9'))]",
+        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
+    scratch.file("foo/BUILD", "load(':extension.bzl', 'my_rule')", "my_rule(name='test')");
+    assertNoEvents();
+    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:test");
+    StructImpl info =
+        (StructImpl)
+            myRuleTarget.get(
+                new SkylarkKey(
+                    Label.parseAbsolute("//foo:extension.bzl", ImmutableMap.of()), "result"));
+    assertThat(info.getValue("xcode_version"))
+        .isEqualTo(
+            new XcodeConfigInfo(
+                DottedVersion.fromStringUnchecked("1.1"),
+                DottedVersion.fromStringUnchecked("1.2"),
+                DottedVersion.fromStringUnchecked("1.3"),
+                DottedVersion.fromStringUnchecked("1.4"),
+                DottedVersion.fromStringUnchecked("1.5"),
+                DottedVersion.fromStringUnchecked("1.6"),
+                DottedVersion.fromStringUnchecked("1.7"),
+                DottedVersion.fromStringUnchecked("1.8"),
+                DottedVersion.fromStringUnchecked("1.9")));
+  }
+
+  @Test
+  public void xcodeVersionConfig_throwsOnBadInput() throws Exception {
+    scratch.file(
+        "foo/extension.bzl",
+        "result = provider()",
+        "def _impl(ctx):",
+        "  return [result(xcode_version ="
+            + " apple_common.XcodeVersionConfig("
+            + " iosSdkVersion='not a valid dotted version',"
+            + " iosMinimumOsVersion='1.2',"
+            + " watchosSdkVersion='1.3',"
+            + " watchosMinimumOsVersion='1.4',"
+            + " tvosSdkVersion='1.5',"
+            + " tvosMinimumOsVersion='1.6',"
+            + " macosSdkVersion='1.7',"
+            + " macosMinimumOsVersion='1.8',"
+            + " xcodeVersion='1.9'))]",
+        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
+    scratch.file("foo/BUILD", "load(':extension.bzl', 'my_rule')", "my_rule(name='test')");
+    assertNoEvents();
+    assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:test"));
+    assertContainsEvent("Dotted version components must all be of the form");
+    assertContainsEvent("got 'not a valid dotted version'");
+  }
+
+  @Test
+  public void xcodeVersionConfig_exposesExpectedAttributes() throws Exception {
+    scratch.file(
+        "foo/extension.bzl",
+        "result = provider()",
+        "def _impl(ctx):",
+        "  xcode_version ="
+            + " apple_common.XcodeVersionConfig("
+            + " iosSdkVersion='1.1',"
+            + " iosMinimumOsVersion='1.2',"
+            + " watchosSdkVersion='1.3',"
+            + " watchosMinimumOsVersion='1.4',"
+            + " tvosSdkVersion='1.5',"
+            + " tvosMinimumOsVersion='1.6',"
+            + " macosSdkVersion='1.7',"
+            + " macosMinimumOsVersion='1.8',"
+            + " xcodeVersion='1.9')",
+        "  return [result(xcode_version=xcode_version.xcode_version(),"
+            + " min_os=xcode_version.minimum_os_for_platform_type(ctx.fragments.apple.single_arch_platform.platform_type)),]",
+        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() },  fragments = ['apple'])");
+    scratch.file("foo/BUILD", "load(':extension.bzl', 'my_rule')", "my_rule(name='test')");
+    assertNoEvents();
+    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:test");
+    StructImpl info =
+        (StructImpl)
+            myRuleTarget.get(
+                new SkylarkKey(
+                    Label.parseAbsolute("//foo:extension.bzl", ImmutableMap.of()), "result"));
+    assertThat(info.getValue("xcode_version").toString()).isEqualTo("1.9");
+    assertThat(info.getValue("min_os").toString()).isEqualTo("1.8");
+  }
+
+  @Test
   public void testConfigAlias_configSetting() throws Exception {
     scratch.file("skylark/BUILD");
     scratch.file(
@@ -761,13 +860,13 @@
 
   private DottedVersion getSdkVersionForPlatform(ApplePlatform platform) throws Exception {
     ConfiguredTarget xcodeConfig = getConfiguredTarget("//xcode:foo");
-    XcodeConfigProvider provider = xcodeConfig.get(XcodeConfigProvider.PROVIDER);
+    XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER);
     return provider.getSdkVersionForPlatform(platform);
   }
 
   private DottedVersion getMinimumOsVersionForPlatform(ApplePlatform platform) throws Exception {
     ConfiguredTarget xcodeConfig = getConfiguredTarget("//xcode:foo");
-    XcodeConfigProvider provider = xcodeConfig.get(XcodeConfigProvider.PROVIDER);
+    XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER);
     return provider.getMinimumOsForPlatformType(platform.getType());
   }
 
@@ -777,7 +876,7 @@
 
   private void assertXcodeVersion(String version, String providerTargetLabel) throws Exception {
     ConfiguredTarget xcodeConfig = getConfiguredTarget(providerTargetLabel);
-    XcodeConfigProvider provider = xcodeConfig.get(XcodeConfigProvider.PROVIDER);
+    XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER);
     assertThat(provider.getXcodeVersion()).isEqualTo(DottedVersion.fromString(version));
   }