// Generated by flatc compiler (version 2.0.0)
// If you make any local changes, they will be lost
// source: monster_test.fbs

package MyGame.Example;

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 com.google.flatbuffers.grpc.FlatbuffersUtils;
import java.nio.ByteBuffer;

/** */
@javax.annotation.Generated(value = "by gRPC proto compiler", comments = "Source: monster_test.fbs")
public final class MonsterStorageGrpc {

  private MonsterStorageGrpc() {}

  public static final String SERVICE_NAME = "MyGame.Example.MonsterStorage";

  // Static method descriptors that strictly reflect the proto.
  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
  @java.lang.Deprecated // Use {@link #getStoreMethod()} instead.
  public static final io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat>
      METHOD_STORE = getStoreMethod();

  private static volatile io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat>
      getStoreMethod;

  private static volatile FlatbuffersUtils.FBExtactor<MyGame.Example.Monster> extractorOfMonster;

  private static FlatbuffersUtils.FBExtactor<MyGame.Example.Monster> getExtractorOfMonster() {
    if (extractorOfMonster != null) return extractorOfMonster;
    synchronized (MonsterStorageGrpc.class) {
      if (extractorOfMonster != null) return extractorOfMonster;
      extractorOfMonster =
          new FlatbuffersUtils.FBExtactor<MyGame.Example.Monster>() {
            public MyGame.Example.Monster extract(ByteBuffer buffer) {
              return MyGame.Example.Monster.getRootAsMonster(buffer);
            }
          };
      return extractorOfMonster;
    }
  }

  private static volatile FlatbuffersUtils.FBExtactor<MyGame.Example.Stat> extractorOfStat;

  private static FlatbuffersUtils.FBExtactor<MyGame.Example.Stat> getExtractorOfStat() {
    if (extractorOfStat != null) return extractorOfStat;
    synchronized (MonsterStorageGrpc.class) {
      if (extractorOfStat != null) return extractorOfStat;
      extractorOfStat =
          new FlatbuffersUtils.FBExtactor<MyGame.Example.Stat>() {
            public MyGame.Example.Stat extract(ByteBuffer buffer) {
              return MyGame.Example.Stat.getRootAsStat(buffer);
            }
          };
      return extractorOfStat;
    }
  }

  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
  public static io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat>
      getStoreMethod() {
    io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat> getStoreMethod;
    if ((getStoreMethod = MonsterStorageGrpc.getStoreMethod) == null) {
      synchronized (MonsterStorageGrpc.class) {
        if ((getStoreMethod = MonsterStorageGrpc.getStoreMethod) == null) {
          MonsterStorageGrpc.getStoreMethod =
              getStoreMethod =
                  io.grpc.MethodDescriptor.<MyGame.Example.Monster, MyGame.Example.Stat>newBuilder()
                      .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
                      .setFullMethodName(
                          generateFullMethodName("MyGame.Example.MonsterStorage", "Store"))
                      .setSampledToLocalTracing(true)
                      .setRequestMarshaller(
                          FlatbuffersUtils.marshaller(
                              MyGame.Example.Monster.class, getExtractorOfMonster()))
                      .setResponseMarshaller(
                          FlatbuffersUtils.marshaller(
                              MyGame.Example.Stat.class, getExtractorOfStat()))
                      .setSchemaDescriptor(null)
                      .build();
        }
      }
    }
    return getStoreMethod;
  }

  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
  @java.lang.Deprecated // Use {@link #getRetrieveMethod()} instead.
  public static final io.grpc.MethodDescriptor<MyGame.Example.Stat, MyGame.Example.Monster>
      METHOD_RETRIEVE = getRetrieveMethod();

