All Downloads are FREE. Search and download functionalities are using the official Maven repository.

kotlin-gen.0.0.2.source-code.KtStub.mustache Maven / Gradle / Ivy

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

import {{packageName}}.{{serviceName}}Grpc.*

import io.grpc.BindableService
import io.grpc.CallOptions
import io.grpc.Channel
import io.grpc.ServerServiceDefinition
import io.grpc.stub.AbstractStub
import io.grpc.stub.ServerCalls
import io.grpc.stub.StreamObserver

import kotlinx.coroutines.experimental.CompletableDeferred
import kotlinx.coroutines.experimental.Deferred
import kotlinx.coroutines.experimental.channels.LinkedListChannel
import kotlinx.coroutines.experimental.channels.ReceiveChannel
import kotlinx.coroutines.experimental.channels.SendChannel
import kotlinx.coroutines.experimental.launch

{{#deprecated}}@Deprecated("deprecated"){{/deprecated}}
@javax.annotation.Generated(
    value = ["by gRPC Kotlin generator"],
    comments = "Source: {{protoName}}")
object {{className}} {

  /**
   * Creates a new coroutine stub that supports all call types for the service
   */
  @JvmStatic
  fun newStub(channel: Channel): {{serviceName}}KtStub {
    return {{serviceName}}KtStub(channel)
  }

  class {{serviceName}}KtStub : AbstractStub<{{serviceName}}KtStub> {

    private val delegate: {{packageName}}.{{serviceName}}Grpc.{{serviceName}}Stub

    internal constructor(channel: Channel) : super(channel) {
      delegate = {{packageName}}.{{serviceName}}Grpc.newStub(channel)
    }

    internal constructor(channel: Channel, callOptions: CallOptions) : super(channel, callOptions) {
      delegate = {{packageName}}.{{serviceName}}Grpc.newStub(channel).build(channel, callOptions)
    }

    override fun build(channel: Channel, callOptions: CallOptions): {{serviceName}}KtStub {
      return {{serviceName}}KtStub(channel, callOptions)
    }

    {{#methods}}
    {{#javaDoc}}{{{javaDoc}}}{{/javaDoc}}
    {{#deprecated}}@Deprecated("deprecated"){{/deprecated}}
    fun {{methodName}}({{^isManyInput}}request: {{inputType}}{{/isManyInput}})
        : {{^isManyInput}}{{^isManyOutput}}Deferred{{/isManyOutput}}{{#isManyOutput}}ReceiveChannel{{/isManyOutput}}<{{outputType}}>{{/isManyInput}}{{#isManyInput}}ManyTo{{^isManyOutput}}One{{/isManyOutput}}{{#isManyOutput}}Many{{/isManyOutput}}Call<{{inputType}}, {{outputType}}>{{/isManyInput}} {
      {{^isManyOutput}}val responseDeferred = StreamObserverDeferred<{{outputType}}>(){{/isManyOutput}}
      {{#isManyOutput}}val responseChannel = StreamObserverChannel<{{outputType}}>(){{/isManyOutput}}
      {{#isManyInput}}val requestObserver = {{/isManyInput}}delegate.{{methodName}}({{^isManyInput}}request, {{/isManyInput}}response{{^isManyOutput}}Deferred{{/isManyOutput}}{{#isManyOutput}}Channel{{/isManyOutput}})
      {{^isManyInput}}
      return response{{^isManyOutput}}Deferred{{/isManyOutput}}{{#isManyOutput}}Channel{{/isManyOutput}}
      {{/isManyInput}}
      {{#isManyInput}}
      val requestChannel = LinkedListChannel<{{inputType}}>()
      connectChannelToObserver(requestChannel, requestObserver)
      return ManyTo{{^isManyOutput}}One{{/isManyOutput}}{{#isManyOutput}}Many{{/isManyOutput}}Call(requestChannel, response{{^isManyOutput}}Deferred{{/isManyOutput}}{{#isManyOutput}}Channel{{/isManyOutput}})
      {{/isManyInput}}
    }

    {{/methods}}
  }

  {{#javaDoc}}{{{javaDoc}}}{{/javaDoc}}
  abstract class {{serviceName}}ImplBase : BindableService {

    {{#methods}}
    {{#javaDoc}}{{{javaDoc}}}{{/javaDoc}}
    {{#deprecated}}@Deprecated("deprecated"){{/deprecated}}
    open fun {{methodName}}(request{{#isManyInput}}Channel{{/isManyInput}}: {{#isManyInput}}ReceiveChannel<{{inputType}}>{{/isManyInput}}{{^isManyInput}}{{inputType}}{{/isManyInput}}): {{#isManyOutput}}ReceiveChannel{{/isManyOutput}}{{^isManyOutput}}Deferred{{/isManyOutput}}<{{outputType}}> {
      throw io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
    }

    internal fun {{methodName}}Internal({{^isManyInput}}request: {{inputType}}, {{/isManyInput}}responseObserver: StreamObserver<{{outputType}}>){{#isManyInput}}: StreamObserver<{{inputType}}>{{/isManyInput}} {
      {{#isManyInput}}val requestChannel = StreamObserverChannel<{{inputType}}>(){{/isManyInput}}
      val response{{^isManyOutput}}Deferred{{/isManyOutput}}{{#isManyOutput}}Channel{{/isManyOutput}} = {{methodName}}(request{{#isManyInput}}Channel{{/isManyInput}})
      {{#isManyOutput}}connectChannelToObserver(responseChannel, responseObserver){{/isManyOutput}}
      {{^isManyOutput}}connectDeferredToObserver(responseDeferred, responseObserver){{/isManyOutput}}
      {{#isManyInput}}return requestChannel{{/isManyInput}}
    }

    {{/methods}}
    override fun bindService(): ServerServiceDefinition {
      return ServerServiceDefinition.builder(getServiceDescriptor())
          {{#methods}}
          .addMethod(
              get{{methodNamePascalCase}}Method(),
              ServerCalls.{{grpcCallsMethodName}}(
                  MethodHandlers(this, METHODID_{{methodNameUpperUnderscore}})))
          {{/methods}}
          .build();
    }
  }

  private fun  connectChannelToObserver(channel: ReceiveChannel, observer: StreamObserver) {
    // todo: specify coroutine context
    launch {
      try {
        for (value in channel) {
          observer.onNext(value)
        }
        observer.onCompleted()
      } catch (t: Throwable) {
        observer.onError(t)
      }
    }
  }

  private fun  connectDeferredToObserver(deferred: Deferred, observer: StreamObserver) {
    // todo: specify coroutine context
    launch {
      try {
        observer.onNext(deferred.await())
        observer.onCompleted()
      } catch (t: Throwable) {
        observer.onError(t)
      }
    }
  }

  data class ManyToOneCall(
      val request: SendChannel,
      val response: Deferred)

  data class ManyToManyCall(
      val request: SendChannel,
      val response: ReceiveChannel)

  private class StreamObserverDeferred
    : StreamObserver,
      CompletableDeferred by CompletableDeferred() {
    override fun onNext(value: E) { complete(value) }
    override fun onError(t: Throwable) { completeExceptionally(t) }
    override fun onCompleted() { /* nothing */ }
  }

  private class StreamObserverChannel : LinkedListChannel(), StreamObserver {
    override fun onNext(value: E) { offer(value) }
    override fun onError(t: Throwable?) { close(cause = t) }
    override fun onCompleted() { close(cause = null) }
  }

  {{#methods}}
  val METHODID_{{methodNameUpperUnderscore}} = {{methodNumber}};
  {{/methods}}

  private class MethodHandlers internal constructor(
      private val serviceImpl: {{serviceName}}ImplBase,
      private val methodId: Int
  ) : ServerCalls.UnaryMethod,
      ServerCalls.ServerStreamingMethod,
      ServerCalls.ClientStreamingMethod,
      ServerCalls.BidiStreamingMethod {


    @Suppress("UNCHECKED_CAST")
    override fun invoke(request: Req, responseObserver: StreamObserver) {
      when (methodId) {
        {{#methods}}
        {{^isManyInput}}
        METHODID_{{methodNameUpperUnderscore}} ->
            serviceImpl.{{methodName}}Internal(
                request as {{inputType}},
                responseObserver as StreamObserver<{{outputType}}>)
        {{/isManyInput}}
        {{/methods}}
        else -> throw AssertionError()
      }
    }

    @Suppress("UNCHECKED_CAST")
    override fun invoke(responseObserver: StreamObserver): StreamObserver {
      when (methodId) {
        {{#methods}}
        {{#isManyInput}}
        METHODID_{{methodNameUpperUnderscore}} ->
            return serviceImpl.{{methodName}}Internal(
                responseObserver as StreamObserver<{{outputType}}>) as StreamObserver
        {{/isManyInput}}
        {{/methods}}
        else -> throw AssertionError()
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy