core: allow LBv2 impls to be stripped out by ProGuard. (#2654)

This should address the concern of increased method count as mentioned
in #2650.
diff --git a/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java b/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java
index cca6c55..7006c54 100644
--- a/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java
+++ b/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java
@@ -112,11 +112,10 @@
   @Nullable
   private NameResolver.Factory nameResolverFactory;
 
-  @Nullable
   private LoadBalancer.Factory loadBalancerFactory;
 
   @Nullable
-  private LoadBalancer2.Factory loadBalancer2Factory;
+  private ChannelFactory channelFactory;
 
   @Nullable
   private DecompressorRegistry decompressorRegistry;
@@ -206,17 +205,38 @@
         "directServerAddress is set (%s), which forbids the use of LoadBalancerFactory",
         directServerAddress);
     this.loadBalancerFactory = loadBalancerFactory;
+    this.channelFactory = null;
     return thisT();
   }
 
   /**
    * DO NOT CALL THIS, as its argument type will soon be renamed.
    */
-  public final T loadBalancerFactory(LoadBalancer2.Factory loadBalancerFactory) {
+  public final T loadBalancerFactory(final LoadBalancer2.Factory loadBalancerFactory) {
     Preconditions.checkState(directServerAddress == null,
         "directServerAddress is set (%s), which forbids the use of LoadBalancerFactory",
         directServerAddress);
-    this.loadBalancer2Factory = loadBalancerFactory;
+    this.channelFactory = new ChannelFactory() {
+        @Override
+        public ManagedChannel create(ClientTransportFactory transportFactory) {
+          return new ManagedChannelImpl2(
+              target,
+              // TODO(carl-mastrangelo): Allow clients to pass this in
+              new ExponentialBackoffPolicy.Provider(),
+              nameResolverFactory,
+              getNameResolverParams(),
+              loadBalancerFactory,
+              transportFactory,
+              firstNonNull(decompressorRegistry, DecompressorRegistry.getDefaultInstance()),
+              firstNonNull(compressorRegistry, CompressorRegistry.getDefaultInstance()),
+              SharedResourcePool.forResource(GrpcUtil.TIMER_SERVICE),
+              getExecutorPool(executor),
+              SharedResourcePool.forResource(GrpcUtil.SHARED_CHANNEL_EXECUTOR),
+              GrpcUtil.STOPWATCH_SUPPLIER, idleTimeoutMillis,
+              userAgent, interceptors, firstNonNull(statsFactory,
+              firstNonNull(Stats.getStatsContextFactory(), NoopStatsContextFactory.INSTANCE)));
+        }
+      };
     return thisT();
   }
 
@@ -294,23 +314,8 @@
       // getResource(), then this shouldn't be a problem unless called on the UI thread.
       nameResolverFactory = NameResolverProvider.asFactory();
     }
-    if (loadBalancer2Factory != null) {
-      return new ManagedChannelImpl2(
-          target,
-          // TODO(carl-mastrangelo): Allow clients to pass this in
-          new ExponentialBackoffPolicy.Provider(),
-          nameResolverFactory,
-          getNameResolverParams(),
-          loadBalancer2Factory,
-          transportFactory,
-          firstNonNull(decompressorRegistry, DecompressorRegistry.getDefaultInstance()),
-          firstNonNull(compressorRegistry, CompressorRegistry.getDefaultInstance()),
-          SharedResourcePool.forResource(GrpcUtil.TIMER_SERVICE),
-          getExecutorPool(executor),
-          SharedResourcePool.forResource(GrpcUtil.SHARED_CHANNEL_EXECUTOR),
-          GrpcUtil.STOPWATCH_SUPPLIER, idleTimeoutMillis,
-          userAgent, interceptors, firstNonNull(statsFactory,
-              firstNonNull(Stats.getStatsContextFactory(), NoopStatsContextFactory.INSTANCE)));
+    if (channelFactory != null) {
+      return channelFactory.create(transportFactory);
     } else {
       return new ManagedChannelImpl(
           target,
@@ -429,4 +434,13 @@
     T thisT = (T) this;
     return thisT;
   }
+
+  /**
+   * A temporary solution to contain the reference to ManagedChannelImpl2 in the v2 LoadBalancer
+   * setter, so that on Android ManagedChannelImpl2 can be stripped out by ProGuard since the v2
+   * setter will not be called.  This should be deleted along with the old ManagedChannelImpl.
+   */
+  private interface ChannelFactory {
+    ManagedChannel create(ClientTransportFactory transportFactory);
+  }
 }