  private static volatile io.grpc.MethodDescriptor<MyGame.Example.Stat, MyGame.Example.Monster>
      getRetrieveMethod;

  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
  public static io.grpc.MethodDescriptor<MyGame.Example.Stat, MyGame.Example.Monster>
      getRetrieveMethod() {
    io.grpc.MethodDescriptor<MyGame.Example.Stat, MyGame.Example.Monster> getRetrieveMethod;
    if ((getRetrieveMethod = MonsterStorageGrpc.getRetrieveMethod) == null) {
      synchronized (MonsterStorageGrpc.class) {
        if ((getRetrieveMethod = MonsterStorageGrpc.getRetrieveMethod) == null) {
          MonsterStorageGrpc.getRetrieveMethod =
              getRetrieveMethod =
                  io.grpc.MethodDescriptor.<MyGame.Example.Stat, MyGame.Example.Monster>newBuilder()
                      .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
                      .setFullMethodName(
                          generateFullMethodName("MyGame.Example.MonsterStorage", "Retrieve"))
                      .setSampledToLocalTracing(true)
                      .setRequestMarshaller(
                          FlatbuffersUtils.marshaller(
                              MyGame.Example.Stat.class, getExtractorOfStat()))
                      .setResponseMarshaller(
                          FlatbuffersUtils.marshaller(
                              MyGame.Example.Monster.class, getExtractorOfMonster()))
                      .setSchemaDescriptor(null)
                      .build();
        }
      }
    }
    return getRetrieveMethod;
  }

  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
  @java.lang.Deprecated // Use {@link #getGetMaxHitPointMethod()} instead.
  public static final io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat>
      METHOD_GET_MAX_HIT_POINT = getGetMaxHitPointMethod();

  private static volatile io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat>
      getGetMaxHitPointMethod;

  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
  public static io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat>
      getGetMaxHitPointMethod() {
    io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat> getGetMaxHitPointMethod;
    if ((getGetMaxHitPointMethod = MonsterStorageGrpc.getGetMaxHitPointMethod) == null) {
      synchronized (MonsterStorageGrpc.class) {
        if ((getGetMaxHitPointMethod = MonsterStorageGrpc.getGetMaxHitPointMethod) == null) {
          MonsterStorageGrpc.getGetMaxHitPointMethod =
              getGetMaxHitPointMethod =
                  io.grpc.MethodDescriptor.<MyGame.Example.Monster, MyGame.Example.Stat>newBuilder()
                      .setType(io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING)
                      .setFullMethodName(
                          generateFullMethodName("MyGame.Example.MonsterStorage", "GetMaxHitPoint"))
                      .setSampledToLocalTracing(true)
                      .setRequestMarshaller(
                          FlatbuffersUtils.marshaller(
                              MyGame.Example.Monster.class, getExtractorOfMonster()))
                      .setResponseMarshaller(
                          FlatbuffersUtils.marshaller(
                              MyGame.Example.Stat.class, getExtractorOfStat()))
                      .setSchemaDescriptor(null)
                      .build();
        }
      }
    }
    return getGetMaxHitPointMethod;
  }

  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
  @java.lang.Deprecated // Use {@link #getGetMinMaxHitPointsMethod()} instead.
  public static final io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat>
      METHOD_GET_MIN_MAX_HIT_POINTS = getGetMinMaxHitPointsMethod();

  private static volatile io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat>
      getGetMinMaxHitPointsMethod;

  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
  public static io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat>
      getGetMinMaxHitPointsMethod() {
    io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat>
        getGetMinMaxHitPointsMethod;
    if ((getGetMinMaxHitPointsMethod = MonsterStorageGrpc.getGetMinMaxHitPointsMethod) == null) {
      synchronized (MonsterStorageGrpc.class) {
        if ((getGetMinMaxHitPointsMethod = MonsterStorageGrpc.getGetMinMaxHitPointsMethod)
            == null) {
          MonsterStorageGrpc.getGetMinMaxHitPointsMethod =
              getGetMinMaxHitPointsMethod =
                  io.grpc.MethodDescriptor.<MyGame.Example.Monster, MyGame.Example.Stat>newBuilder()
                      .setType(io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING)
                      .setFullMethodName(
                          generateFullMethodName(
                              "MyGame.Example.MonsterStorage", "GetMinMaxHitPoints"))
                      .setSampledToLocalTracing(true)
                      .setRequestMarshaller(
                          FlatbuffersUtils.marshaller(
                              MyGame.Example.Monster.class, getExtractorOfMonster()))
                      .setResponseMarshaller(
                          FlatbuffersUtils.marshaller(
                              MyGame.Example.Stat.class, getExtractorOfStat()))
                      .setSchemaDescriptor(null)
                      .build();
        }
      }
    }
    return getGetMinMaxHitPointsMethod;
  }

