core: make ServiceDescriptor use the Builder pattern

diff --git a/benchmarks/src/generated/main/grpc/io/grpc/benchmarks/proto/BenchmarkServiceGrpc.java b/benchmarks/src/generated/main/grpc/io/grpc/benchmarks/proto/BenchmarkServiceGrpc.java
index 1da5667..f0834ed 100644
--- a/benchmarks/src/generated/main/grpc/io/grpc/benchmarks/proto/BenchmarkServiceGrpc.java
+++ b/benchmarks/src/generated/main/grpc/io/grpc/benchmarks/proto/BenchmarkServiceGrpc.java
@@ -277,11 +277,11 @@
       synchronized (BenchmarkServiceGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new BenchmarkServiceDescriptorSupplier(),
-              METHOD_UNARY_CALL,
-              METHOD_STREAMING_CALL);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new BenchmarkServiceDescriptorSupplier())
+              .addMethod(METHOD_UNARY_CALL)
+              .addMethod(METHOD_STREAMING_CALL)
+              .build();
         }
       }
     }
diff --git a/benchmarks/src/generated/main/grpc/io/grpc/benchmarks/proto/WorkerServiceGrpc.java b/benchmarks/src/generated/main/grpc/io/grpc/benchmarks/proto/WorkerServiceGrpc.java
index 5e946bb..3a9a58c 100644
--- a/benchmarks/src/generated/main/grpc/io/grpc/benchmarks/proto/WorkerServiceGrpc.java
+++ b/benchmarks/src/generated/main/grpc/io/grpc/benchmarks/proto/WorkerServiceGrpc.java
@@ -395,13 +395,13 @@
       synchronized (WorkerServiceGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new WorkerServiceDescriptorSupplier(),
-              METHOD_RUN_SERVER,
-              METHOD_RUN_CLIENT,
-              METHOD_CORE_COUNT,
-              METHOD_QUIT_WORKER);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new WorkerServiceDescriptorSupplier())
+              .addMethod(METHOD_RUN_SERVER)
+              .addMethod(METHOD_RUN_CLIENT)
+              .addMethod(METHOD_CORE_COUNT)
+              .addMethod(METHOD_QUIT_WORKER)
+              .build();
         }
       }
     }
diff --git a/compiler/src/java_plugin/cpp/java_generator.cpp b/compiler/src/java_plugin/cpp/java_generator.cpp
index 8a57a0f..09b1571 100644
--- a/compiler/src/java_plugin/cpp/java_generator.cpp
+++ b/compiler/src/java_plugin/cpp/java_generator.cpp
@@ -930,21 +930,20 @@
 
   p->Print(
       *vars,
-      "serviceDescriptor = result = new $ServiceDescriptor$(\n");
+      "serviceDescriptor = result = $ServiceDescriptor$.newBuilder(SERVICE_NAME)");
   p->Indent();
   p->Indent();
-  p->Print("SERVICE_NAME");
   if (flavor == ProtoFlavor::NORMAL) {
     p->Print(
         *vars,
-        ",\nnew $proto_descriptor_supplier$()");
+        "\n.setSchemaDescriptor(new $proto_descriptor_supplier$())");
   }
   for (int i = 0; i < service->method_count(); ++i) {
     const MethodDescriptor* method = service->method(i);
     (*vars)["method_field_name"] = MethodPropertiesFieldName(method);
-    p->Print(*vars, ",\n$method_field_name$");
+    p->Print(*vars, "\n.addMethod($method_field_name$)");
   }
-  p->Print(");\n");
+  p->Print("\n.build();\n");
   p->Outdent();
   p->Outdent();
 
diff --git a/compiler/src/test/golden/TestService.java.txt b/compiler/src/test/golden/TestService.java.txt
index 86bc987..848d298 100644
--- a/compiler/src/test/golden/TestService.java.txt
+++ b/compiler/src/test/golden/TestService.java.txt
@@ -440,14 +440,14 @@
       synchronized (TestServiceGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new TestServiceDescriptorSupplier(),
-              METHOD_UNARY_CALL,
-              METHOD_STREAMING_OUTPUT_CALL,
-              METHOD_STREAMING_INPUT_CALL,
-              METHOD_FULL_BIDI_CALL,
-              METHOD_HALF_BIDI_CALL);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new TestServiceDescriptorSupplier())
+              .addMethod(METHOD_UNARY_CALL)
+              .addMethod(METHOD_STREAMING_OUTPUT_CALL)
+              .addMethod(METHOD_STREAMING_INPUT_CALL)
+              .addMethod(METHOD_FULL_BIDI_CALL)
+              .addMethod(METHOD_HALF_BIDI_CALL)
+              .build();
         }
       }
     }
diff --git a/compiler/src/testLite/golden/TestService.java.txt b/compiler/src/testLite/golden/TestService.java.txt
index 6720b78..860a953 100644
--- a/compiler/src/testLite/golden/TestService.java.txt
+++ b/compiler/src/testLite/golden/TestService.java.txt
@@ -433,13 +433,13 @@
       synchronized (TestServiceGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              METHOD_UNARY_CALL,
-              METHOD_STREAMING_OUTPUT_CALL,
-              METHOD_STREAMING_INPUT_CALL,
-              METHOD_FULL_BIDI_CALL,
-              METHOD_HALF_BIDI_CALL);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .addMethod(METHOD_UNARY_CALL)
+              .addMethod(METHOD_STREAMING_OUTPUT_CALL)
+              .addMethod(METHOD_STREAMING_INPUT_CALL)
+              .addMethod(METHOD_FULL_BIDI_CALL)
+              .addMethod(METHOD_HALF_BIDI_CALL)
+              .build();
         }
       }
     }
diff --git a/compiler/src/testNano/golden/TestService.java.txt b/compiler/src/testNano/golden/TestService.java.txt
index 31701a5..bf74753 100644
--- a/compiler/src/testNano/golden/TestService.java.txt
+++ b/compiler/src/testNano/golden/TestService.java.txt
@@ -511,13 +511,13 @@
       synchronized (TestServiceGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              METHOD_UNARY_CALL,
-              METHOD_STREAMING_OUTPUT_CALL,
-              METHOD_STREAMING_INPUT_CALL,
-              METHOD_FULL_BIDI_CALL,
-              METHOD_HALF_BIDI_CALL);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .addMethod(METHOD_UNARY_CALL)
+              .addMethod(METHOD_STREAMING_OUTPUT_CALL)
+              .addMethod(METHOD_STREAMING_INPUT_CALL)
+              .addMethod(METHOD_FULL_BIDI_CALL)
+              .addMethod(METHOD_HALF_BIDI_CALL)
+              .build();
         }
       }
     }
diff --git a/core/src/main/java/io/grpc/ServiceDescriptor.java b/core/src/main/java/io/grpc/ServiceDescriptor.java
index 634e041..a75bb48 100644
--- a/core/src/main/java/io/grpc/ServiceDescriptor.java
+++ b/core/src/main/java/io/grpc/ServiceDescriptor.java
@@ -32,49 +32,64 @@
 package io.grpc;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
 
