Get rid of AbstractServiceDescriptor as it is no longer useful
diff --git a/benchmarks/src/generated/main/grpc/io/grpc/testing/TestServiceGrpc.java b/benchmarks/src/generated/main/grpc/io/grpc/testing/TestServiceGrpc.java
index 5dfcc13..4d980e3 100644
--- a/benchmarks/src/generated/main/grpc/io/grpc/testing/TestServiceGrpc.java
+++ b/benchmarks/src/generated/main/grpc/io/grpc/testing/TestServiceGrpc.java
@@ -23,7 +23,6 @@
           "grpc.testing.TestService", "UnaryCall",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.SimpleRequest.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.SimpleResponse.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.SimpleRequest,
       io.grpc.testing.SimpleResponse> METHOD_STREAMING_CALL =
       io.grpc.MethodDescriptor.create(
@@ -33,59 +32,17 @@
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.SimpleResponse.parser()));
 
   public static TestServiceStub newStub(io.grpc.Channel channel) {
-    return new TestServiceStub(channel, CONFIG);
+    return new TestServiceStub(channel);
   }
 
   public static TestServiceBlockingStub newBlockingStub(
       io.grpc.Channel channel) {
-    return new TestServiceBlockingStub(channel, CONFIG);
+    return new TestServiceBlockingStub(channel);
   }
 
   public static TestServiceFutureStub newFutureStub(
       io.grpc.Channel channel) {
-    return new TestServiceFutureStub(channel, CONFIG);
-  }
-
-  // The default service descriptor
-  private static final TestServiceServiceDescriptor CONFIG =
-      new TestServiceServiceDescriptor();
-
-  @javax.annotation.concurrent.Immutable
-  public static class TestServiceServiceDescriptor extends
-      io.grpc.stub.AbstractServiceDescriptor<TestServiceServiceDescriptor> {
-    public final io.grpc.MethodDescriptor<io.grpc.testing.SimpleRequest,
-        io.grpc.testing.SimpleResponse> unaryCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.SimpleRequest,
-        io.grpc.testing.SimpleResponse> streamingCall;
-
-    private TestServiceServiceDescriptor() {
-      unaryCall = METHOD_UNARY_CALL;
-      streamingCall = METHOD_STREAMING_CALL;
-    }
-
-    @SuppressWarnings("unchecked")
-    private TestServiceServiceDescriptor(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      unaryCall = (io.grpc.MethodDescriptor<io.grpc.testing.SimpleRequest,
-          io.grpc.testing.SimpleResponse>) methodMap.get(
-          CONFIG.unaryCall.getFullMethodName());
-      streamingCall = (io.grpc.MethodDescriptor<io.grpc.testing.SimpleRequest,
-          io.grpc.testing.SimpleResponse>) methodMap.get(
-          CONFIG.streamingCall.getFullMethodName());
-    }
-
-    @java.lang.Override
-    protected TestServiceServiceDescriptor build(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      return new TestServiceServiceDescriptor(methodMap);
-    }
-
-    @java.lang.Override
-    public java.util.Collection<io.grpc.MethodDescriptor<?, ?>> methods() {
-      return com.google.common.collect.ImmutableList.<io.grpc.MethodDescriptor<?, ?>>of(
-          unaryCall,
-          streamingCall);
-    }
+    return new TestServiceFutureStub(channel);
   }
 
   public static interface TestService {
@@ -108,96 +65,84 @@
         io.grpc.testing.SimpleRequest request);
   }
 
-  public static class TestServiceStub extends
-      io.grpc.stub.AbstractStub<TestServiceStub, TestServiceServiceDescriptor>
+  public static class TestServiceStub extends io.grpc.stub.AbstractStub<TestServiceStub>
       implements TestService {
-    private TestServiceStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config) {
-      super(channel, config);
+    private TestServiceStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private TestServiceStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected TestServiceStub build(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new TestServiceStub(channel, config, callOptions);
+      return new TestServiceStub(channel, callOptions);
     }
 
     @java.lang.Override
     public void unaryCall(io.grpc.testing.SimpleRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.SimpleResponse> responseObserver) {
       asyncUnaryCall(
-          channel.newCall(config.unaryCall, callOptions), request, responseObserver);
+          channel.newCall(METHOD_UNARY_CALL, callOptions), request, responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.SimpleRequest> streamingCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.SimpleResponse> responseObserver) {
       return asyncDuplexStreamingCall(
-          channel.newCall(config.streamingCall, callOptions), responseObserver);
+          channel.newCall(METHOD_STREAMING_CALL, callOptions), responseObserver);
     }
   }
 
-  public static class TestServiceBlockingStub extends
-      io.grpc.stub.AbstractStub<TestServiceBlockingStub, TestServiceServiceDescriptor>
+  public static class TestServiceBlockingStub extends io.grpc.stub.AbstractStub<TestServiceBlockingStub>
       implements TestServiceBlockingClient {
-    private TestServiceBlockingStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config) {
-      super(channel, config);
+    private TestServiceBlockingStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private TestServiceBlockingStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected TestServiceBlockingStub build(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new TestServiceBlockingStub(channel, config, callOptions);
+      return new TestServiceBlockingStub(channel, callOptions);
     }
 
     @java.lang.Override
     public io.grpc.testing.SimpleResponse unaryCall(io.grpc.testing.SimpleRequest request) {
       return blockingUnaryCall(
-          channel.newCall(config.unaryCall, callOptions), request);
+          channel.newCall(METHOD_UNARY_CALL, callOptions), request);
     }
   }
 
-  public static class TestServiceFutureStub extends
-      io.grpc.stub.AbstractStub<TestServiceFutureStub, TestServiceServiceDescriptor>
+  public static class TestServiceFutureStub extends io.grpc.stub.AbstractStub<TestServiceFutureStub>
       implements TestServiceFutureClient {
-    private TestServiceFutureStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config) {
-      super(channel, config);
+    private TestServiceFutureStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private TestServiceFutureStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected TestServiceFutureStub build(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new TestServiceFutureStub(channel, config, callOptions);
+      return new TestServiceFutureStub(channel, callOptions);
     }
 
     @java.lang.Override
     public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.SimpleResponse> unaryCall(
         io.grpc.testing.SimpleRequest request) {
       return futureUnaryCall(
-          channel.newCall(config.unaryCall, callOptions), request);
+          channel.newCall(METHOD_UNARY_CALL, callOptions), request);
     }
   }
 
