Include Java's @Deprecated annotation on RPC services or methods with `option deprecated = true;`
diff --git a/.gitattributes b/.gitattributes
index 6754557..d7df7b3 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,6 @@
 TestService.java.txt binary
 TestServiceLite.java.txt binary
 TestServiceNano.java.txt binary
+TestDeprecatedService.java.txt binary
+TestDeprecatedServiceLite.java.txt binary
+TestDeprecatedServiceNano.java.txt binary
diff --git a/compiler/build.gradle b/compiler/build.gradle
index ceffda8..253392f 100644
--- a/compiler/build.gradle
+++ b/compiler/build.gradle
@@ -301,7 +301,7 @@
     }
 }
 
-def configureTestTask(Task task, String dep, String extraPackage) {
+def configureTestTask(Task task, String dep, String extraPackage, String serviceName) {
     test.dependsOn task
     task.dependsOn "generateTest${dep}Proto"
     if (osdetector.os != 'windows') {
@@ -312,13 +312,19 @@
     }
     // File isn't found on Windows if last slash is forward-slash
     def slash = System.getProperty("file.separator")
-    task.args "$buildDir/generated/source/proto/test${dep}/grpc/io/grpc/testing/compiler${extraPackage}${slash}TestServiceGrpc.java",
-            "$projectDir/src/test${dep}/golden/TestService.java.txt"
+    task.args "$buildDir/generated/source/proto/test${dep}/grpc/io/grpc/testing/compiler${extraPackage}${slash}${serviceName}Grpc.java",
+            "$projectDir/src/test${dep}/golden/${serviceName}.java.txt"
 }
 
 task testGolden(type: Exec)
 task testLiteGolden(type: Exec)
 task testNanoGolden(type: Exec)
-configureTestTask(testGolden, '', '')
-configureTestTask(testLiteGolden, 'Lite', '')
-configureTestTask(testNanoGolden, 'Nano', '/nano')
+task testDeprecatedGolden(type: Exec)
+task testDeprecatedLiteGolden(type: Exec)
+task testDeprecatedNanoGolden(type: Exec)
+configureTestTask(testGolden, '', '', 'TestService')
+configureTestTask(testLiteGolden, 'Lite', '', 'TestService')
+configureTestTask(testNanoGolden, 'Nano', '/nano', 'TestService')
+configureTestTask(testDeprecatedGolden, '', '', 'TestDeprecatedService')
+configureTestTask(testDeprecatedLiteGolden, 'Lite', '', 'TestDeprecatedService')
+configureTestTask(testDeprecatedNanoGolden, 'Nano', '/nano', 'TestDeprecatedService')
diff --git a/compiler/src/java_plugin/cpp/java_generator.cpp b/compiler/src/java_plugin/cpp/java_generator.cpp
index 7d5ba6f..519a28a 100644
--- a/compiler/src/java_plugin/cpp/java_generator.cpp
+++ b/compiler/src/java_plugin/cpp/java_generator.cpp
@@ -8,6 +8,7 @@
 #include <vector>
 #include <google/protobuf/compiler/java/java_names.h>
 #include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 
@@ -644,6 +645,11 @@
   if (!interface) {
     GrpcWriteServiceDocComment(p, service);
   }
+
+  if (service->options().deprecated()) {
+    p->Print(*vars, "@$Deprecated$\n");
+  }
+
   if (impl_base) {
     p->Print(
         *vars,
@@ -713,6 +719,11 @@
     if (!interface) {
       GrpcWriteMethodDocComment(p, method);
     }
+
+    if (method->options().deprecated()) {
+      p->Print(*vars, "@$Deprecated$\n");
+    }
+
     p->Print("public ");
     switch (call_type) {
       case BLOCKING_CALL:
@@ -1152,7 +1163,14 @@
       *vars,
       "@$Generated$(\n"
       "    value = \"by gRPC proto compiler$grpc_version$\",\n"
-      "    comments = \"Source: $file_name$\")\n"
+      "    comments = \"Source: $file_name$\")\n");
+
+  if (service->options().deprecated()) {
+    p->Print(*vars, "@$Deprecated$\n");
+  }
+
+  p->Print(
+      *vars,
       "public final class $service_class_name$ {\n\n");
   p->Indent();
   p->Print(
diff --git a/compiler/src/test/golden/TestDeprecatedService.java.txt b/compiler/src/test/golden/TestDeprecatedService.java.txt
new file mode 100644
index 0000000..dffc6b8
--- /dev/null
+++ b/compiler/src/test/golden/TestDeprecatedService.java.txt
@@ -0,0 +1,316 @@
+package io.grpc.testing.compiler;
+
+import static io.grpc.MethodDescriptor.generateFullMethodName;
+import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncUnaryCall;
+import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;
+import static io.grpc.stub.ClientCalls.blockingUnaryCall;
+import static io.grpc.stub.ClientCalls.futureUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+
+/**
+ * <pre>
+ * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+ * </pre>
+ */
+@javax.annotation.Generated(
+    value = "by gRPC proto compiler (version 1.15.0-SNAPSHOT)",
+    comments = "Source: grpc/testing/compiler/test.proto")
+@java.lang.Deprecated
+public final class TestDeprecatedServiceGrpc {
+
+  private TestDeprecatedServiceGrpc() {}
+
+  public static final String SERVICE_NAME = "grpc.testing.compiler.TestDeprecatedService";
+
+  // Static method descriptors that strictly reflect the proto.
+  private static volatile io.grpc.MethodDescriptor<io.grpc.testing.compiler.Test.SimpleRequest,
+      io.grpc.testing.compiler.Test.SimpleResponse> getDeprecatedMethodMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "DeprecatedMethod",
+      requestType = io.grpc.testing.compiler.Test.SimpleRequest.class,
+      responseType = io.grpc.testing.compiler.Test.SimpleResponse.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<io.grpc.testing.compiler.Test.SimpleRequest,
+      io.grpc.testing.compiler.Test.SimpleResponse> getDeprecatedMethodMethod() {
+    io.grpc.MethodDescriptor<io.grpc.testing.compiler.Test.SimpleRequest, io.grpc.testing.compiler.Test.SimpleResponse> getDeprecatedMethodMethod;
+    if ((getDeprecatedMethodMethod = TestDeprecatedServiceGrpc.getDeprecatedMethodMethod) == null) {
+      synchronized (TestDeprecatedServiceGrpc.class) {
+        if ((getDeprecatedMethodMethod = TestDeprecatedServiceGrpc.getDeprecatedMethodMethod) == null) {
+          TestDeprecatedServiceGrpc.getDeprecatedMethodMethod = getDeprecatedMethodMethod = 
+              io.grpc.MethodDescriptor.<io.grpc.testing.compiler.Test.SimpleRequest, io.grpc.testing.compiler.Test.SimpleResponse>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(
+                  "grpc.testing.compiler.TestDeprecatedService", "DeprecatedMethod"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.testing.compiler.Test.SimpleRequest.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.testing.compiler.Test.SimpleResponse.getDefaultInstance()))
+                  .setSchemaDescriptor(new TestDeprecatedServiceMethodDescriptorSupplier("DeprecatedMethod"))
+                  .build();
+          }
+        }
+     }
+     return getDeprecatedMethodMethod;
+  }
+
+  /**
+   * Creates a new async stub that supports all call types for the service
+   */
+  public static TestDeprecatedServiceStub newStub(io.grpc.Channel channel) {
+    return new TestDeprecatedServiceStub(channel);
+  }
+
+  /**
+   * Creates a new blocking-style stub that supports unary and streaming output calls on the service
+   */
+  public static TestDeprecatedServiceBlockingStub newBlockingStub(
+      io.grpc.Channel channel) {
+    return new TestDeprecatedServiceBlockingStub(channel);
+  }
+
+  /**
+   * Creates a new ListenableFuture-style stub that supports unary calls on the service
+   */
+  public static TestDeprecatedServiceFutureStub newFutureStub(
+      io.grpc.Channel channel) {
+    return new TestDeprecatedServiceFutureStub(channel);
+  }
+
+  /**
+   * <pre>
+   * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+   * </pre>
+   */
+  @java.lang.Deprecated
+  public static abstract class TestDeprecatedServiceImplBase implements io.grpc.BindableService {
+
+    /**
+     * <pre>
+     * An RPC method that has been deprecated and should generate with Java's &#64;Deprecated annotation
+     * </pre>
+     */
+    @java.lang.Deprecated
+    public void deprecatedMethod(io.grpc.testing.compiler.Test.SimpleRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.testing.compiler.Test.SimpleResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(getDeprecatedMethodMethod(), responseObserver);
+    }
+
+    @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            getDeprecatedMethodMethod(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                io.grpc.testing.compiler.Test.SimpleRequest,
+                io.grpc.testing.compiler.Test.SimpleResponse>(
+                  this, METHODID_DEPRECATED_METHOD)))
+          .build();
+    }
+  }
+
+  /**
+   * <pre>
+   * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+   * </pre>
+   */
+  @java.lang.Deprecated
+  public static final class TestDeprecatedServiceStub extends io.grpc.stub.AbstractStub<TestDeprecatedServiceStub> {
+    private TestDeprecatedServiceStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+
+    private TestDeprecatedServiceStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected TestDeprecatedServiceStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new TestDeprecatedServiceStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * An RPC method that has been deprecated and should generate with Java's &#64;Deprecated annotation
+     * </pre>
+     */
+    @java.lang.Deprecated
+    public void deprecatedMethod(io.grpc.testing.compiler.Test.SimpleRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.testing.compiler.Test.SimpleResponse> responseObserver) {
+      asyncUnaryCall(
+          getChannel().newCall(getDeprecatedMethodMethod(), getCallOptions()), request, responseObserver);
+    }
+  }
+
+  /**
+   * <pre>
+   * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+   * </pre>
+   */
+  @java.lang.Deprecated
+  public static final class TestDeprecatedServiceBlockingStub extends io.grpc.stub.AbstractStub<TestDeprecatedServiceBlockingStub> {
+    private TestDeprecatedServiceBlockingStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+
+    private TestDeprecatedServiceBlockingStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected TestDeprecatedServiceBlockingStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new TestDeprecatedServiceBlockingStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * An RPC method that has been deprecated and should generate with Java's &#64;Deprecated annotation
+     * </pre>
+     */
+    @java.lang.Deprecated
+    public io.grpc.testing.compiler.Test.SimpleResponse deprecatedMethod(io.grpc.testing.compiler.Test.SimpleRequest request) {
+      return blockingUnaryCall(
+          getChannel(), getDeprecatedMethodMethod(), getCallOptions(), request);
+    }
+  }
+
+  /**
+   * <pre>
+   * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+   * </pre>
+   */
+  @java.lang.Deprecated
+  public static final class TestDeprecatedServiceFutureStub extends io.grpc.stub.AbstractStub<TestDeprecatedServiceFutureStub> {
+    private TestDeprecatedServiceFutureStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+
+    private TestDeprecatedServiceFutureStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected TestDeprecatedServiceFutureStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new TestDeprecatedServiceFutureStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * An RPC method that has been deprecated and should generate with Java's &#64;Deprecated annotation
+     * </pre>
+     */
+    @java.lang.Deprecated
+    public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.compiler.Test.SimpleResponse> deprecatedMethod(
+        io.grpc.testing.compiler.Test.SimpleRequest request) {
+      return futureUnaryCall(
+          getChannel().newCall(getDeprecatedMethodMethod(), getCallOptions()), request);
+    }
+  }
+
+  private static final int METHODID_DEPRECATED_METHOD = 0;
+
+  private static final class MethodHandlers<Req, Resp> implements
+      io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+    private final TestDeprecatedServiceImplBase serviceImpl;
+    private final int methodId;
+
+    MethodHandlers(TestDeprecatedServiceImplBase serviceImpl, int methodId) {
+      this.serviceImpl = serviceImpl;
+      this.methodId = methodId;
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        case METHODID_DEPRECATED_METHOD:
+          serviceImpl.deprecatedMethod((io.grpc.testing.compiler.Test.SimpleRequest) request,
+              (io.grpc.stub.StreamObserver<io.grpc.testing.compiler.Test.SimpleResponse>) responseObserver);
+          break;
+        default:
+          throw new AssertionError();
+      }
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver<Req> invoke(
+        io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        default:
+          throw new AssertionError();
+      }
+    }
+  }
+
+  private static abstract class TestDeprecatedServiceBaseDescriptorSupplier
+      implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier {
+    TestDeprecatedServiceBaseDescriptorSupplier() {}
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() {
+      return io.grpc.testing.compiler.Test.getDescriptor();
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {
+      return getFileDescriptor().findServiceByName("TestDeprecatedService");
+    }
+  }
+
+  private static final class TestDeprecatedServiceFileDescriptorSupplier
+      extends TestDeprecatedServiceBaseDescriptorSupplier {
+    TestDeprecatedServiceFileDescriptorSupplier() {}
+  }
+
+  private static final class TestDeprecatedServiceMethodDescriptorSupplier
+      extends TestDeprecatedServiceBaseDescriptorSupplier
+      implements io.grpc.protobuf.ProtoMethodDescriptorSupplier {
+    private final String methodName;
+
+    TestDeprecatedServiceMethodDescriptorSupplier(String methodName) {
+      this.methodName = methodName;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() {
+      return getServiceDescriptor().findMethodByName(methodName);
+    }
+  }
+
+  private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
+
+  public static io.grpc.ServiceDescriptor getServiceDescriptor() {
+    io.grpc.ServiceDescriptor result = serviceDescriptor;
+    if (result == null) {
+      synchronized (TestDeprecatedServiceGrpc.class) {
+        result = serviceDescriptor;
+        if (result == null) {
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new TestDeprecatedServiceFileDescriptorSupplier())
+              .addMethod(getDeprecatedMethodMethod())
+              .build();
+        }
+      }
+    }
+    return result;
+  }
+}
diff --git a/compiler/src/test/proto/grpc/testing/compiler/test.proto b/compiler/src/test/proto/grpc/testing/compiler/test.proto
index 464cecd..62cf6c8 100644
--- a/compiler/src/test/proto/grpc/testing/compiler/test.proto
+++ b/compiler/src/test/proto/grpc/testing/compiler/test.proto
@@ -71,3 +71,13 @@
   // method should have a '_' appended.
   rpc Import(stream StreamingInputCallRequest) returns (stream StreamingInputCallResponse);
 }
