{{#packageName}}
package {{packageName}};
{{/packageName}}

import static {{packageName}}.{{serviceName}}Grpc.getServiceDescriptor;
import static io.grpc.stub.ServerCalls.asyncUnaryCall;
import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;


{{#deprecated}}
@java.lang.Deprecated
{{/deprecated}}
@javax.annotation.Generated(
value = "by VertxGrpc generator",
comments = "Source: {{protoName}}")
public final class {{className}} {
    private {{className}}() {}

    public static {{serviceName}}VertxStub newVertxStub(io.grpc.Channel channel) {
        return new {{serviceName}}VertxStub(channel);
    }

    {{#javaDoc}}{{{javaDoc}}}{{/javaDoc}}
    public static final class {{serviceName}}VertxStub extends io.grpc.stub.AbstractStub<{{serviceName}}VertxStub> {
        private final io.vertx.core.impl.ContextInternal ctx;
        private {{serviceName}}Grpc.{{serviceName}}Stub delegateStub;

        private {{serviceName}}VertxStub(io.grpc.Channel channel) {
            super(channel);
            delegateStub = {{serviceName}}Grpc.newStub(channel);
            this.ctx = (io.vertx.core.impl.ContextInternal) io.vertx.core.Vertx.currentContext();
        }

        private {{serviceName}}VertxStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
            super(channel, callOptions);
            delegateStub = {{serviceName}}Grpc.newStub(channel).build(channel, callOptions);
            this.ctx = (io.vertx.core.impl.ContextInternal) io.vertx.core.Vertx.currentContext();
        }

        @Override
        protected {{serviceName}}VertxStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
            return new {{serviceName}}VertxStub(channel, callOptions);
        }

        {{#unaryUnaryMethods}}
        {{{methodHeader}}}
        public io.vertx.core.Future<{{outputType}}> {{methodName}}({{inputType}} request) {
            return io.vertx.grpc.stub.ClientCalls.{{vertxCallsMethodName}}(ctx, request, delegateStub::{{methodName}});
        }

        {{/unaryUnaryMethods}}
        {{#unaryManyMethods}}
        {{{methodHeader}}}
        public io.vertx.core.streams.ReadStream<{{outputType}}> {{methodName}}({{inputType}} request) {
            return io.vertx.grpc.stub.ClientCalls.{{vertxCallsMethodName}}(ctx, request, delegateStub::{{methodName}});
        }

        {{/unaryManyMethods}}
        {{#manyUnaryMethods}}
        {{{methodHeader}}}
        public io.vertx.core.Future<{{outputType}}> {{methodName}}(io.vertx.core.Handler<io.vertx.core.streams.WriteStream<{{inputType}}>> hdlr) {
            return io.vertx.grpc.stub.ClientCalls.{{vertxCallsMethodName}}(ctx, hdlr, delegateStub::{{methodName}});
        }

        {{/manyUnaryMethods}}
        {{#manyManyMethods}}
        {{{methodHeader}}}
        public io.vertx.core.streams.ReadStream<{{outputType}}> {{methodName}}(io.vertx.core.Handler<io.vertx.core.streams.WriteStream<{{inputType}}>> hdlr) {
            return io.vertx.grpc.stub.ClientCalls.{{vertxCallsMethodName}}(ctx, hdlr, delegateStub::{{methodName}});
        }
        {{/manyManyMethods}}
    }

    {{#javaDoc}}{{{javaDoc}}}{{/javaDoc}}
    public static abstract class {{serviceName}}VertxImplBase implements io.grpc.BindableService {
        private String compression;

        /**
         * Set whether the server will try to use a compressed response.
         *
         * @param compression the compression, e.g {@code gzip}
         */
        public {{serviceName}}VertxImplBase withCompression(String compression) {
            this.compression = compression;
            return this;
        }

        {{#unaryUnaryMethods}}
        {{{methodHeader}}}
        public io.vertx.core.Future<{{outputType}}> {{methodName}}({{inputType}} request) {
            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }

        {{/unaryUnaryMethods}}
        {{#unaryManyMethods}}
        {{{methodHeader}}}
        public void {{methodName}}({{inputType}} request, io.vertx.core.streams.WriteStream<{{outputType}}> response) {
            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }

        {{/unaryManyMethods}}
        {{#manyUnaryMethods}}
        {{{methodHeader}}}
        public io.vertx.core.Future<{{outputType}}> {{methodName}}(io.vertx.core.streams.ReadStream<{{inputType}}> request) {
            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }

        {{/manyUnaryMethods}}
        {{#manyManyMethods}}
        {{{methodHeader}}}
        public void {{methodName}}(io.vertx.core.streams.ReadStream<{{inputType}}> request, io.vertx.core.streams.WriteStream<{{outputType}}> response) {
            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }

        {{/manyManyMethods}}
        @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
            return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
                    {{#methods}}
                    .addMethod(
                            {{packageName}}.{{serviceName}}Grpc.{{methodNameGetter}}(),
                            {{grpcCallsMethodName}}(
                                    new MethodHandlers<
                                            {{inputType}},
                                            {{outputType}}>(
                                            this, METHODID_{{methodNameUpperUnderscore}}, compression)))
                    {{/methods}}
                    .build();
        }
    }

    {{#methods}}
    private static final int METHODID_{{methodNameUpperUnderscore}} = {{methodNumber}};
    {{/methods}}

    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 {{serviceName}}VertxImplBase serviceImpl;
        private final int methodId;
        private final String compression;

        MethodHandlers({{serviceName}}VertxImplBase serviceImpl, int methodId, String compression) {
            this.serviceImpl = serviceImpl;
            this.methodId = methodId;
            this.compression = compression;
        }

        @java.lang.Override
        @java.lang.SuppressWarnings("unchecked")
        public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
            switch (methodId) {
                {{#methods}}
                {{^isManyInput}}
                case METHODID_{{methodNameUpperUnderscore}}:
                    io.vertx.grpc.stub.ServerCalls.{{vertxCallsMethodName}}(
                            ({{inputType}}) request,
                            (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver,
                            compression,
                            serviceImpl::{{methodName}});
                    break;
                {{/isManyInput}}
                {{/methods}}
                default:
                    throw new java.lang.AssertionError();
            }
        }

        @java.lang.Override
        @java.lang.SuppressWarnings("unchecked")
        public io.grpc.stub.StreamObserver<Req> invoke(io.grpc.stub.StreamObserver<Resp> responseObserver) {
            switch (methodId) {
                {{#methods}}
                {{#isManyInput}}
                case METHODID_{{methodNameUpperUnderscore}}:
                    return (io.grpc.stub.StreamObserver<Req>) io.vertx.grpc.stub.ServerCalls.{{vertxCallsMethodName}}(
                            (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver,
                            compression,
                            serviceImpl::{{methodName}});
                {{/isManyInput}}
                {{/methods}}
                default:
                    throw new java.lang.AssertionError();
            }
        }
    }

}