diff --git a/benchmarks/src/generated/main/grpc/io/grpc/testing/WorkerGrpc.java b/benchmarks/src/generated/main/grpc/io/grpc/testing/WorkerGrpc.java
index 82220ae..ccea8f1 100644
--- a/benchmarks/src/generated/main/grpc/io/grpc/testing/WorkerGrpc.java
+++ b/benchmarks/src/generated/main/grpc/io/grpc/testing/WorkerGrpc.java
@@ -23,7 +23,6 @@
           "grpc.testing.Worker", "RunTest",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.ClientArgs.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.ClientStatus.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.ServerArgs,
       io.grpc.testing.ServerStatus> METHOD_RUN_SERVER =
       io.grpc.MethodDescriptor.create(
@@ -33,59 +32,17 @@
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.ServerStatus.parser()));
 
   public static WorkerStub newStub(io.grpc.Channel channel) {
-    return new WorkerStub(channel, CONFIG);
+    return new WorkerStub(channel);
   }
 
   public static WorkerBlockingStub newBlockingStub(
       io.grpc.Channel channel) {
-    return new WorkerBlockingStub(channel, CONFIG);
+    return new WorkerBlockingStub(channel);
   }
 
   public static WorkerFutureStub newFutureStub(
       io.grpc.Channel channel) {
-    return new WorkerFutureStub(channel, CONFIG);
-  }
-
-  // The default service descriptor
-  private static final WorkerServiceDescriptor CONFIG =
-      new WorkerServiceDescriptor();
-
-  @javax.annotation.concurrent.Immutable
-  public static class WorkerServiceDescriptor extends
-      io.grpc.stub.AbstractServiceDescriptor<WorkerServiceDescriptor> {
-    public final io.grpc.MethodDescriptor<io.grpc.testing.ClientArgs,
-        io.grpc.testing.ClientStatus> runTest;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.ServerArgs,
-        io.grpc.testing.ServerStatus> runServer;
-
-    private WorkerServiceDescriptor() {
-      runTest = METHOD_RUN_TEST;
-      runServer = METHOD_RUN_SERVER;
-    }
-
-    @SuppressWarnings("unchecked")
-    private WorkerServiceDescriptor(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      runTest = (io.grpc.MethodDescriptor<io.grpc.testing.ClientArgs,
-          io.grpc.testing.ClientStatus>) methodMap.get(
-          CONFIG.runTest.getFullMethodName());
-      runServer = (io.grpc.MethodDescriptor<io.grpc.testing.ServerArgs,
-          io.grpc.testing.ServerStatus>) methodMap.get(
-          CONFIG.runServer.getFullMethodName());
-    }
-
-    @java.lang.Override
-    protected WorkerServiceDescriptor build(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      return new WorkerServiceDescriptor(methodMap);
-    }
-
-    @java.lang.Override
-    public java.util.Collection<io.grpc.MethodDescriptor<?, ?>> methods() {
-      return com.google.common.collect.ImmutableList.<io.grpc.MethodDescriptor<?, ?>>of(
-          runTest,
-          runServer);
-    }
+    return new WorkerFutureStub(channel);
   }
 
   public static interface Worker {
@@ -103,83 +60,71 @@
   public static interface WorkerFutureClient {
   }
 
-  public static class WorkerStub extends
-      io.grpc.stub.AbstractStub<WorkerStub, WorkerServiceDescriptor>
+  public static class WorkerStub extends io.grpc.stub.AbstractStub<WorkerStub>
       implements Worker {
-    private WorkerStub(io.grpc.Channel channel,
-        WorkerServiceDescriptor config) {
-      super(channel, config);
+    private WorkerStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private WorkerStub(io.grpc.Channel channel,
-        WorkerServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected WorkerStub build(io.grpc.Channel channel,
-        WorkerServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new WorkerStub(channel, config, callOptions);
+      return new WorkerStub(channel, callOptions);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.ClientArgs> runTest(
         io.grpc.stub.StreamObserver<io.grpc.testing.ClientStatus> responseObserver) {
       return asyncDuplexStreamingCall(
-          channel.newCall(config.runTest, callOptions), responseObserver);
+          channel.newCall(METHOD_RUN_TEST, callOptions), responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.ServerArgs> runServer(
         io.grpc.stub.StreamObserver<io.grpc.testing.ServerStatus> responseObserver) {
       return asyncDuplexStreamingCall(
-          channel.newCall(config.runServer, callOptions), responseObserver);
+          channel.newCall(METHOD_RUN_SERVER, callOptions), responseObserver);
     }
   }
 
-  public static class WorkerBlockingStub extends
-      io.grpc.stub.AbstractStub<WorkerBlockingStub, WorkerServiceDescriptor>
+  public static class WorkerBlockingStub extends io.grpc.stub.AbstractStub<WorkerBlockingStub>
       implements WorkerBlockingClient {
-    private WorkerBlockingStub(io.grpc.Channel channel,
-        WorkerServiceDescriptor config) {
-      super(channel, config);
+    private WorkerBlockingStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private WorkerBlockingStub(io.grpc.Channel channel,
-        WorkerServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected WorkerBlockingStub build(io.grpc.Channel channel,
-        WorkerServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new WorkerBlockingStub(channel, config, callOptions);
+      return new WorkerBlockingStub(channel, callOptions);
     }
   }
 
-  public static class WorkerFutureStub extends
-      io.grpc.stub.AbstractStub<WorkerFutureStub, WorkerServiceDescriptor>
+  public static class WorkerFutureStub extends io.grpc.stub.AbstractStub<WorkerFutureStub>
       implements WorkerFutureClient {
-    private WorkerFutureStub(io.grpc.Channel channel,
-        WorkerServiceDescriptor config) {
-      super(channel, config);
+    private WorkerFutureStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private WorkerFutureStub(io.grpc.Channel channel,
-        WorkerServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected WorkerFutureStub build(io.grpc.Channel channel,
-        WorkerServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new WorkerFutureStub(channel, config, callOptions);
+      return new WorkerFutureStub(channel, callOptions);
     }
   }
 
diff --git a/compiler/src/java_plugin/cpp/java_generator.cpp b/compiler/src/java_plugin/cpp/java_generator.cpp
index 07af2f1..7bff09d 100644
--- a/compiler/src/java_plugin/cpp/java_generator.cpp
+++ b/compiler/src/java_plugin/cpp/java_generator.cpp
@@ -62,6 +62,7 @@
 static void PrintMethodFields(
     const ServiceDescriptor* service, map<string, string>* vars, Printer* p,
     bool generate_nano) {
+  p->Print("// Static method descriptors that strictly reflect the proto.\n");
   (*vars)["service_name"] = service->name();
   for (int i = 0; i < service->method_count(); ++i) {
     const MethodDescriptor* method = service->method(i);
@@ -85,8 +86,6 @@
       }
     }
 
-    p->Print("// Static method descriptors that strictly reflect the proto.\n");
-
     if (generate_nano) {
       // TODO(zsurocking): we're creating two Parsers for each method right now.
       // We could instead create static Parsers and reuse them if some methods
@@ -129,105 +128,6 @@
   p->Print("\n");
 }
 
-static void PrintServiceDescriptor(
-    const ServiceDescriptor* service, map<string, string>* vars, Printer* p) {
-  (*vars)["service_name"] = service->name();
-  p->Print(
-      *vars,
-      "@$Immutable$\n");
-  p->Print(
-      *vars,
-      "public static class $service_name$ServiceDescriptor extends\n"
-      "    $AbstractServiceDescriptor$<$service_name$ServiceDescriptor> {\n");
-  p->Indent();
-
-  // Service descriptor fields
-  for (int i = 0; i < service->method_count(); ++i) {
-    const MethodDescriptor* method = service->method(i);
-    (*vars)["input_type"] = MessageFullJavaName(method->input_type());
-    (*vars)["output_type"] = MessageFullJavaName(method->output_type());
-    (*vars)["lower_method_name"] = LowerMethodName(method);
-    p->Print(
-        *vars,
-        "public final $MethodDescriptor$<$input_type$,\n"
-        "    $output_type$> $lower_method_name$;\n");
-  }
-
-  // The default constructor
-  p->Print(
-      *vars,
-      "\nprivate $service_name$ServiceDescriptor() {\n");
-  p->Indent();
-  for (int i = 0; i < service->method_count(); ++i) {
-    const MethodDescriptor* method = service->method(i);
-    (*vars)["method_field_name"] = MethodPropertiesFieldName(method);
-    (*vars)["lower_method_name"] = LowerMethodName(method);
-    p->Print(*vars,
-             "$lower_method_name$ = $method_field_name$;\n");
-  }
-  p->Outdent();
-  p->Print("}\n");
-
-  // The reconfiguring constructor
-  p->Print(
-      *vars,
-      "\n@SuppressWarnings(\"unchecked\")\n"
-      "private $service_name$ServiceDescriptor(\n"
-      "    $Map$<$String$, $MethodDescriptor$<?, ?>> methodMap) {\n");
-  p->Indent();
-  for (int i = 0; i < service->method_count(); ++i) {
-    const MethodDescriptor* method = service->method(i);
-    (*vars)["input_type"] = MessageFullJavaName(method->input_type());
-    (*vars)["output_type"] = MessageFullJavaName(method->output_type());
-    (*vars)["lower_method_name"] = LowerMethodName(method);
-    (*vars)["method_field_name"] = MethodPropertiesFieldName(method);
-    p->Print(
-        *vars,
-        "$lower_method_name$ = ($MethodDescriptor$<$input_type$,\n"
-        "    $output_type$>) methodMap.get(\n"
-        "    CONFIG.$lower_method_name$.getFullMethodName());\n");
-  }
-  p->Outdent();
-  p->Print("}\n\n");
-
-  p->Print(
-      *vars,
-      "@$Override$\nprotected $service_name$ServiceDescriptor build(\n"
-      "    $Map$<$String$, $MethodDescriptor$<?, ?>> methodMap) {\n");
-  p->Indent();
-  p->Print(
-      *vars,
-      "return new $service_name$ServiceDescriptor(methodMap);\n");
-  p->Outdent();
-  p->Print("}\n\n");
-
-  p->Print(
-      *vars,
-      "@$Override$\n"
-      "public $Collection$<$MethodDescriptor$<?, ?>> methods() {\n");
-  p->Indent();
-  p->Print(
-      *vars,
-      "return $ImmutableList$.<$MethodDescriptor$<?, ?>>of(\n");
-  p->Indent();
-  p->Indent();
-  for (int i = 0; i < service->method_count(); ++i) {
-    p->Print(MixedLower(service->method(i)->name()).c_str());
-    if (i < service->method_count() - 1) {
-      p->Print(",\n");
-    } else {
-      p->Print(");\n");
-    }
-  }
-  p->Outdent();
-  p->Outdent();
-  p->Outdent();
-  p->Print("}\n");
-
-  p->Outdent();
-  p->Print("}\n\n");
-}
-
 enum StubType {
   ASYNC_INTERFACE = 0,
   BLOCKING_CLIENT_INTERFACE = 1,
@@ -314,8 +214,7 @@
   } else {
     p->Print(
         *vars,
-        "public static class $impl_name$ extends\n"
-        "    $AbstractStub$<$impl_name$, $service_name$ServiceDescriptor>\n"
+        "public static class $impl_name$ extends $AbstractStub$<$impl_name$>\n"
         "    implements $interface_name$ {\n");
   }
   p->Indent();
@@ -324,31 +223,28 @@
   if (impl) {
     p->Print(
         *vars,
-        "private $impl_name$($Channel$ channel,\n"
-        "    $service_name$ServiceDescriptor config) {\n");
+        "private $impl_name$($Channel$ channel) {\n");
     p->Indent();
-    p->Print("super(channel, config);\n");
+    p->Print("super(channel);\n");
     p->Outdent();
     p->Print("}\n\n");
     p->Print(
         *vars,
         "private $impl_name$($Channel$ channel,\n"
-        "    $service_name$ServiceDescriptor config,\n"
         "    $CallOptions$ callOptions) {\n");
     p->Indent();
-    p->Print("super(channel, config, callOptions);\n");
+    p->Print("super(channel, callOptions);\n");
     p->Outdent();
     p->Print("}\n\n");
     p->Print(
         *vars,
         "@$Override$\n"
         "protected $impl_name$ build($Channel$ channel,\n"
-        "    $service_name$ServiceDescriptor config,\n"
         "    $CallOptions$ callOptions) {\n");
     p->Indent();
     p->Print(
         *vars,
-        "return new $impl_name$(channel, config, callOptions);\n");
+        "return new $impl_name$(channel, callOptions);\n");
     p->Outdent();
     p->Print("}\n");
   }
@@ -359,6 +255,7 @@
     (*vars)["input_type"] = MessageFullJavaName(method->input_type());
     (*vars)["output_type"] = MessageFullJavaName(method->output_type());
     (*vars)["lower_method_name"] = LowerMethodName(method);
+    (*vars)["method_field_name"] = MethodPropertiesFieldName(method);
     bool client_streaming = method->client_streaming();
     bool server_streaming = method->server_streaming();
 
@@ -444,7 +341,7 @@
           p->Print(
               *vars,
               "return $calls_method$(\n"
-              "    channel.newCall(config.$lower_method_name$, callOptions), $params$);\n");
+              "    channel.newCall($method_field_name$, callOptions), $params$);\n");
           break;
         case ASYNC_CALL:
           if (server_streaming) {
@@ -468,7 +365,7 @@
           p->Print(
               *vars,
               "$last_line_prefix$$calls_method$(\n"
-              "    channel.newCall(config.$lower_method_name$, callOptions), $params$);\n");
+              "    channel.newCall($method_field_name$, callOptions), $params$);\n");
           break;
         case FUTURE_CALL:
           CHECK(!client_streaming && !server_streaming)
@@ -479,7 +376,7 @@
           p->Print(
               *vars,
               "return $calls_method$(\n"
-              "    channel.newCall(config.$lower_method_name$, callOptions), request);\n");
+              "    channel.newCall($method_field_name$, callOptions), request);\n");
           break;
       }
       p->Outdent();
@@ -602,7 +499,7 @@
   p->Indent();
   p->Print(
       *vars,
-      "return new $service_name$Stub(channel, CONFIG);\n");
+      "return new $service_name$Stub(channel);\n");
   p->Outdent();
   p->Print("}\n\n");
   p->Print(
@@ -612,7 +509,7 @@
   p->Indent();
   p->Print(
       *vars,
-      "return new $service_name$BlockingStub(channel, CONFIG);\n");
+      "return new $service_name$BlockingStub(channel);\n");
   p->Outdent();
   p->Print("}\n\n");
   p->Print(
@@ -622,16 +519,10 @@
   p->Indent();
   p->Print(
       *vars,
-      "return new $service_name$FutureStub(channel, CONFIG);\n");
+      "return new $service_name$FutureStub(channel);\n");
   p->Outdent();
   p->Print("}\n\n");
 
-  p->Print("// The default service descriptor\n");
-  p->Print(
-      *vars,
-      "private static final $service_name$ServiceDescriptor CONFIG =\n"
-      "    new $service_name$ServiceDescriptor();\n\n");
-  PrintServiceDescriptor(service, vars, p);
   PrintStub(service, vars, p, ASYNC_INTERFACE);
   PrintStub(service, vars, p, BLOCKING_CLIENT_INTERFACE);
   PrintStub(service, vars, p, FUTURE_CLIENT_INTERFACE);
@@ -688,8 +579,6 @@
   vars["ServerServiceDefinition"] =
       "io.grpc.ServerServiceDefinition";
   vars["AbstractStub"] = "io.grpc.stub.AbstractStub";
-  vars["AbstractServiceDescriptor"] =
-      "io.grpc.stub.AbstractServiceDescriptor";
   vars["ImmutableList"] = "com.google.common.collect.ImmutableList";
   vars["Collection"] = "java.util.Collection";
   vars["MethodDescriptor"] = "io.grpc.MethodDescriptor";
diff --git a/compiler/src/test/golden/TestService.java.txt b/compiler/src/test/golden/TestService.java.txt
index 78c11c1..dcf1d83 100644
--- a/compiler/src/test/golden/TestService.java.txt
+++ b/compiler/src/test/golden/TestService.java.txt
@@ -23,7 +23,6 @@
           "grpc.testing.TestService", "UnaryCall",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Test.SimpleRequest.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Test.SimpleResponse.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
       io.grpc.testing.integration.Test.StreamingOutputCallResponse> METHOD_STREAMING_OUTPUT_CALL =
       io.grpc.MethodDescriptor.create(
@@ -31,7 +30,6 @@
           "grpc.testing.TestService", "StreamingOutputCall",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Test.StreamingOutputCallRequest.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Test.StreamingOutputCallResponse.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingInputCallRequest,
       io.grpc.testing.integration.Test.StreamingInputCallResponse> METHOD_STREAMING_INPUT_CALL =
       io.grpc.MethodDescriptor.create(
@@ -39,7 +37,6 @@
           "grpc.testing.TestService", "StreamingInputCall",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Test.StreamingInputCallRequest.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Test.StreamingInputCallResponse.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
       io.grpc.testing.integration.Test.StreamingOutputCallResponse> METHOD_FULL_DUPLEX_CALL =
       io.grpc.MethodDescriptor.create(
@@ -47,7 +44,6 @@
           "grpc.testing.TestService", "FullDuplexCall",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Test.StreamingOutputCallRequest.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Test.StreamingOutputCallResponse.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
       io.grpc.testing.integration.Test.StreamingOutputCallResponse> METHOD_HALF_DUPLEX_CALL =
       io.grpc.MethodDescriptor.create(
@@ -57,80 +53,17 @@
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Test.StreamingOutputCallResponse.parser()));
 
   public static TestServiceStub newStub(io.grpc.Channel channel) {
-    return new TestServiceStub(channel, CONFIG);
+    return new TestServiceStub(channel);
   }
 
   public static TestServiceBlockingStub newBlockingStub(
       io.grpc.Channel channel) {
-    return new TestServiceBlockingStub(channel, CONFIG);
+    return new TestServiceBlockingStub(channel);
   }
 
   public static TestServiceFutureStub newFutureStub(
       io.grpc.Channel channel) {
-    return new TestServiceFutureStub(channel, CONFIG);
-  }
-
-  // The default service descriptor
-  private static final TestServiceServiceDescriptor CONFIG =
-      new TestServiceServiceDescriptor();
-
-  @javax.annotation.concurrent.Immutable
-  public static class TestServiceServiceDescriptor extends
-      io.grpc.stub.AbstractServiceDescriptor<TestServiceServiceDescriptor> {
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.SimpleRequest,
-        io.grpc.testing.integration.Test.SimpleResponse> unaryCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-        io.grpc.testing.integration.Test.StreamingOutputCallResponse> streamingOutputCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingInputCallRequest,
-        io.grpc.testing.integration.Test.StreamingInputCallResponse> streamingInputCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-        io.grpc.testing.integration.Test.StreamingOutputCallResponse> fullDuplexCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-        io.grpc.testing.integration.Test.StreamingOutputCallResponse> halfDuplexCall;
-
-    private TestServiceServiceDescriptor() {
-      unaryCall = METHOD_UNARY_CALL;
-      streamingOutputCall = METHOD_STREAMING_OUTPUT_CALL;
-      streamingInputCall = METHOD_STREAMING_INPUT_CALL;
-      fullDuplexCall = METHOD_FULL_DUPLEX_CALL;
-      halfDuplexCall = METHOD_HALF_DUPLEX_CALL;
-    }
-
-    @SuppressWarnings("unchecked")
-    private TestServiceServiceDescriptor(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      unaryCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.SimpleRequest,
-          io.grpc.testing.integration.Test.SimpleResponse>) methodMap.get(
-          CONFIG.unaryCall.getFullMethodName());
-      streamingOutputCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-          io.grpc.testing.integration.Test.StreamingOutputCallResponse>) methodMap.get(
-          CONFIG.streamingOutputCall.getFullMethodName());
-      streamingInputCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingInputCallRequest,
-          io.grpc.testing.integration.Test.StreamingInputCallResponse>) methodMap.get(
-          CONFIG.streamingInputCall.getFullMethodName());
-      fullDuplexCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-          io.grpc.testing.integration.Test.StreamingOutputCallResponse>) methodMap.get(
-          CONFIG.fullDuplexCall.getFullMethodName());
-      halfDuplexCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-          io.grpc.testing.integration.Test.StreamingOutputCallResponse>) methodMap.get(
-          CONFIG.halfDuplexCall.getFullMethodName());
-    }
-
-    @java.lang.Override
-    protected TestServiceServiceDescriptor build(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      return new TestServiceServiceDescriptor(methodMap);
-    }
-
-    @java.lang.Override
-    public java.util.Collection<io.grpc.MethodDescriptor<?, ?>> methods() {
-      return com.google.common.collect.ImmutableList.<io.grpc.MethodDescriptor<?, ?>>of(
-          unaryCall,
-          streamingOutputCall,
-          streamingInputCall,
-          fullDuplexCall,
-          halfDuplexCall);
-    }
+    return new TestServiceFutureStub(channel);
   }
 
   public static interface TestService {
@@ -165,124 +98,112 @@
         io.grpc.testing.integration.Test.SimpleRequest request);
   }
 