  /** Creates a new async stub that supports all call types for the service */
  public static MonsterStorageStub newStub(io.grpc.Channel channel) {
    return new MonsterStorageStub(channel);
  }

  /**
   * Creates a new blocking-style stub that supports unary and streaming output calls on the service
   */
  public static MonsterStorageBlockingStub newBlockingStub(io.grpc.Channel channel) {
    return new MonsterStorageBlockingStub(channel);
  }

  /** Creates a new ListenableFuture-style stub that supports unary calls on the service */
  public static MonsterStorageFutureStub newFutureStub(io.grpc.Channel channel) {
    return new MonsterStorageFutureStub(channel);
  }

  /** */
  public abstract static class MonsterStorageImplBase implements io.grpc.BindableService {

    /** */
    public void store(
        MyGame.Example.Monster request,
        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver) {
      asyncUnimplementedUnaryCall(getStoreMethod(), responseObserver);
    }

    /** */
    public void retrieve(
        MyGame.Example.Stat request,
        io.grpc.stub.StreamObserver<MyGame.Example.Monster> responseObserver) {
      asyncUnimplementedUnaryCall(getRetrieveMethod(), responseObserver);
    }

    /** */
    public io.grpc.stub.StreamObserver<MyGame.Example.Monster> getMaxHitPoint(
        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver) {
      return asyncUnimplementedStreamingCall(getGetMaxHitPointMethod(), responseObserver);
    }

    /** */
    public io.grpc.stub.StreamObserver<MyGame.Example.Monster> getMinMaxHitPoints(
        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver) {
      return asyncUnimplementedStreamingCall(getGetMinMaxHitPointsMethod(), responseObserver);
    }

    @java.lang.Override
    public final io.grpc.ServerServiceDefinition bindService() {
      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
          .addMethod(
              getStoreMethod(),
              asyncUnaryCall(
                  new MethodHandlers<MyGame.Example.Monster, MyGame.Example.Stat>(
                      this, METHODID_STORE)))
          .addMethod(
              getRetrieveMethod(),
              asyncServerStreamingCall(
                  new MethodHandlers<MyGame.Example.Stat, MyGame.Example.Monster>(
                      this, METHODID_RETRIEVE)))
          .addMethod(
              getGetMaxHitPointMethod(),
              asyncClientStreamingCall(
                  new MethodHandlers<MyGame.Example.Monster, MyGame.Example.Stat>(
                      this, METHODID_GET_MAX_HIT_POINT)))
          .addMethod(
              getGetMinMaxHitPointsMethod(),
              asyncBidiStreamingCall(
                  new MethodHandlers<MyGame.Example.Monster, MyGame.Example.Stat>(
                      this, METHODID_GET_MIN_MAX_HIT_POINTS)))
          .build();
    }
  }

  /** */
  public static final class MonsterStorageStub
      extends io.grpc.stub.AbstractStub<MonsterStorageStub> {
    private MonsterStorageStub(io.grpc.Channel channel) {
      super(channel);
    }

    private MonsterStorageStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
      super(channel, callOptions);
    }