+
+// Test service that has been deprecated and should generate with Java's @Deprecated annotation
+service TestDeprecatedService {
+  option deprecated = true;
+
+  // An RPC method that has been deprecated and should generate with Java's @Deprecated annotation
+  rpc DeprecatedMethod(SimpleRequest) returns (SimpleResponse) {
+    option deprecated = true;
+  }
+}
\ No newline at end of file
diff --git a/compiler/src/testLite/golden/TestDeprecatedService.java.txt b/compiler/src/testLite/golden/TestDeprecatedService.java.txt
new file mode 100644
index 0000000..4b9e9d5
--- /dev/null
+++ b/compiler/src/testLite/golden/TestDeprecatedService.java.txt
@@ -0,0 +1,279 @@
+package io.grpc.testing.compiler;
+
+import static io.grpc.MethodDescriptor.generateFullMethodName;
+import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncUnaryCall;
+import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;
+import static io.grpc.stub.ClientCalls.blockingUnaryCall;
+import static io.grpc.stub.ClientCalls.futureUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+
+/**
+ * <pre>
+ * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+ * </pre>
+ */
+@javax.annotation.Generated(
+    value = "by gRPC proto compiler (version 1.15.0-SNAPSHOT)",
+    comments = "Source: grpc/testing/compiler/test.proto")
+@java.lang.Deprecated
+public final class TestDeprecatedServiceGrpc {
+
+  private TestDeprecatedServiceGrpc() {}
+
+  public static final String SERVICE_NAME = "grpc.testing.compiler.TestDeprecatedService";
+
+  // Static method descriptors that strictly reflect the proto.
+  private static volatile io.grpc.MethodDescriptor<io.grpc.testing.compiler.Test.SimpleRequest,
+      io.grpc.testing.compiler.Test.SimpleResponse> getDeprecatedMethodMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "DeprecatedMethod",
+      requestType = io.grpc.testing.compiler.Test.SimpleRequest.class,
+      responseType = io.grpc.testing.compiler.Test.SimpleResponse.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<io.grpc.testing.compiler.Test.SimpleRequest,
+      io.grpc.testing.compiler.Test.SimpleResponse> getDeprecatedMethodMethod() {
+    io.grpc.MethodDescriptor<io.grpc.testing.compiler.Test.SimpleRequest, io.grpc.testing.compiler.Test.SimpleResponse> getDeprecatedMethodMethod;
+    if ((getDeprecatedMethodMethod = TestDeprecatedServiceGrpc.getDeprecatedMethodMethod) == null) {
+      synchronized (TestDeprecatedServiceGrpc.class) {
+        if ((getDeprecatedMethodMethod = TestDeprecatedServiceGrpc.getDeprecatedMethodMethod) == null) {
+          TestDeprecatedServiceGrpc.getDeprecatedMethodMethod = getDeprecatedMethodMethod = 
+              io.grpc.MethodDescriptor.<io.grpc.testing.compiler.Test.SimpleRequest, io.grpc.testing.compiler.Test.SimpleResponse>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(
+                  "grpc.testing.compiler.TestDeprecatedService", "DeprecatedMethod"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller(
+                  io.grpc.testing.compiler.Test.SimpleRequest.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller(
+                  io.grpc.testing.compiler.Test.SimpleResponse.getDefaultInstance()))
+                  .build();
+          }
+        }
+     }
+     return getDeprecatedMethodMethod;
+  }
+
+  /**
+   * Creates a new async stub that supports all call types for the service
+   */
+  public static TestDeprecatedServiceStub newStub(io.grpc.Channel channel) {
+    return new TestDeprecatedServiceStub(channel);
+  }
+
+  /**
+   * Creates a new blocking-style stub that supports unary and streaming output calls on the service
+   */
+  public static TestDeprecatedServiceBlockingStub newBlockingStub(
+      io.grpc.Channel channel) {
+    return new TestDeprecatedServiceBlockingStub(channel);
+  }
+
+  /**
+   * Creates a new ListenableFuture-style stub that supports unary calls on the service
+   */
+  public static TestDeprecatedServiceFutureStub newFutureStub(
+      io.grpc.Channel channel) {
+    return new TestDeprecatedServiceFutureStub(channel);
+  }
+
+  /**
+   * <pre>
+   * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+   * </pre>
+   */
+  @java.lang.Deprecated
+  public static abstract class TestDeprecatedServiceImplBase implements io.grpc.BindableService {
+
+    /**
+     * <pre>
+     * An RPC method that has been deprecated and should generate with Java's &#64;Deprecated annotation
+     * </pre>
+     */
+    @java.lang.Deprecated
+    public void deprecatedMethod(io.grpc.testing.compiler.Test.SimpleRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.testing.compiler.Test.SimpleResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(getDeprecatedMethodMethod(), responseObserver);
+    }
+
+    @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            getDeprecatedMethodMethod(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                io.grpc.testing.compiler.Test.SimpleRequest,
+                io.grpc.testing.compiler.Test.SimpleResponse>(
+                  this, METHODID_DEPRECATED_METHOD)))
+          .build();
+    }
+  }
+
+  /**
+   * <pre>
+   * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+   * </pre>
+   */
+  @java.lang.Deprecated
+  public static final class TestDeprecatedServiceStub extends io.grpc.stub.AbstractStub<TestDeprecatedServiceStub> {
+    private TestDeprecatedServiceStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+
+    private TestDeprecatedServiceStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected TestDeprecatedServiceStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new TestDeprecatedServiceStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * An RPC method that has been deprecated and should generate with Java's &#64;Deprecated annotation
+     * </pre>
+     */
+    @java.lang.Deprecated
+    public void deprecatedMethod(io.grpc.testing.compiler.Test.SimpleRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.testing.compiler.Test.SimpleResponse> responseObserver) {
+      asyncUnaryCall(
+          getChannel().newCall(getDeprecatedMethodMethod(), getCallOptions()), request, responseObserver);
+    }
+  }
+
+  /**
+   * <pre>
+   * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+   * </pre>
+   */
+  @java.lang.Deprecated
+  public static final class TestDeprecatedServiceBlockingStub extends io.grpc.stub.AbstractStub<TestDeprecatedServiceBlockingStub> {
+    private TestDeprecatedServiceBlockingStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+
+    private TestDeprecatedServiceBlockingStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected TestDeprecatedServiceBlockingStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new TestDeprecatedServiceBlockingStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * An RPC method that has been deprecated and should generate with Java's &#64;Deprecated annotation
+     * </pre>
+     */
+    @java.lang.Deprecated
+    public io.grpc.testing.compiler.Test.SimpleResponse deprecatedMethod(io.grpc.testing.compiler.Test.SimpleRequest request) {
+      return blockingUnaryCall(
+          getChannel(), getDeprecatedMethodMethod(), getCallOptions(), request);
+    }
+  }
+
+  /**
+   * <pre>
+   * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+   * </pre>
+   */
+  @java.lang.Deprecated
+  public static final class TestDeprecatedServiceFutureStub extends io.grpc.stub.AbstractStub<TestDeprecatedServiceFutureStub> {
+    private TestDeprecatedServiceFutureStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+
+    private TestDeprecatedServiceFutureStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected TestDeprecatedServiceFutureStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new TestDeprecatedServiceFutureStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * An RPC method that has been deprecated and should generate with Java's &#64;Deprecated annotation
+     * </pre>
+     */
+    @java.lang.Deprecated
+    public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.compiler.Test.SimpleResponse> deprecatedMethod(
+        io.grpc.testing.compiler.Test.SimpleRequest request) {
+      return futureUnaryCall(
+          getChannel().newCall(getDeprecatedMethodMethod(), getCallOptions()), request);
+    }
+  }
+
+  private static final int METHODID_DEPRECATED_METHOD = 0;
+
+  private static final class MethodHandlers<Req, Resp> implements
+      io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+    private final TestDeprecatedServiceImplBase serviceImpl;
+    private final int methodId;
+
+    MethodHandlers(TestDeprecatedServiceImplBase serviceImpl, int methodId) {
+      this.serviceImpl = serviceImpl;
+      this.methodId = methodId;
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        case METHODID_DEPRECATED_METHOD:
+          serviceImpl.deprecatedMethod((io.grpc.testing.compiler.Test.SimpleRequest) request,
+              (io.grpc.stub.StreamObserver<io.grpc.testing.compiler.Test.SimpleResponse>) responseObserver);
+          break;
+        default:
+          throw new AssertionError();
+      }
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver<Req> invoke(
+        io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        default:
+          throw new AssertionError();
+      }
+    }
+  }
+
+  private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
+
+  public static io.grpc.ServiceDescriptor getServiceDescriptor() {
+    io.grpc.ServiceDescriptor result = serviceDescriptor;
+    if (result == null) {
+      synchronized (TestDeprecatedServiceGrpc.class) {
+        result = serviceDescriptor;
+        if (result == null) {
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .addMethod(getDeprecatedMethodMethod())
+              .build();
+        }
+      }
+    }
+    return result;
+  }
+}
diff --git a/compiler/src/testNano/golden/TestDeprecatedService.java.txt b/compiler/src/testNano/golden/TestDeprecatedService.java.txt
new file mode 100644
index 0000000..e7209eb
--- /dev/null
+++ b/compiler/src/testNano/golden/TestDeprecatedService.java.txt
@@ -0,0 +1,305 @@
+package io.grpc.testing.compiler.nano;
+
+import static io.grpc.MethodDescriptor.generateFullMethodName;
+import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncUnaryCall;
+import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;
+import static io.grpc.stub.ClientCalls.blockingUnaryCall;
+import static io.grpc.stub.ClientCalls.futureUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+
+import java.io.IOException;
+
+/**
+ * <pre>
+ * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+ * </pre>
+ */
+@javax.annotation.Generated(
+    value = "by gRPC proto compiler (version 1.15.0-SNAPSHOT)",
+    comments = "Source: grpc/testing/compiler/test.proto")
+@java.lang.Deprecated
+public final class TestDeprecatedServiceGrpc {
+
+  private TestDeprecatedServiceGrpc() {}
+
+  public static final String SERVICE_NAME = "grpc.testing.compiler.TestDeprecatedService";
+
+  // Static method descriptors that strictly reflect the proto.
+  private static final int ARG_IN_METHOD_DEPRECATED_METHOD = 0;
+  private static final int ARG_OUT_METHOD_DEPRECATED_METHOD = 1;
+  private static volatile io.grpc.MethodDescriptor<io.grpc.testing.compiler.nano.Test.SimpleRequest,
+      io.grpc.testing.compiler.nano.Test.SimpleResponse> getDeprecatedMethodMethod;
+
+  public static io.grpc.MethodDescriptor<io.grpc.testing.compiler.nano.Test.SimpleRequest,
+      io.grpc.testing.compiler.nano.Test.SimpleResponse> getDeprecatedMethodMethod() {
+    io.grpc.MethodDescriptor<io.grpc.testing.compiler.nano.Test.SimpleRequest, io.grpc.testing.compiler.nano.Test.SimpleResponse> getDeprecatedMethodMethod;
+    if ((getDeprecatedMethodMethod = TestDeprecatedServiceGrpc.getDeprecatedMethodMethod) == null) {
+      synchronized (TestDeprecatedServiceGrpc.class) {
+        if ((getDeprecatedMethodMethod = TestDeprecatedServiceGrpc.getDeprecatedMethodMethod) == null) {
+          TestDeprecatedServiceGrpc.getDeprecatedMethodMethod = getDeprecatedMethodMethod = 
+              io.grpc.MethodDescriptor.<io.grpc.testing.compiler.nano.Test.SimpleRequest, io.grpc.testing.compiler.nano.Test.SimpleResponse>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(
+                  "grpc.testing.compiler.TestDeprecatedService", "DeprecatedMethod"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.nano.NanoUtils.<io.grpc.testing.compiler.nano.Test.SimpleRequest>marshaller(
+                  new NanoFactory<io.grpc.testing.compiler.nano.Test.SimpleRequest>(ARG_IN_METHOD_DEPRECATED_METHOD)))
+              .setResponseMarshaller(io.grpc.protobuf.nano.NanoUtils.<io.grpc.testing.compiler.nano.Test.SimpleResponse>marshaller(
+                  new NanoFactory<io.grpc.testing.compiler.nano.Test.SimpleResponse>(ARG_OUT_METHOD_DEPRECATED_METHOD)))
+              .build();
+        }
+      }
+    }
+    return getDeprecatedMethodMethod;
+  }
+
+  private static final class NanoFactory<T extends com.google.protobuf.nano.MessageNano>
+      implements io.grpc.protobuf.nano.MessageNanoFactory<T> {
+    private final int id;
+
+    NanoFactory(int id) {
+      this.id = id;
+    }
+
+    @java.lang.Override
+    public T newInstance() {
+      Object o;
+      switch (id) {
+      case ARG_IN_METHOD_DEPRECATED_METHOD:
+        o = new io.grpc.testing.compiler.nano.Test.SimpleRequest();
+        break;
+      case ARG_OUT_METHOD_DEPRECATED_METHOD:
+        o = new io.grpc.testing.compiler.nano.Test.SimpleResponse();
+        break;
+      default:
+        throw new AssertionError();
+      }
+      @java.lang.SuppressWarnings("unchecked")
+      T t = (T) o;
+      return t;
+    }
+  }
+
+  /**
+   * Creates a new async stub that supports all call types for the service
+   */
+  public static TestDeprecatedServiceStub newStub(io.grpc.Channel channel) {
+    return new TestDeprecatedServiceStub(channel);
+  }
+
+  /**
+   * Creates a new blocking-style stub that supports unary and streaming output calls on the service
+   */
+  public static TestDeprecatedServiceBlockingStub newBlockingStub(
+      io.grpc.Channel channel) {
+    return new TestDeprecatedServiceBlockingStub(channel);
+  }
+
+  /**
+   * Creates a new ListenableFuture-style stub that supports unary calls on the service
+   */
+  public static TestDeprecatedServiceFutureStub newFutureStub(
+      io.grpc.Channel channel) {
+    return new TestDeprecatedServiceFutureStub(channel);
+  }
+
+  /**
+   * <pre>
+   * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+   * </pre>
+   */
+  @java.lang.Deprecated
+  public static abstract class TestDeprecatedServiceImplBase implements io.grpc.BindableService {
+
+    /**
+     * <pre>
+     * An RPC method that has been deprecated and should generate with Java's &#64;Deprecated annotation
+     * </pre>
+     */
+    @java.lang.Deprecated
+    public void deprecatedMethod(io.grpc.testing.compiler.nano.Test.SimpleRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.testing.compiler.nano.Test.SimpleResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(getDeprecatedMethodMethod(), responseObserver);
+    }
+
+    @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            getDeprecatedMethodMethod(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                io.grpc.testing.compiler.nano.Test.SimpleRequest,
+                io.grpc.testing.compiler.nano.Test.SimpleResponse>(
+                  this, METHODID_DEPRECATED_METHOD)))
+          .build();
+    }
+  }
+
+  /**
+   * <pre>
+   * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+   * </pre>
+   */
+  @java.lang.Deprecated
+  public static final class TestDeprecatedServiceStub extends io.grpc.stub.AbstractStub<TestDeprecatedServiceStub> {
+    private TestDeprecatedServiceStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+
+    private TestDeprecatedServiceStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected TestDeprecatedServiceStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new TestDeprecatedServiceStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * An RPC method that has been deprecated and should generate with Java's &#64;Deprecated annotation
+     * </pre>
+     */
+    @java.lang.Deprecated
+    public void deprecatedMethod(io.grpc.testing.compiler.nano.Test.SimpleRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.testing.compiler.nano.Test.SimpleResponse> responseObserver) {
+      asyncUnaryCall(
+          getChannel().newCall(getDeprecatedMethodMethod(), getCallOptions()), request, responseObserver);
+    }
+  }
+
+  /**
+   * <pre>
+   * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+   * </pre>
+   */
+  @java.lang.Deprecated
+  public static final class TestDeprecatedServiceBlockingStub extends io.grpc.stub.AbstractStub<TestDeprecatedServiceBlockingStub> {
+    private TestDeprecatedServiceBlockingStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+
+    private TestDeprecatedServiceBlockingStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected TestDeprecatedServiceBlockingStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new TestDeprecatedServiceBlockingStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * An RPC method that has been deprecated and should generate with Java's &#64;Deprecated annotation
+     * </pre>
+     */
+    @java.lang.Deprecated
+    public io.grpc.testing.compiler.nano.Test.SimpleResponse deprecatedMethod(io.grpc.testing.compiler.nano.Test.SimpleRequest request) {
+      return blockingUnaryCall(
+          getChannel(), getDeprecatedMethodMethod(), getCallOptions(), request);
+    }
+  }
+
+  /**
+   * <pre>
+   * Test service that has been deprecated and should generate with Java's &#64;Deprecated annotation
+   * </pre>
+   */
+  @java.lang.Deprecated
+  public static final class TestDeprecatedServiceFutureStub extends io.grpc.stub.AbstractStub<TestDeprecatedServiceFutureStub> {
+    private TestDeprecatedServiceFutureStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+
+    private TestDeprecatedServiceFutureStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected TestDeprecatedServiceFutureStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new TestDeprecatedServiceFutureStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * An RPC method that has been deprecated and should generate with Java's &#64;Deprecated annotation
+     * </pre>
+     */
+    @java.lang.Deprecated
+    public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.compiler.nano.Test.SimpleResponse> deprecatedMethod(
+        io.grpc.testing.compiler.nano.Test.SimpleRequest request) {
+      return futureUnaryCall(
+          getChannel().newCall(getDeprecatedMethodMethod(), getCallOptions()), request);
+    }
+  }
+
+  private static final int METHODID_DEPRECATED_METHOD = 0;
+
+  private static final class MethodHandlers<Req, Resp> implements
+      io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+    private final TestDeprecatedServiceImplBase serviceImpl;
+    private final int methodId;
+
+    MethodHandlers(TestDeprecatedServiceImplBase serviceImpl, int methodId) {
+      this.serviceImpl = serviceImpl;
+      this.methodId = methodId;
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        case METHODID_DEPRECATED_METHOD:
+          serviceImpl.deprecatedMethod((io.grpc.testing.compiler.nano.Test.SimpleRequest) request,
+              (io.grpc.stub.StreamObserver<io.grpc.testing.compiler.nano.Test.SimpleResponse>) responseObserver);
+          break;
+        default:
+          throw new AssertionError();
+      }
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver<Req> invoke(
+        io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        default:
+          throw new AssertionError();
+      }
+    }
+  }
+
+  private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
+
+  public static io.grpc.ServiceDescriptor getServiceDescriptor() {
+    io.grpc.ServiceDescriptor result = serviceDescriptor;
+    if (result == null) {
+      synchronized (TestDeprecatedServiceGrpc.class) {
+        result = serviceDescriptor;
+        if (result == null) {
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .addMethod(getDeprecatedMethodMethod())
+              .build();
+        }
+      }
+    }
+    return result;
+  }
+}