-  public static class TestServiceStub extends
-      io.grpc.stub.AbstractStub<TestServiceStub, TestServiceServiceDescriptor>
+  public static class TestServiceStub extends io.grpc.stub.AbstractStub<TestServiceStub>
       implements TestService {
-    private TestServiceStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config) {
-      super(channel, config);
+    private TestServiceStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private TestServiceStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected TestServiceStub build(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new TestServiceStub(channel, config, callOptions);
+      return new TestServiceStub(channel, callOptions);
     }
 
     @java.lang.Override
     public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver) {
       asyncUnaryCall(
-          channel.newCall(config.unaryCall, callOptions), request, responseObserver);
+          channel.newCall(METHOD_UNARY_CALL, callOptions), request, responseObserver);
     }
 
     @java.lang.Override
     public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
       asyncServerStreamingCall(
-          channel.newCall(config.streamingOutputCall, callOptions), request, responseObserver);
+          channel.newCall(METHOD_STREAMING_OUTPUT_CALL, callOptions), request, responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver) {
       return asyncClientStreamingCall(
-          channel.newCall(config.streamingInputCall, callOptions), responseObserver);
+          channel.newCall(METHOD_STREAMING_INPUT_CALL, callOptions), responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullDuplexCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
       return asyncDuplexStreamingCall(
-          channel.newCall(config.fullDuplexCall, callOptions), responseObserver);
+          channel.newCall(METHOD_FULL_DUPLEX_CALL, callOptions), responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfDuplexCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
       return asyncDuplexStreamingCall(
-          channel.newCall(config.halfDuplexCall, callOptions), responseObserver);
+          channel.newCall(METHOD_HALF_DUPLEX_CALL, callOptions), responseObserver);
     }
   }
 