    @java.lang.Override
    protected MonsterStorageStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
      return new MonsterStorageStub(channel, callOptions);
    }

    /** */
    public void store(
        MyGame.Example.Monster request,
        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver) {
      asyncUnaryCall(
          getChannel().newCall(getStoreMethod(), getCallOptions()), request, responseObserver);
    }

    /** */
    public void retrieve(
        MyGame.Example.Stat request,
        io.grpc.stub.StreamObserver<MyGame.Example.Monster> responseObserver) {
      asyncServerStreamingCall(
          getChannel().newCall(getRetrieveMethod(), getCallOptions()), request, responseObserver);
    }

    /** */
    public io.grpc.stub.StreamObserver<MyGame.Example.Monster> getMaxHitPoint(
        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver) {
      return asyncClientStreamingCall(
          getChannel().newCall(getGetMaxHitPointMethod(), getCallOptions()), responseObserver);
    }

    /** */
    public io.grpc.stub.StreamObserver<MyGame.Example.Monster> getMinMaxHitPoints(
        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver) {
      return asyncBidiStreamingCall(
          getChannel().newCall(getGetMinMaxHitPointsMethod(), getCallOptions()), responseObserver);
    }
  }

  /** */
  public static final class MonsterStorageBlockingStub
      extends io.grpc.stub.AbstractStub<MonsterStorageBlockingStub> {
    private MonsterStorageBlockingStub(io.grpc.Channel channel) {
      super(channel);
    }

    private MonsterStorageBlockingStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
      super(channel, callOptions);
    }

    @java.lang.Override
    protected MonsterStorageBlockingStub build(
        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
      return new MonsterStorageBlockingStub(channel, callOptions);
    }

    /** */
    public MyGame.Example.Stat store(MyGame.Example.Monster request) {
      return blockingUnaryCall(getChannel(), getStoreMethod(), getCallOptions(), request);
    }

    /** */
    public java.util.Iterator<MyGame.Example.Monster> retrieve(MyGame.Example.Stat request) {
      return blockingServerStreamingCall(
          getChannel(), getRetrieveMethod(), getCallOptions(), request);
    }
  }

  /** */
  public static final class MonsterStorageFutureStub
      extends io.grpc.stub.AbstractStub<MonsterStorageFutureStub> {
    private MonsterStorageFutureStub(io.grpc.Channel channel) {
      super(channel);
    }

    private MonsterStorageFutureStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
      super(channel, callOptions);
    }

    @java.lang.Override
    protected MonsterStorageFutureStub build(
        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
      return new MonsterStorageFutureStub(channel, callOptions);
    }

    /** */
    public com.google.common.util.concurrent.ListenableFuture<MyGame.Example.Stat> store(
        MyGame.Example.Monster request) {
      return futureUnaryCall(getChannel().newCall(getStoreMethod(), getCallOptions()), request);
    }
  }

  private static final int METHODID_STORE = 0;
  private static final int METHODID_RETRIEVE = 1;
  private static final int METHODID_GET_MIN_MAX_HIT_POINTS = 2;
  private static final int METHODID_GET_MAX_HIT_POINT = 3;

  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 MonsterStorageImplBase serviceImpl;
    private final int methodId;

    MethodHandlers(MonsterStorageImplBase 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_STORE:
          serviceImpl.store(
              (MyGame.Example.Monster) request,
              (io.grpc.stub.StreamObserver<MyGame.Example.Stat>) responseObserver);
          break;
        case METHODID_RETRIEVE:
          serviceImpl.retrieve(
              (MyGame.Example.Stat) request,
              (io.grpc.stub.StreamObserver<MyGame.Example.Monster>) 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) {
        case METHODID_GET_MAX_HIT_POINT:
          return (io.grpc.stub.StreamObserver<Req>)
              serviceImpl.getMaxHitPoint(
                  (io.grpc.stub.StreamObserver<MyGame.Example.Stat>) responseObserver);
        case METHODID_GET_MIN_MAX_HIT_POINTS:
          return (io.grpc.stub.StreamObserver<Req>)
              serviceImpl.getMinMaxHitPoints(
                  (io.grpc.stub.StreamObserver<MyGame.Example.Stat>) responseObserver);
        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 (MonsterStorageGrpc.class) {
        result = serviceDescriptor;
        if (result == null) {
          serviceDescriptor =
              result =
                  io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
                      .setSchemaDescriptor(null)
                      .addMethod(getStoreMethod())
                      .addMethod(getRetrieveMethod())
                      .addMethod(getGetMaxHitPointMethod())
                      .addMethod(getGetMinMaxHitPointsMethod())
                      .build();
        }
      }
    }
    return result;
  }
}
