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.26.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(SERVICE_NAME, "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;
  }
}