-  public static class TestServiceBlockingStub extends
-      io.grpc.stub.AbstractStub<TestServiceBlockingStub, TestServiceServiceDescriptor>
+  public static class TestServiceBlockingStub extends io.grpc.stub.AbstractStub<TestServiceBlockingStub>
       implements TestServiceBlockingClient {
-    private TestServiceBlockingStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config) {
-      super(channel, config);
+    private TestServiceBlockingStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private TestServiceBlockingStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected TestServiceBlockingStub build(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new TestServiceBlockingStub(channel, config, callOptions);
+      return new TestServiceBlockingStub(channel, callOptions);
     }
 
     @java.lang.Override
     public io.grpc.testing.integration.Test.SimpleResponse unaryCall(io.grpc.testing.integration.Test.SimpleRequest request) {
       return blockingUnaryCall(
-          channel.newCall(config.unaryCall, callOptions), request);
+          channel.newCall(METHOD_UNARY_CALL, callOptions), request);
     }
 
     @java.lang.Override
     public java.util.Iterator<io.grpc.testing.integration.Test.StreamingOutputCallResponse> streamingOutputCall(
         io.grpc.testing.integration.Test.StreamingOutputCallRequest request) {
       return blockingServerStreamingCall(
-          channel.newCall(config.streamingOutputCall, callOptions), request);
+          channel.newCall(METHOD_STREAMING_OUTPUT_CALL, callOptions), request);
     }
   }
 
-  public static class TestServiceFutureStub extends
-      io.grpc.stub.AbstractStub<TestServiceFutureStub, TestServiceServiceDescriptor>
+  public static class TestServiceFutureStub extends io.grpc.stub.AbstractStub<TestServiceFutureStub>
       implements TestServiceFutureClient {
-    private TestServiceFutureStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config) {
-      super(channel, config);
+    private TestServiceFutureStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private TestServiceFutureStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected TestServiceFutureStub build(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new TestServiceFutureStub(channel, config, callOptions);
+      return new TestServiceFutureStub(channel, callOptions);
     }
 
     @java.lang.Override
     public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.integration.Test.SimpleResponse> unaryCall(
         io.grpc.testing.integration.Test.SimpleRequest request) {
       return futureUnaryCall(
-          channel.newCall(config.unaryCall, callOptions), request);
+          channel.newCall(METHOD_UNARY_CALL, callOptions), request);
     }
   }
 
diff --git a/compiler/src/test/golden/TestServiceNano.java.txt b/compiler/src/test/golden/TestServiceNano.java.txt
index 9c6ea67..1b823ab 100644
--- a/compiler/src/test/golden/TestServiceNano.java.txt
+++ b/compiler/src/test/golden/TestServiceNano.java.txt
@@ -37,7 +37,6 @@
                       return io.grpc.testing.integration.Test.SimpleResponse.parseFrom(input);
                   }
           }));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
       io.grpc.testing.integration.Test.StreamingOutputCallResponse> METHOD_STREAMING_OUTPUT_CALL =
       io.grpc.MethodDescriptor.create(
@@ -57,7 +56,6 @@
                       return io.grpc.testing.integration.Test.StreamingOutputCallResponse.parseFrom(input);
                   }
           }));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingInputCallRequest,
       io.grpc.testing.integration.Test.StreamingInputCallResponse> METHOD_STREAMING_INPUT_CALL =
       io.grpc.MethodDescriptor.create(
@@ -77,7 +75,6 @@
                       return io.grpc.testing.integration.Test.StreamingInputCallResponse.parseFrom(input);
                   }
           }));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
       io.grpc.testing.integration.Test.StreamingOutputCallResponse> METHOD_FULL_DUPLEX_CALL =
       io.grpc.MethodDescriptor.create(
@@ -97,7 +94,6 @@
                       return io.grpc.testing.integration.Test.StreamingOutputCallResponse.parseFrom(input);
                   }
           }));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
       io.grpc.testing.integration.Test.StreamingOutputCallResponse> METHOD_HALF_DUPLEX_CALL =
       io.grpc.MethodDescriptor.create(
@@ -119,80 +115,17 @@
           }));
 
   public static TestServiceStub newStub(io.grpc.Channel channel) {
-    return new TestServiceStub(channel, CONFIG);
+    return new TestServiceStub(channel);
   }
 
   public static TestServiceBlockingStub newBlockingStub(
       io.grpc.Channel channel) {
-    return new TestServiceBlockingStub(channel, CONFIG);
+    return new TestServiceBlockingStub(channel);
   }
 
   public static TestServiceFutureStub newFutureStub(
       io.grpc.Channel channel) {
-    return new TestServiceFutureStub(channel, CONFIG);
-  }
-
-  // The default service descriptor
-  private static final TestServiceServiceDescriptor CONFIG =
-      new TestServiceServiceDescriptor();
-
-  @javax.annotation.concurrent.Immutable
-  public static class TestServiceServiceDescriptor extends
-      io.grpc.stub.AbstractServiceDescriptor<TestServiceServiceDescriptor> {
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.SimpleRequest,
-        io.grpc.testing.integration.Test.SimpleResponse> unaryCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-        io.grpc.testing.integration.Test.StreamingOutputCallResponse> streamingOutputCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingInputCallRequest,
-        io.grpc.testing.integration.Test.StreamingInputCallResponse> streamingInputCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-        io.grpc.testing.integration.Test.StreamingOutputCallResponse> fullDuplexCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-        io.grpc.testing.integration.Test.StreamingOutputCallResponse> halfDuplexCall;
-
-    private TestServiceServiceDescriptor() {
-      unaryCall = METHOD_UNARY_CALL;
-      streamingOutputCall = METHOD_STREAMING_OUTPUT_CALL;
-      streamingInputCall = METHOD_STREAMING_INPUT_CALL;
-      fullDuplexCall = METHOD_FULL_DUPLEX_CALL;
-      halfDuplexCall = METHOD_HALF_DUPLEX_CALL;
-    }
-
-    @SuppressWarnings("unchecked")
-    private TestServiceServiceDescriptor(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      unaryCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.SimpleRequest,
-          io.grpc.testing.integration.Test.SimpleResponse>) methodMap.get(
-          CONFIG.unaryCall.getFullMethodName());
-      streamingOutputCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-          io.grpc.testing.integration.Test.StreamingOutputCallResponse>) methodMap.get(
-          CONFIG.streamingOutputCall.getFullMethodName());
-      streamingInputCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingInputCallRequest,
-          io.grpc.testing.integration.Test.StreamingInputCallResponse>) methodMap.get(
-          CONFIG.streamingInputCall.getFullMethodName());
-      fullDuplexCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-          io.grpc.testing.integration.Test.StreamingOutputCallResponse>) methodMap.get(
-          CONFIG.fullDuplexCall.getFullMethodName());
-      halfDuplexCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-          io.grpc.testing.integration.Test.StreamingOutputCallResponse>) methodMap.get(
-          CONFIG.halfDuplexCall.getFullMethodName());
-    }
-
-    @java.lang.Override
-    protected TestServiceServiceDescriptor build(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      return new TestServiceServiceDescriptor(methodMap);
-    }
-
-    @java.lang.Override
-    public java.util.Collection<io.grpc.MethodDescriptor<?, ?>> methods() {
-      return com.google.common.collect.ImmutableList.<io.grpc.MethodDescriptor<?, ?>>of(
-          unaryCall,
-          streamingOutputCall,
-          streamingInputCall,
-          fullDuplexCall,
-          halfDuplexCall);
-    }
+    return new TestServiceFutureStub(channel);
   }
 
   public static interface TestService {
@@ -227,124 +160,112 @@
         io.grpc.testing.integration.Test.SimpleRequest request);
   }
 