-import com.google.common.base.Preconditions;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import javax.annotation.Nullable;
 
 /**
  * Descriptor for a service.
+ *
+ * @since 1.0.0
  */
 public final class ServiceDescriptor {
 
   private final String name;
   private final Collection<MethodDescriptor<?, ?>> methods;
-  private final Object marshallerDescriptor;
+  private final Object schemaDescriptor;
 
+  /**
+   * Constructs a new Service Descriptor.  Users are encouraged to use {@link #newBuilder}
+   * instead.
+   *
+   * @param name The name of the service
+   * @param methods The methods that are part of the service
+   * @since 1.0.0
+   */
   public ServiceDescriptor(String name, MethodDescriptor<?, ?>... methods) {
-    this(name, null, Arrays.asList(methods));
+    this(name, Arrays.asList(methods));
   }
 
+  /**
+   * Constructs a new Service Descriptor.  Users are encouraged to use {@link #newBuilder}
+   * instead.
+   *
+   * @param name The name of the service
+   * @param methods The methods that are part of the service
+   * @since 1.0.0
+   */
   public ServiceDescriptor(String name, Collection<MethodDescriptor<?, ?>> methods) {
-    this(name, null, methods);
+    this(newBuilder(name).addAllMethods(checkNotNull(methods, "methods")));
   }
 
-  public ServiceDescriptor(String name, Object marshallerDescriptor,
-                           MethodDescriptor<?, ?>... methods) {
-    this(name, marshallerDescriptor, Arrays.asList(methods));
+  private ServiceDescriptor(Builder b) {
+    this.name = b.name;
+    validateMethodNames(name, b.methods);
+    this.methods = Collections.unmodifiableList(new ArrayList<MethodDescriptor<?, ?>>(b.methods));
+    this.schemaDescriptor = b.schemaDescriptor;
   }
 
-  /** Creates a new ServiceDescriptor. */
-  public ServiceDescriptor(String name, Object marshallerDescriptor,
-                           Collection<MethodDescriptor<?, ?>> methods) {
-    this.name = Preconditions.checkNotNull(name, "name");
-    Preconditions.checkNotNull(methods, "methods");
-    validateMethodNames(name, methods);
-    this.marshallerDescriptor = marshallerDescriptor;
-    this.methods = Collections.unmodifiableList(new ArrayList<MethodDescriptor<?, ?>>(methods));
-  }
-
-  /** Simple name of the service. It is not an absolute path. */
+  /**
+   * Simple name of the service. It is not an absolute path.
+   *
+   * @since 1.0.0
+   */
   public String getName() {
     return name;
   }
@@ -82,24 +97,33 @@
   /**
    * A collection of {@link MethodDescriptor} instances describing the methods exposed by the
    * service.
+   *
+   * @since 1.0.0
    */
   public Collection<MethodDescriptor<?, ?>> getMethods() {
     return methods;
   }
 
   /**
-   * Returns a marshaller-specific object that provides additional information about the service.
-   * For example, when using Protobuf this should generally be a
-   * {@link io.grpc.protobuf.ProtoFileDescriptorSupplier}, when present.
+   * Returns the schema descriptor for this service.  A schema descriptor is an object that is not
+   * used by gRPC core but includes information related to the service.  The type of the object
+   * is specific to the consumer, so both the code setting the schema descriptor and the code
+   * calling {@link #getSchemaDescriptor()} must coordinate.  For example, protobuf generated code
+   * sets this value, in order to be consumed by the server reflection service.  See also:
+   * {@code io.grpc.protobuf.ProtoFileDescriptorSupplier}.
+   *
+   * @since 1.1.0
    */
   @Nullable
-  public Object getMarshallerDescriptor() {
-    return marshallerDescriptor;
+  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2666")
+  public Object getSchemaDescriptor() {
+    return schemaDescriptor;
   }
 
   static void validateMethodNames(String serviceName, Collection<MethodDescriptor<?, ?>> methods) {
     Set<String> allNames = new HashSet<String>(methods.size());
     for (MethodDescriptor<?, ?> method : methods) {
+      checkNotNull(method, "method");
       String methodServiceName =
           MethodDescriptor.extractFullServiceName(method.getFullMethodName());
       checkArgument(serviceName.equals(methodServiceName),
@@ -108,4 +132,91 @@
           "duplicate name %s", method.getFullMethodName());
     }
   }
+
+  /**
+   * Creates a new builder for a {@link ServiceDescriptor}.
+   *
+   * @since 1.1.0
+   */
+  public static Builder newBuilder(String name) {
+    return new Builder(name);
+  }
+
+  /**
+   * A builder for a {@link ServiceDescriptor}.
+   *
+   * @since 1.1.0
+   */
+  public static final class Builder {
+    private Builder(String name) {
+      setName(name);
+    }
+
+    private String name;
+    private List<MethodDescriptor<?, ?>> methods = new ArrayList<MethodDescriptor<?, ?>>();
+    private Object schemaDescriptor;
+
+    /**
+     * Sets the name.  This should be non-{@code null}.
+     *
+     * @param name The name of the service.
+     * @return this builder.
+     * @since 1.1.0
+     */
+    @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2666")
+    public Builder setName(String name) {
+      this.name = checkNotNull(name, "name");
+      return this;
+    }
+
+    /**
+     * Adds a method to this service.  This should be non-{@code null}.
+     *
+     * @param method the method to add to the descriptor.
+     * @return this builder.
+     * @since 1.1.0
+     */
+    public Builder addMethod(MethodDescriptor<?, ?> method) {
+      methods.add(checkNotNull(method, "method"));
+      return this;
+    }
+
+    /**
+     * Currently not exposed.  Bulk adds methods to this builder.
+     *
+     * @param methods the methods to add.
+     * @return this builder.
+     */
+    private Builder addAllMethods(Collection<MethodDescriptor<?, ?>> methods) {
+      this.methods.addAll(methods);
+      return this;
+    }
+
+    /**
+     * Sets the schema descriptor for this builder.  A schema descriptor is an object that is not
+     * used by gRPC core but includes information related to the service.  The type of the object
+     * is specific to the consumer, so both the code calling this and the code calling
+     * {@link ServiceDescriptor#getSchemaDescriptor()} must coordinate.  For example, protobuf
+     * generated code sets this value, in order to be consumed by the server reflection service.
+     *
+     * @param schemaDescriptor an object that describes the service structure.  Should be immutable.
+     * @return this builder.
+     * @since 1.1.0
+     */
+    public Builder setSchemaDescriptor(@Nullable Object schemaDescriptor) {
+      this.schemaDescriptor = schemaDescriptor;
+      return this;
+    }
+
+    /**
+     * Constructs a new {@link ServiceDescriptor}.  {@link #setName} should have been called with a
+     * non-{@code null} value before calling this.
+     *
+     * @return a new ServiceDescriptor
+     * @since 1.1.0
+     */
+    public ServiceDescriptor build() {
+      return new ServiceDescriptor(this);
+    }
+  }
 }
\ No newline at end of file
diff --git a/core/src/test/java/io/grpc/ServiceDescriptorTest.java b/core/src/test/java/io/grpc/ServiceDescriptorTest.java
index c4a2e7f..861f34a 100644
--- a/core/src/test/java/io/grpc/ServiceDescriptorTest.java
+++ b/core/src/test/java/io/grpc/ServiceDescriptorTest.java
@@ -56,7 +56,7 @@
     thrown.expect(NullPointerException.class);
     thrown.expectMessage("name");
 
-    new ServiceDescriptor(null, Collections.emptyList());
+    new ServiceDescriptor(null, Collections.<MethodDescriptor<?, ?>>emptyList());
   }
 
   @Test
@@ -68,6 +68,14 @@
   }
 
   @Test