-  public static class TestServiceStub extends
-      io.grpc.stub.AbstractStub<TestServiceStub, TestServiceServiceDescriptor>
+  public static class TestServiceStub extends io.grpc.stub.AbstractStub<TestServiceStub>
       implements TestService {
-    private TestServiceStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config) {
-      super(channel, config);
+    private TestServiceStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private TestServiceStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected TestServiceStub build(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new TestServiceStub(channel, config, callOptions);
+      return new TestServiceStub(channel, callOptions);
     }
 
     @java.lang.Override
     public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver) {
       asyncUnaryCall(
-          channel.newCall(config.unaryCall, callOptions), request, responseObserver);
+          channel.newCall(METHOD_UNARY_CALL, callOptions), request, responseObserver);
     }
 
     @java.lang.Override
     public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
       asyncServerStreamingCall(
-          channel.newCall(config.streamingOutputCall, callOptions), request, responseObserver);
+          channel.newCall(METHOD_STREAMING_OUTPUT_CALL, callOptions), request, responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver) {
       return asyncClientStreamingCall(
-          channel.newCall(config.streamingInputCall, callOptions), responseObserver);
+          channel.newCall(METHOD_STREAMING_INPUT_CALL, callOptions), responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullDuplexCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
       return asyncDuplexStreamingCall(
-          channel.newCall(config.fullDuplexCall, callOptions), responseObserver);
+          channel.newCall(METHOD_FULL_DUPLEX_CALL, callOptions), responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfDuplexCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
       return asyncDuplexStreamingCall(
-          channel.newCall(config.halfDuplexCall, callOptions), responseObserver);
+          channel.newCall(METHOD_HALF_DUPLEX_CALL, callOptions), responseObserver);
     }
   }
 
-  public static class TestServiceBlockingStub extends
-      io.grpc.stub.AbstractStub<TestServiceBlockingStub, TestServiceServiceDescriptor>
+  public static class TestServiceBlockingStub extends io.grpc.stub.AbstractStub<TestServiceBlockingStub>
       implements TestServiceBlockingClient {
-    private TestServiceBlockingStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config) {
-      super(channel, config);
+    private TestServiceBlockingStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private TestServiceBlockingStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected TestServiceBlockingStub build(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new TestServiceBlockingStub(channel, config, callOptions);
+      return new TestServiceBlockingStub(channel, callOptions);
     }
 
     @java.lang.Override
     public io.grpc.testing.integration.Test.SimpleResponse unaryCall(io.grpc.testing.integration.Test.SimpleRequest request) {
       return blockingUnaryCall(
-          channel.newCall(config.unaryCall, callOptions), request);
+          channel.newCall(METHOD_UNARY_CALL, callOptions), request);
     }
 
     @java.lang.Override
     public java.util.Iterator<io.grpc.testing.integration.Test.StreamingOutputCallResponse> streamingOutputCall(
         io.grpc.testing.integration.Test.StreamingOutputCallRequest request) {
       return blockingServerStreamingCall(
-          channel.newCall(config.streamingOutputCall, callOptions), request);
+          channel.newCall(METHOD_STREAMING_OUTPUT_CALL, callOptions), request);
     }
   }
 
-  public static class TestServiceFutureStub extends
-      io.grpc.stub.AbstractStub<TestServiceFutureStub, TestServiceServiceDescriptor>
+  public static class TestServiceFutureStub extends io.grpc.stub.AbstractStub<TestServiceFutureStub>
       implements TestServiceFutureClient {
-    private TestServiceFutureStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config) {
-      super(channel, config);
+    private TestServiceFutureStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private TestServiceFutureStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected TestServiceFutureStub build(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new TestServiceFutureStub(channel, config, callOptions);
+      return new TestServiceFutureStub(channel, callOptions);
     }
 
     @java.lang.Override
     public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.integration.Test.SimpleResponse> unaryCall(
         io.grpc.testing.integration.Test.SimpleRequest request) {
       return futureUnaryCall(
-          channel.newCall(config.unaryCall, callOptions), request);
+          channel.newCall(METHOD_UNARY_CALL, callOptions), request);
     }
   }
 
diff --git a/examples/src/generated/main/grpc/io/grpc/examples/helloworld/GreeterGrpc.java b/examples/src/generated/main/grpc/io/grpc/examples/helloworld/GreeterGrpc.java
index 180c1ae..79b3aad 100644
--- a/examples/src/generated/main/grpc/io/grpc/examples/helloworld/GreeterGrpc.java
+++ b/examples/src/generated/main/grpc/io/grpc/examples/helloworld/GreeterGrpc.java
@@ -25,52 +25,17 @@
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.examples.helloworld.HelloResponse.parser()));
 
   public static GreeterStub newStub(io.grpc.Channel channel) {
-    return new GreeterStub(channel, CONFIG);
+    return new GreeterStub(channel);
   }
 
   public static GreeterBlockingStub newBlockingStub(
       io.grpc.Channel channel) {
-    return new GreeterBlockingStub(channel, CONFIG);
+    return new GreeterBlockingStub(channel);
   }
 
   public static GreeterFutureStub newFutureStub(
       io.grpc.Channel channel) {
-    return new GreeterFutureStub(channel, CONFIG);
-  }
-
-  // The default service descriptor
-  private static final GreeterServiceDescriptor CONFIG =
-      new GreeterServiceDescriptor();
-
-  @javax.annotation.concurrent.Immutable
-  public static class GreeterServiceDescriptor extends
-      io.grpc.stub.AbstractServiceDescriptor<GreeterServiceDescriptor> {
-    public final io.grpc.MethodDescriptor<io.grpc.examples.helloworld.HelloRequest,
-        io.grpc.examples.helloworld.HelloResponse> sayHello;
-
-    private GreeterServiceDescriptor() {
-      sayHello = METHOD_SAY_HELLO;
-    }
-
-    @SuppressWarnings("unchecked")
-    private GreeterServiceDescriptor(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      sayHello = (io.grpc.MethodDescriptor<io.grpc.examples.helloworld.HelloRequest,
-          io.grpc.examples.helloworld.HelloResponse>) methodMap.get(
-          CONFIG.sayHello.getFullMethodName());
-    }
-
-    @java.lang.Override
-    protected GreeterServiceDescriptor build(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      return new GreeterServiceDescriptor(methodMap);
-    }
-
-    @java.lang.Override
-    public java.util.Collection<io.grpc.MethodDescriptor<?, ?>> methods() {
-      return com.google.common.collect.ImmutableList.<io.grpc.MethodDescriptor<?, ?>>of(
-          sayHello);
-    }
+    return new GreeterFutureStub(channel);
   }
 
   public static interface Greeter {
@@ -90,89 +55,77 @@
         io.grpc.examples.helloworld.HelloRequest request);
   }
 
-  public static class GreeterStub extends
-      io.grpc.stub.AbstractStub<GreeterStub, GreeterServiceDescriptor>
+  public static class GreeterStub extends io.grpc.stub.AbstractStub<GreeterStub>
       implements Greeter {
-    private GreeterStub(io.grpc.Channel channel,
-        GreeterServiceDescriptor config) {
-      super(channel, config);
+    private GreeterStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private GreeterStub(io.grpc.Channel channel,
-        GreeterServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected GreeterStub build(io.grpc.Channel channel,
-        GreeterServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new GreeterStub(channel, config, callOptions);
+      return new GreeterStub(channel, callOptions);
     }
 
     @java.lang.Override
     public void sayHello(io.grpc.examples.helloworld.HelloRequest request,
         io.grpc.stub.StreamObserver<io.grpc.examples.helloworld.HelloResponse> responseObserver) {
       asyncUnaryCall(
-          channel.newCall(config.sayHello, callOptions), request, responseObserver);
+          channel.newCall(METHOD_SAY_HELLO, callOptions), request, responseObserver);
     }
   }
 
-  public static class GreeterBlockingStub extends
-      io.grpc.stub.AbstractStub<GreeterBlockingStub, GreeterServiceDescriptor>
+  public static class GreeterBlockingStub extends io.grpc.stub.AbstractStub<GreeterBlockingStub>
       implements GreeterBlockingClient {
-    private GreeterBlockingStub(io.grpc.Channel channel,
-        GreeterServiceDescriptor config) {
-      super(channel, config);
+    private GreeterBlockingStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private GreeterBlockingStub(io.grpc.Channel channel,
-        GreeterServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected GreeterBlockingStub build(io.grpc.Channel channel,
-        GreeterServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new GreeterBlockingStub(channel, config, callOptions);
+      return new GreeterBlockingStub(channel, callOptions);
     }
 
     @java.lang.Override
     public io.grpc.examples.helloworld.HelloResponse sayHello(io.grpc.examples.helloworld.HelloRequest request) {
       return blockingUnaryCall(
-          channel.newCall(config.sayHello, callOptions), request);
+          channel.newCall(METHOD_SAY_HELLO, callOptions), request);
     }
   }
 
-  public static class GreeterFutureStub extends
-      io.grpc.stub.AbstractStub<GreeterFutureStub, GreeterServiceDescriptor>
+  public static class GreeterFutureStub extends io.grpc.stub.AbstractStub<GreeterFutureStub>
       implements GreeterFutureClient {
-    private GreeterFutureStub(io.grpc.Channel channel,
-        GreeterServiceDescriptor config) {
-      super(channel, config);
+    private GreeterFutureStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private GreeterFutureStub(io.grpc.Channel channel,
-        GreeterServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected GreeterFutureStub build(io.grpc.Channel channel,
-        GreeterServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new GreeterFutureStub(channel, config, callOptions);
+      return new GreeterFutureStub(channel, callOptions);
     }
 
     @java.lang.Override
     public com.google.common.util.concurrent.ListenableFuture<io.grpc.examples.helloworld.HelloResponse> sayHello(
         io.grpc.examples.helloworld.HelloRequest request) {
       return futureUnaryCall(
-          channel.newCall(config.sayHello, callOptions), request);
+          channel.newCall(METHOD_SAY_HELLO, callOptions), request);
     }
   }
 
diff --git a/examples/src/generated/main/grpc/io/grpc/examples/routeguide/RouteGuideGrpc.java b/examples/src/generated/main/grpc/io/grpc/examples/routeguide/RouteGuideGrpc.java
index 0a9416d..9b7e967 100644
--- a/examples/src/generated/main/grpc/io/grpc/examples/routeguide/RouteGuideGrpc.java
+++ b/examples/src/generated/main/grpc/io/grpc/examples/routeguide/RouteGuideGrpc.java
@@ -23,7 +23,6 @@
           "routeguide.RouteGuide", "GetFeature",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.examples.routeguide.Point.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.examples.routeguide.Feature.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.examples.routeguide.Rectangle,
       io.grpc.examples.routeguide.Feature> METHOD_LIST_FEATURES =
       io.grpc.MethodDescriptor.create(
@@ -31,7 +30,6 @@
           "routeguide.RouteGuide", "ListFeatures",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.examples.routeguide.Rectangle.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.examples.routeguide.Feature.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.examples.routeguide.Point,
       io.grpc.examples.routeguide.RouteSummary> METHOD_RECORD_ROUTE =
       io.grpc.MethodDescriptor.create(
@@ -39,7 +37,6 @@
           "routeguide.RouteGuide", "RecordRoute",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.examples.routeguide.Point.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.examples.routeguide.RouteSummary.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.examples.routeguide.RouteNote,
       io.grpc.examples.routeguide.RouteNote> METHOD_ROUTE_CHAT =
       io.grpc.MethodDescriptor.create(
@@ -49,73 +46,17 @@
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.examples.routeguide.RouteNote.parser()));
 
   public static RouteGuideStub newStub(io.grpc.Channel channel) {
-    return new RouteGuideStub(channel, CONFIG);
+    return new RouteGuideStub(channel);
   }
 
   public static RouteGuideBlockingStub newBlockingStub(
       io.grpc.Channel channel) {
-    return new RouteGuideBlockingStub(channel, CONFIG);
+    return new RouteGuideBlockingStub(channel);
   }
 
   public static RouteGuideFutureStub newFutureStub(
       io.grpc.Channel channel) {
-    return new RouteGuideFutureStub(channel, CONFIG);
-  }
-
-  // The default service descriptor
-  private static final RouteGuideServiceDescriptor CONFIG =
-      new RouteGuideServiceDescriptor();
-
-  @javax.annotation.concurrent.Immutable
-  public static class RouteGuideServiceDescriptor extends
-      io.grpc.stub.AbstractServiceDescriptor<RouteGuideServiceDescriptor> {
-    public final io.grpc.MethodDescriptor<io.grpc.examples.routeguide.Point,
-        io.grpc.examples.routeguide.Feature> getFeature;
-    public final io.grpc.MethodDescriptor<io.grpc.examples.routeguide.Rectangle,
-        io.grpc.examples.routeguide.Feature> listFeatures;
-    public final io.grpc.MethodDescriptor<io.grpc.examples.routeguide.Point,
-        io.grpc.examples.routeguide.RouteSummary> recordRoute;
-    public final io.grpc.MethodDescriptor<io.grpc.examples.routeguide.RouteNote,
-        io.grpc.examples.routeguide.RouteNote> routeChat;
-
-    private RouteGuideServiceDescriptor() {
-      getFeature = METHOD_GET_FEATURE;
-      listFeatures = METHOD_LIST_FEATURES;
-      recordRoute = METHOD_RECORD_ROUTE;
-      routeChat = METHOD_ROUTE_CHAT;
-    }
-
-    @SuppressWarnings("unchecked")
-    private RouteGuideServiceDescriptor(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      getFeature = (io.grpc.MethodDescriptor<io.grpc.examples.routeguide.Point,
-          io.grpc.examples.routeguide.Feature>) methodMap.get(
-          CONFIG.getFeature.getFullMethodName());
-      listFeatures = (io.grpc.MethodDescriptor<io.grpc.examples.routeguide.Rectangle,
-          io.grpc.examples.routeguide.Feature>) methodMap.get(
-          CONFIG.listFeatures.getFullMethodName());
-      recordRoute = (io.grpc.MethodDescriptor<io.grpc.examples.routeguide.Point,
-          io.grpc.examples.routeguide.RouteSummary>) methodMap.get(
-          CONFIG.recordRoute.getFullMethodName());
-      routeChat = (io.grpc.MethodDescriptor<io.grpc.examples.routeguide.RouteNote,
-          io.grpc.examples.routeguide.RouteNote>) methodMap.get(
-          CONFIG.routeChat.getFullMethodName());
-    }
-
-    @java.lang.Override
-    protected RouteGuideServiceDescriptor build(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      return new RouteGuideServiceDescriptor(methodMap);
-    }
-
-    @java.lang.Override
-    public java.util.Collection<io.grpc.MethodDescriptor<?, ?>> methods() {
-      return com.google.common.collect.ImmutableList.<io.grpc.MethodDescriptor<?, ?>>of(
-          getFeature,
-          listFeatures,
-          recordRoute,
-          routeChat);
-    }
+    return new RouteGuideFutureStub(channel);
   }
 
   public static interface RouteGuide {
@@ -147,117 +88,105 @@
         io.grpc.examples.routeguide.Point request);
   }
 
-  public static class RouteGuideStub extends
-      io.grpc.stub.AbstractStub<RouteGuideStub, RouteGuideServiceDescriptor>
+  public static class RouteGuideStub extends io.grpc.stub.AbstractStub<RouteGuideStub>
       implements RouteGuide {
-    private RouteGuideStub(io.grpc.Channel channel,
-        RouteGuideServiceDescriptor config) {
-      super(channel, config);
+    private RouteGuideStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private RouteGuideStub(io.grpc.Channel channel,
-        RouteGuideServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected RouteGuideStub build(io.grpc.Channel channel,
-        RouteGuideServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new RouteGuideStub(channel, config, callOptions);
+      return new RouteGuideStub(channel, callOptions);
     }
 
     @java.lang.Override
     public void getFeature(io.grpc.examples.routeguide.Point request,
         io.grpc.stub.StreamObserver<io.grpc.examples.routeguide.Feature> responseObserver) {
       asyncUnaryCall(
-          channel.newCall(config.getFeature, callOptions), request, responseObserver);
+          channel.newCall(METHOD_GET_FEATURE, callOptions), request, responseObserver);
     }
 
     @java.lang.Override
     public void listFeatures(io.grpc.examples.routeguide.Rectangle request,
         io.grpc.stub.StreamObserver<io.grpc.examples.routeguide.Feature> responseObserver) {
       asyncServerStreamingCall(
-          channel.newCall(config.listFeatures, callOptions), request, responseObserver);
+          channel.newCall(METHOD_LIST_FEATURES, callOptions), request, responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.examples.routeguide.Point> recordRoute(
         io.grpc.stub.StreamObserver<io.grpc.examples.routeguide.RouteSummary> responseObserver) {
       return asyncClientStreamingCall(
-          channel.newCall(config.recordRoute, callOptions), responseObserver);
+          channel.newCall(METHOD_RECORD_ROUTE, callOptions), responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.examples.routeguide.RouteNote> routeChat(
         io.grpc.stub.StreamObserver<io.grpc.examples.routeguide.RouteNote> responseObserver) {
       return asyncDuplexStreamingCall(
-          channel.newCall(config.routeChat, callOptions), responseObserver);
+          channel.newCall(METHOD_ROUTE_CHAT, callOptions), responseObserver);
     }
   }
 
-  public static class RouteGuideBlockingStub extends
-      io.grpc.stub.AbstractStub<RouteGuideBlockingStub, RouteGuideServiceDescriptor>
+  public static class RouteGuideBlockingStub extends io.grpc.stub.AbstractStub<RouteGuideBlockingStub>
       implements RouteGuideBlockingClient {
-    private RouteGuideBlockingStub(io.grpc.Channel channel,
-        RouteGuideServiceDescriptor config) {
-      super(channel, config);
+    private RouteGuideBlockingStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private RouteGuideBlockingStub(io.grpc.Channel channel,
-        RouteGuideServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected RouteGuideBlockingStub build(io.grpc.Channel channel,
-        RouteGuideServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new RouteGuideBlockingStub(channel, config, callOptions);
+      return new RouteGuideBlockingStub(channel, callOptions);
     }
 
     @java.lang.Override
     public io.grpc.examples.routeguide.Feature getFeature(io.grpc.examples.routeguide.Point request) {
       return blockingUnaryCall(
-          channel.newCall(config.getFeature, callOptions), request);
+          channel.newCall(METHOD_GET_FEATURE, callOptions), request);
     }
 
     @java.lang.Override
     public java.util.Iterator<io.grpc.examples.routeguide.Feature> listFeatures(
         io.grpc.examples.routeguide.Rectangle request) {
       return blockingServerStreamingCall(
-          channel.newCall(config.listFeatures, callOptions), request);
+          channel.newCall(METHOD_LIST_FEATURES, callOptions), request);
     }
   }
 
-  public static class RouteGuideFutureStub extends
-      io.grpc.stub.AbstractStub<RouteGuideFutureStub, RouteGuideServiceDescriptor>
+  public static class RouteGuideFutureStub extends io.grpc.stub.AbstractStub<RouteGuideFutureStub>
       implements RouteGuideFutureClient {
-    private RouteGuideFutureStub(io.grpc.Channel channel,
-        RouteGuideServiceDescriptor config) {
-      super(channel, config);
+    private RouteGuideFutureStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private RouteGuideFutureStub(io.grpc.Channel channel,
-        RouteGuideServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected RouteGuideFutureStub build(io.grpc.Channel channel,
-        RouteGuideServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new RouteGuideFutureStub(channel, config, callOptions);
+      return new RouteGuideFutureStub(channel, callOptions);
     }
 
     @java.lang.Override
     public com.google.common.util.concurrent.ListenableFuture<io.grpc.examples.routeguide.Feature> getFeature(
         io.grpc.examples.routeguide.Point request) {
       return futureUnaryCall(
-          channel.newCall(config.getFeature, callOptions), request);
+          channel.newCall(METHOD_GET_FEATURE, callOptions), request);
     }
   }
 
diff --git a/interop-testing/src/generated/main/grpc/io/grpc/testing/integration/TestServiceGrpc.java b/interop-testing/src/generated/main/grpc/io/grpc/testing/integration/TestServiceGrpc.java
index ca27aaa..1841c95 100644
--- a/interop-testing/src/generated/main/grpc/io/grpc/testing/integration/TestServiceGrpc.java
+++ b/interop-testing/src/generated/main/grpc/io/grpc/testing/integration/TestServiceGrpc.java
@@ -23,7 +23,6 @@
           "grpc.testing.TestService", "EmptyCall",
           io.grpc.protobuf.ProtoUtils.marshaller(com.google.protobuf.EmptyProtos.Empty.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(com.google.protobuf.EmptyProtos.Empty.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.SimpleRequest,
       io.grpc.testing.integration.Messages.SimpleResponse> METHOD_UNARY_CALL =
       io.grpc.MethodDescriptor.create(
@@ -31,7 +30,6 @@
           "grpc.testing.TestService", "UnaryCall",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Messages.SimpleRequest.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Messages.SimpleResponse.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.StreamingOutputCallRequest,
       io.grpc.testing.integration.Messages.StreamingOutputCallResponse> METHOD_STREAMING_OUTPUT_CALL =
       io.grpc.MethodDescriptor.create(
@@ -39,7 +37,6 @@
           "grpc.testing.TestService", "StreamingOutputCall",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Messages.StreamingOutputCallRequest.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Messages.StreamingOutputCallResponse.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.StreamingInputCallRequest,
       io.grpc.testing.integration.Messages.StreamingInputCallResponse> METHOD_STREAMING_INPUT_CALL =
       io.grpc.MethodDescriptor.create(
@@ -47,7 +44,6 @@
           "grpc.testing.TestService", "StreamingInputCall",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Messages.StreamingInputCallRequest.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Messages.StreamingInputCallResponse.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.StreamingOutputCallRequest,
       io.grpc.testing.integration.Messages.StreamingOutputCallResponse> METHOD_FULL_DUPLEX_CALL =
       io.grpc.MethodDescriptor.create(
@@ -55,7 +51,6 @@
           "grpc.testing.TestService", "FullDuplexCall",
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Messages.StreamingOutputCallRequest.parser()),
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Messages.StreamingOutputCallResponse.parser()));
-  // Static method descriptors that strictly reflect the proto.
   public static final io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.StreamingOutputCallRequest,
       io.grpc.testing.integration.Messages.StreamingOutputCallResponse> METHOD_HALF_DUPLEX_CALL =
       io.grpc.MethodDescriptor.create(
@@ -65,87 +60,17 @@
           io.grpc.protobuf.ProtoUtils.marshaller(io.grpc.testing.integration.Messages.StreamingOutputCallResponse.parser()));
 
   public static TestServiceStub newStub(io.grpc.Channel channel) {
-    return new TestServiceStub(channel, CONFIG);
+    return new TestServiceStub(channel);
   }
 
   public static TestServiceBlockingStub newBlockingStub(
       io.grpc.Channel channel) {
-    return new TestServiceBlockingStub(channel, CONFIG);
+    return new TestServiceBlockingStub(channel);
   }
 
   public static TestServiceFutureStub newFutureStub(
       io.grpc.Channel channel) {
-    return new TestServiceFutureStub(channel, CONFIG);
-  }
-
-  // The default service descriptor
-  private static final TestServiceServiceDescriptor CONFIG =
-      new TestServiceServiceDescriptor();
-
-  @javax.annotation.concurrent.Immutable
-  public static class TestServiceServiceDescriptor extends
-      io.grpc.stub.AbstractServiceDescriptor<TestServiceServiceDescriptor> {
-    public final io.grpc.MethodDescriptor<com.google.protobuf.EmptyProtos.Empty,
-        com.google.protobuf.EmptyProtos.Empty> emptyCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.SimpleRequest,
-        io.grpc.testing.integration.Messages.SimpleResponse> unaryCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.StreamingOutputCallRequest,
-        io.grpc.testing.integration.Messages.StreamingOutputCallResponse> streamingOutputCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.StreamingInputCallRequest,
-        io.grpc.testing.integration.Messages.StreamingInputCallResponse> streamingInputCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.StreamingOutputCallRequest,
-        io.grpc.testing.integration.Messages.StreamingOutputCallResponse> fullDuplexCall;
-    public final io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.StreamingOutputCallRequest,
-        io.grpc.testing.integration.Messages.StreamingOutputCallResponse> halfDuplexCall;
-
-    private TestServiceServiceDescriptor() {
-      emptyCall = METHOD_EMPTY_CALL;
-      unaryCall = METHOD_UNARY_CALL;
-      streamingOutputCall = METHOD_STREAMING_OUTPUT_CALL;
-      streamingInputCall = METHOD_STREAMING_INPUT_CALL;
-      fullDuplexCall = METHOD_FULL_DUPLEX_CALL;
-      halfDuplexCall = METHOD_HALF_DUPLEX_CALL;
-    }
-
-    @SuppressWarnings("unchecked")
-    private TestServiceServiceDescriptor(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      emptyCall = (io.grpc.MethodDescriptor<com.google.protobuf.EmptyProtos.Empty,
-          com.google.protobuf.EmptyProtos.Empty>) methodMap.get(
-          CONFIG.emptyCall.getFullMethodName());
-      unaryCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.SimpleRequest,
-          io.grpc.testing.integration.Messages.SimpleResponse>) methodMap.get(
-          CONFIG.unaryCall.getFullMethodName());
-      streamingOutputCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.StreamingOutputCallRequest,
-          io.grpc.testing.integration.Messages.StreamingOutputCallResponse>) methodMap.get(
-          CONFIG.streamingOutputCall.getFullMethodName());
-      streamingInputCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.StreamingInputCallRequest,
-          io.grpc.testing.integration.Messages.StreamingInputCallResponse>) methodMap.get(
-          CONFIG.streamingInputCall.getFullMethodName());
-      fullDuplexCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.StreamingOutputCallRequest,
-          io.grpc.testing.integration.Messages.StreamingOutputCallResponse>) methodMap.get(
-          CONFIG.fullDuplexCall.getFullMethodName());
-      halfDuplexCall = (io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.StreamingOutputCallRequest,
-          io.grpc.testing.integration.Messages.StreamingOutputCallResponse>) methodMap.get(
-          CONFIG.halfDuplexCall.getFullMethodName());
-    }
-
-    @java.lang.Override
-    protected TestServiceServiceDescriptor build(
-        java.util.Map<java.lang.String, io.grpc.MethodDescriptor<?, ?>> methodMap) {
-      return new TestServiceServiceDescriptor(methodMap);
-    }
-
-    @java.lang.Override
-    public java.util.Collection<io.grpc.MethodDescriptor<?, ?>> methods() {
-      return com.google.common.collect.ImmutableList.<io.grpc.MethodDescriptor<?, ?>>of(
-          emptyCall,
-          unaryCall,
-          streamingOutputCall,
-          streamingInputCall,
-          fullDuplexCall,
-          halfDuplexCall);
-    }
+    return new TestServiceFutureStub(channel);
   }
 
   public static interface TestService {
@@ -188,144 +113,132 @@
         io.grpc.testing.integration.Messages.SimpleRequest request);
   }
 
-  public static class TestServiceStub extends
-      io.grpc.stub.AbstractStub<TestServiceStub, TestServiceServiceDescriptor>
+  public static class TestServiceStub extends io.grpc.stub.AbstractStub<TestServiceStub>
       implements TestService {
-    private TestServiceStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config) {
-      super(channel, config);
+    private TestServiceStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private TestServiceStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected TestServiceStub build(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new TestServiceStub(channel, config, callOptions);
+      return new TestServiceStub(channel, callOptions);
     }
 
     @java.lang.Override
     public void emptyCall(com.google.protobuf.EmptyProtos.Empty request,
         io.grpc.stub.StreamObserver<com.google.protobuf.EmptyProtos.Empty> responseObserver) {
       asyncUnaryCall(
-          channel.newCall(config.emptyCall, callOptions), request, responseObserver);
+          channel.newCall(METHOD_EMPTY_CALL, callOptions), request, responseObserver);
     }
 
     @java.lang.Override
     public void unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Messages.SimpleResponse> responseObserver) {
       asyncUnaryCall(
-          channel.newCall(config.unaryCall, callOptions), request, responseObserver);
+          channel.newCall(METHOD_UNARY_CALL, callOptions), request, responseObserver);
     }
 
     @java.lang.Override
     public void streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Messages.StreamingOutputCallResponse> responseObserver) {
       asyncServerStreamingCall(
-          channel.newCall(config.streamingOutputCall, callOptions), request, responseObserver);
+          channel.newCall(METHOD_STREAMING_OUTPUT_CALL, callOptions), request, responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Messages.StreamingInputCallRequest> streamingInputCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Messages.StreamingInputCallResponse> responseObserver) {
       return asyncClientStreamingCall(
-          channel.newCall(config.streamingInputCall, callOptions), responseObserver);
+          channel.newCall(METHOD_STREAMING_INPUT_CALL, callOptions), responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Messages.StreamingOutputCallRequest> fullDuplexCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Messages.StreamingOutputCallResponse> responseObserver) {
       return asyncDuplexStreamingCall(
-          channel.newCall(config.fullDuplexCall, callOptions), responseObserver);
+          channel.newCall(METHOD_FULL_DUPLEX_CALL, callOptions), responseObserver);
     }
 
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Messages.StreamingOutputCallRequest> halfDuplexCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Messages.StreamingOutputCallResponse> responseObserver) {
       return asyncDuplexStreamingCall(
-          channel.newCall(config.halfDuplexCall, callOptions), responseObserver);
+          channel.newCall(METHOD_HALF_DUPLEX_CALL, callOptions), responseObserver);
     }
   }
 