+  public void failsOnNullMethod() {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("method");
+
+    new ServiceDescriptor("name", (Collections.<MethodDescriptor<?, ?>>singletonList(null)));
+  }
+
+  @Test
   public void failsOnNonMatchingNames() {
     thrown.expect(IllegalArgumentException.class);
     thrown.expectMessage("service names");
diff --git a/grpclb/src/generated/main/grpc/io/grpc/grpclb/LoadBalancerGrpc.java b/grpclb/src/generated/main/grpc/io/grpc/grpclb/LoadBalancerGrpc.java
index 196b3f1..573c662 100644
--- a/grpclb/src/generated/main/grpc/io/grpc/grpclb/LoadBalancerGrpc.java
+++ b/grpclb/src/generated/main/grpc/io/grpc/grpclb/LoadBalancerGrpc.java
@@ -208,10 +208,10 @@
       synchronized (LoadBalancerGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new LoadBalancerDescriptorSupplier(),
-              METHOD_BALANCE_LOAD);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new LoadBalancerDescriptorSupplier())
+              .addMethod(METHOD_BALANCE_LOAD)
+              .build();
         }
       }
     }
diff --git a/services/src/generated/main/grpc/io/grpc/health/v1/HealthGrpc.java b/services/src/generated/main/grpc/io/grpc/health/v1/HealthGrpc.java
index 7d7c66a..8926aec 100644
--- a/services/src/generated/main/grpc/io/grpc/health/v1/HealthGrpc.java
+++ b/services/src/generated/main/grpc/io/grpc/health/v1/HealthGrpc.java
@@ -218,10 +218,10 @@
       synchronized (HealthGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new HealthDescriptorSupplier(),
-              METHOD_CHECK);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new HealthDescriptorSupplier())
+              .addMethod(METHOD_CHECK)
+              .build();
         }
       }
     }