-  public static class TestServiceBlockingStub extends
-      io.grpc.stub.AbstractStub<TestServiceBlockingStub, TestServiceServiceDescriptor>
+  public static class TestServiceBlockingStub extends io.grpc.stub.AbstractStub<TestServiceBlockingStub>
       implements TestServiceBlockingClient {
-    private TestServiceBlockingStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config) {
-      super(channel, config);
+    private TestServiceBlockingStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private TestServiceBlockingStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected TestServiceBlockingStub build(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new TestServiceBlockingStub(channel, config, callOptions);
+      return new TestServiceBlockingStub(channel, callOptions);
     }
 
     @java.lang.Override
     public com.google.protobuf.EmptyProtos.Empty emptyCall(com.google.protobuf.EmptyProtos.Empty request) {
       return blockingUnaryCall(
-          channel.newCall(config.emptyCall, callOptions), request);
+          channel.newCall(METHOD_EMPTY_CALL, callOptions), request);
     }
 
     @java.lang.Override
     public io.grpc.testing.integration.Messages.SimpleResponse unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) {
       return blockingUnaryCall(
-          channel.newCall(config.unaryCall, callOptions), request);
+          channel.newCall(METHOD_UNARY_CALL, callOptions), request);
     }
 
     @java.lang.Override
     public java.util.Iterator<io.grpc.testing.integration.Messages.StreamingOutputCallResponse> streamingOutputCall(
         io.grpc.testing.integration.Messages.StreamingOutputCallRequest request) {
       return blockingServerStreamingCall(
-          channel.newCall(config.streamingOutputCall, callOptions), request);
+          channel.newCall(METHOD_STREAMING_OUTPUT_CALL, callOptions), request);
     }
   }
 
-  public static class TestServiceFutureStub extends
-      io.grpc.stub.AbstractStub<TestServiceFutureStub, TestServiceServiceDescriptor>
+  public static class TestServiceFutureStub extends io.grpc.stub.AbstractStub<TestServiceFutureStub>
       implements TestServiceFutureClient {
-    private TestServiceFutureStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config) {
-      super(channel, config);
+    private TestServiceFutureStub(io.grpc.Channel channel) {
+      super(channel);
     }
 
     private TestServiceFutureStub(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      super(channel, config, callOptions);
+      super(channel, callOptions);
     }
 
     @java.lang.Override
     protected TestServiceFutureStub build(io.grpc.Channel channel,
-        TestServiceServiceDescriptor config,
         io.grpc.CallOptions callOptions) {
-      return new TestServiceFutureStub(channel, config, callOptions);
+      return new TestServiceFutureStub(channel, callOptions);
     }
 
     @java.lang.Override
     public com.google.common.util.concurrent.ListenableFuture<com.google.protobuf.EmptyProtos.Empty> emptyCall(
         com.google.protobuf.EmptyProtos.Empty request) {
       return futureUnaryCall(
-          channel.newCall(config.emptyCall, callOptions), request);
+          channel.newCall(METHOD_EMPTY_CALL, callOptions), request);
     }
 
     @java.lang.Override
     public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.integration.Messages.SimpleResponse> unaryCall(
         io.grpc.testing.integration.Messages.SimpleRequest request) {
       return futureUnaryCall(
-          channel.newCall(config.unaryCall, callOptions), request);
+          channel.newCall(METHOD_UNARY_CALL, callOptions), request);
     }
   }
 
diff --git a/stub/src/main/java/io/grpc/stub/AbstractServiceDescriptor.java b/stub/src/main/java/io/grpc/stub/AbstractServiceDescriptor.java
deleted file mode 100644
index 99fe34f..0000000
--- a/stub/src/main/java/io/grpc/stub/AbstractServiceDescriptor.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2014, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *    * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- *    * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package io.grpc.stub;
-
-import io.grpc.MethodDescriptor;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * Base class for all stub configurations.
- *
- * @param <T> The concrete class type.
- */
-public abstract class AbstractServiceDescriptor<T extends AbstractServiceDescriptor<?>> {
-
-  /**
-   * Returns an immutable collection of methods defined in the stub configuration.
-   */
-  public abstract Collection<MethodDescriptor<?, ?>> methods();
-
-  /**
-   * Returns a new stub configuration for the provided method configurations.
-   *
-   * @param methodMap a map from fully qualified method names to {@code MethodDescriptor}s
-   */
-  protected abstract T build(Map<String, MethodDescriptor<?, ?>> methodMap);
-}
diff --git a/stub/src/main/java/io/grpc/stub/AbstractStub.java b/stub/src/main/java/io/grpc/stub/AbstractStub.java
index d9a6ac3..5d6f0d5 100644
--- a/stub/src/main/java/io/grpc/stub/AbstractStub.java
+++ b/stub/src/main/java/io/grpc/stub/AbstractStub.java
@@ -49,41 +49,31 @@
  * reconfiguration, e.g., attaching interceptors to the stub.
  *
  * @param <S> the concrete type of this stub.
- * @param <C> the service descriptor type
  */
-public abstract class AbstractStub<S extends AbstractStub<?, ?>,
-    C extends AbstractServiceDescriptor<C>> {
+public abstract class AbstractStub<S extends AbstractStub<?>> {
   protected final Channel channel;
-  protected final C config;
   protected final CallOptions callOptions;
 
   /**
    * Constructor for use by subclasses, with the default {@code CallOptions}.
    *
    * @param channel the channel that this stub will use to do communications
-   * @param config defines the RPC methods of the stub
    */
-  protected AbstractStub(Channel channel, C config) {
-    this(channel, config, CallOptions.DEFAULT);
+  protected AbstractStub(Channel channel) {
+    this(channel, CallOptions.DEFAULT);
   }
 
   /**
    * Constructor for use by subclasses, with the default {@code CallOptions}.
    *
    * @param channel the channel that this stub will use to do communications
-   * @param config defines the RPC methods of the stub
    * @param callOptions the runtime call options to be applied to every call on this stub
    */
-  protected AbstractStub(Channel channel, C config, CallOptions callOptions) {
+  protected AbstractStub(Channel channel, CallOptions callOptions) {
     this.channel = channel;
-    this.config = config;
     this.callOptions = callOptions;
   }
 
-  protected C getServiceDescriptor() {
-    return config;
-  }
-
   /**
    * Creates a builder for reconfiguring the stub.
    */
@@ -109,10 +99,9 @@
    * Returns a new stub with the given channel for the provided method configurations.
    *
    * @param channel the channel that this stub will use to do communications
-   * @param config defines the RPC methods of the stub
    * @param callOptions the runtime call options to be applied to every call on this stub
    */
-  protected abstract S build(Channel channel, C config, CallOptions callOptions);
+  protected abstract S build(Channel channel, CallOptions callOptions);
 
   /**
    * Utility class for (re) configuring the operations in a stub.
@@ -170,8 +159,8 @@
      * Create a new stub with the configurations made on this builder.
      */
     public S build() {
-      return AbstractStub.this.build(ClientInterceptors.intercept(stubChannel, interceptors),
-          config, callOptions);
+      return AbstractStub.this.build(
+          ClientInterceptors.intercept(stubChannel, interceptors), callOptions);
     }
   }
 }