diff --git a/services/src/generated/main/grpc/io/grpc/reflection/v1alpha/ServerReflectionGrpc.java b/services/src/generated/main/grpc/io/grpc/reflection/v1alpha/ServerReflectionGrpc.java
index 5527379..b81716e 100644
--- a/services/src/generated/main/grpc/io/grpc/reflection/v1alpha/ServerReflectionGrpc.java
+++ b/services/src/generated/main/grpc/io/grpc/reflection/v1alpha/ServerReflectionGrpc.java
@@ -210,10 +210,10 @@
       synchronized (ServerReflectionGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new ServerReflectionDescriptorSupplier(),
-              METHOD_SERVER_REFLECTION_INFO);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new ServerReflectionDescriptorSupplier())
+              .addMethod(METHOD_SERVER_REFLECTION_INFO)
+              .build();
         }
       }
     }
diff --git a/services/src/generated/test/grpc/io/grpc/reflection/testing/AnotherDynamicServiceGrpc.java b/services/src/generated/test/grpc/io/grpc/reflection/testing/AnotherDynamicServiceGrpc.java
index d88761e..f67868e 100644
--- a/services/src/generated/test/grpc/io/grpc/reflection/testing/AnotherDynamicServiceGrpc.java
+++ b/services/src/generated/test/grpc/io/grpc/reflection/testing/AnotherDynamicServiceGrpc.java
@@ -245,10 +245,10 @@
       synchronized (AnotherDynamicServiceGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new AnotherDynamicServiceDescriptorSupplier(),
-              METHOD_METHOD);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new AnotherDynamicServiceDescriptorSupplier())
+              .addMethod(METHOD_METHOD)
+              .build();
         }
       }
     }
diff --git a/services/src/generated/test/grpc/io/grpc/reflection/testing/DynamicServiceGrpc.java b/services/src/generated/test/grpc/io/grpc/reflection/testing/DynamicServiceGrpc.java
index 13bd680..dae56d3 100644
--- a/services/src/generated/test/grpc/io/grpc/reflection/testing/DynamicServiceGrpc.java
+++ b/services/src/generated/test/grpc/io/grpc/reflection/testing/DynamicServiceGrpc.java
@@ -245,10 +245,10 @@
       synchronized (DynamicServiceGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new DynamicServiceDescriptorSupplier(),
-              METHOD_METHOD);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new DynamicServiceDescriptorSupplier())
+              .addMethod(METHOD_METHOD)
+              .build();
         }
       }
     }
diff --git a/services/src/generated/test/grpc/io/grpc/reflection/testing/ReflectableServiceGrpc.java b/services/src/generated/test/grpc/io/grpc/reflection/testing/ReflectableServiceGrpc.java
index ac89434..a4ca44e 100644
--- a/services/src/generated/test/grpc/io/grpc/reflection/testing/ReflectableServiceGrpc.java
+++ b/services/src/generated/test/grpc/io/grpc/reflection/testing/ReflectableServiceGrpc.java
@@ -218,10 +218,10 @@
       synchronized (ReflectableServiceGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new ReflectableServiceDescriptorSupplier(),
-              METHOD_METHOD);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new ReflectableServiceDescriptorSupplier())
+              .addMethod(METHOD_METHOD)
+              .build();
         }
       }
     }
diff --git a/services/src/main/java/io/grpc/protobuf/service/ProtoReflectionService.java b/services/src/main/java/io/grpc/protobuf/service/ProtoReflectionService.java
index 89941d8..6611322 100644
--- a/services/src/main/java/io/grpc/protobuf/service/ProtoReflectionService.java
+++ b/services/src/main/java/io/grpc/protobuf/service/ProtoReflectionService.java
@@ -337,10 +337,10 @@
         List<ServerServiceDefinition> currentMutableServices = server.getMutableServices();
         for (ServerServiceDefinition mutableService : currentMutableServices) {
           io.grpc.ServiceDescriptor serviceDescriptor = mutableService.getServiceDescriptor();
-          if (serviceDescriptor.getMarshallerDescriptor() instanceof ProtoFileDescriptorSupplier) {
+          if (serviceDescriptor.getSchemaDescriptor() instanceof ProtoFileDescriptorSupplier) {
             String serviceName = serviceDescriptor.getName();
             FileDescriptor fileDescriptor =
-                ((ProtoFileDescriptorSupplier) serviceDescriptor.getMarshallerDescriptor())
+                ((ProtoFileDescriptorSupplier) serviceDescriptor.getSchemaDescriptor())
                     .getFileDescriptor();
             currentFileDescriptors.add(fileDescriptor);
             checkState(!currentServiceNames.contains(serviceName),
@@ -433,9 +433,9 @@
       Set<String> seenFiles = new HashSet<String>();
       for (ServerServiceDefinition service : services) {
         io.grpc.ServiceDescriptor serviceDescriptor = service.getServiceDescriptor();
-        if (serviceDescriptor.getMarshallerDescriptor() instanceof ProtoFileDescriptorSupplier) {
+        if (serviceDescriptor.getSchemaDescriptor() instanceof ProtoFileDescriptorSupplier) {
           FileDescriptor fileDescriptor =
-              ((ProtoFileDescriptorSupplier) serviceDescriptor.getMarshallerDescriptor())
+              ((ProtoFileDescriptorSupplier) serviceDescriptor.getSchemaDescriptor())
                   .getFileDescriptor();
           String serviceName = serviceDescriptor.getName();
           checkState(!serviceNames.contains(serviceName),
diff --git a/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/MetricsServiceGrpc.java b/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/MetricsServiceGrpc.java
index 4ad6080..3bf0ddc 100644
--- a/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/MetricsServiceGrpc.java
+++ b/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/MetricsServiceGrpc.java
@@ -286,11 +286,11 @@
       synchronized (MetricsServiceGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new MetricsServiceDescriptorSupplier(),
-              METHOD_GET_ALL_GAUGES,
-              METHOD_GET_GAUGE);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new MetricsServiceDescriptorSupplier())
+              .addMethod(METHOD_GET_ALL_GAUGES)
+              .addMethod(METHOD_GET_GAUGE)
+              .build();
         }
       }
     }
diff --git a/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/ReconnectServiceGrpc.java b/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/ReconnectServiceGrpc.java
index a92abca..ec088a7 100644
--- a/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/ReconnectServiceGrpc.java
+++ b/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/ReconnectServiceGrpc.java
@@ -284,11 +284,11 @@
       synchronized (ReconnectServiceGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new ReconnectServiceDescriptorSupplier(),
-              METHOD_START,
-              METHOD_STOP);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new ReconnectServiceDescriptorSupplier())
+              .addMethod(METHOD_START)
+              .addMethod(METHOD_STOP)
+              .build();
         }
       }
     }
diff --git a/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/TestServiceGrpc.java b/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/TestServiceGrpc.java
index 4ebd5d9..aee416b 100644
--- a/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/TestServiceGrpc.java
+++ b/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/TestServiceGrpc.java
@@ -571,16 +571,16 @@
       synchronized (TestServiceGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new TestServiceDescriptorSupplier(),
-              METHOD_EMPTY_CALL,
-              METHOD_UNARY_CALL,
-              METHOD_STREAMING_OUTPUT_CALL,
-              METHOD_STREAMING_INPUT_CALL,
-              METHOD_FULL_DUPLEX_CALL,
-              METHOD_HALF_DUPLEX_CALL,
-              METHOD_UNIMPLEMENTED_CALL);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new TestServiceDescriptorSupplier())
+              .addMethod(METHOD_EMPTY_CALL)
+              .addMethod(METHOD_UNARY_CALL)
+              .addMethod(METHOD_STREAMING_OUTPUT_CALL)
+              .addMethod(METHOD_STREAMING_INPUT_CALL)
+              .addMethod(METHOD_FULL_DUPLEX_CALL)
+              .addMethod(METHOD_HALF_DUPLEX_CALL)
+              .addMethod(METHOD_UNIMPLEMENTED_CALL)
+              .build();
         }
       }
     }
diff --git a/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/UnimplementedServiceGrpc.java b/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/UnimplementedServiceGrpc.java
index e6c6a98..e77568a 100644
--- a/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/UnimplementedServiceGrpc.java
+++ b/testing-proto/src/generated/main/grpc/io/grpc/testing/integration/UnimplementedServiceGrpc.java
@@ -250,10 +250,10 @@
       synchronized (UnimplementedServiceGrpc.class) {
         result = serviceDescriptor;
         if (result == null) {
-          serviceDescriptor = result = new io.grpc.ServiceDescriptor(
-              SERVICE_NAME,
-              new UnimplementedServiceDescriptorSupplier(),
-              METHOD_UNIMPLEMENTED_CALL);
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new UnimplementedServiceDescriptorSupplier())
+              .addMethod(METHOD_UNIMPLEMENTED_CALL)
+              .build();
         }
       }
     }