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

izumi.idealingua.translator.toscala.ServiceRenderer.scala Maven / Gradle / Ivy

The newest version!
package izumi.idealingua.translator.toscala

import _root_.io.circe.{DecodingFailure, Json}
import izumi.functional.bio.IO2
import izumi.idealingua.model.il.ast.typed.DefMethod.RPCMethod
import izumi.idealingua.model.il.ast.typed.Service
import izumi.idealingua.translator.toscala.products.CogenProduct.CogenServiceProduct
import izumi.idealingua.translator.toscala.products.RenderableCogenProduct
import izumi.idealingua.translator.toscala.types.{runtime, _}

import scala.meta._

class ServiceRenderer(ctx: STContext) {

  import ctx._

  def renderService(svc: Service): RenderableCogenProduct = {
    val c = ServiceContext(ctx, svc)

    val decls = svc.methods.collect { case c: RPCMethod => c }
      .map(ServiceMethodProduct(ctx, c, _))

    val qqServer =
      q"""trait ${c.svcServerTpe.typeName}[Or[+_, +_], ${c.Ctx.p}] {
            type Just[+T] = Or[Nothing, T]
            ..${decls.map(_.defnServer)}
          }"""

    val qqClient =
      q"""trait ${c.svcClientTpe.typeName}[Or[+_, +_]] {
            type Just[+T] = Or[Nothing, T]
            ..${decls.map(_.defnClient)}
          }"""

    val qqClientWrapped =
      q"""class ${c.svcWrappedClientTpe.typeName}[Or[+_, +_] : IRTIO2](_dispatcher: ${rt.IRTDispatcher.parameterize(List(c.F.t)).typeFull})
               extends ${c.svcClientTpe.parameterize(List(c.F.t)).init()} {
               final val _F: IRTIO2[${c.F.t}] =  implicitly
               ${c.methodImport}

               ..${decls.map(_.defnClientWrapped)}
          }"""

    val qqClientWrappedCompanion =
      q"""
         object ${c.svcWrappedClientTpe.termName} extends ${rt.IRTWrappedClient.init()} {
           val allCodecs: Map[${rt.IRTMethodId.typeName}, IRTCirceMarshaller] = {
             Map(..${decls.map(_.defnCodecRegistration)})
           }
         }
       """

    val qqServerWrapped =
      q"""class ${c.svcWrappedServerTpe.typeName}[Or[+_, +_] : IRTIO2, ${c.Ctx.p}](
              _service: ${c.svcServerTpe.typeName}[${c.F.t}, ${c.Ctx.t}]
            )
               extends IRTWrappedService[${c.F.t}, ${c.Ctx.t}] {
            final val _F: IRTIO2[${c.F.t}] = implicitly

            final val serviceId: ${rt.IRTServiceId.typeName} = ${c.svcMethods.termName}.serviceId

            val allMethods: Map[${rt.IRTMethodId.typeName}, IRTMethodWrapper[${c.F.t}, ${c.Ctx.t}]] = {
              Seq[IRTMethodWrapper[${c.F.t}, ${c.Ctx.t}]](..${decls.map(_.defnMethodRegistration)})
                .map(m => m.signature.id -> m)
                .toMap
            }

            ..${decls.map(_.defnServerWrapped)}
          }"""

    val qqServerWrappedCompanion =
      q"""
         object ${c.svcWrappedServerTpe.termName} {
         }
       """

    val qqServiceMethods =
      q"""
         object ${c.svcMethods.termName} {
           final val serviceId: ${rt.IRTServiceId.typeName} = ${rt.IRTServiceId.termName}(${Lit.String(c.typeName)})

           ..${decls.map(_.defnMethod)}
           ..${decls.flatMap(_.defStructs)}
         }
       """

    val qqServiceCodecs =
      q"""
         object ${c.svcCodecs.termName} {
          ..${decls.map(_.defnCodec)}
         }
       """

    val out = CogenServiceProduct(
      qqServer,
      qqClient,
      CogenServiceProduct.Pair(qqServerWrapped, qqServerWrappedCompanion),
      CogenServiceProduct.Pair(qqClientWrapped, qqClientWrappedCompanion),
      qqServiceMethods,
      qqServiceCodecs,
      List(
        runtime.Import.from(runtime.Pkg.language, "higherKinds"),
        runtime.Import.from(runtime.Pkg.of[IO2[Nothing]], "IO2", Some("IRTIO2")),
        runtime.Import[Json](Some("IRTJson")),
        runtime.Import[DecodingFailure](Some("IRTDecodingFailure")),
        runtime.Pkg.of[_root_.io.circe.syntax.EncoderOps[Nothing]].`import`,
        rt.services.`import`,
      ),
    )

    ext.extend(FullServiceContext(c, decls), out, _.handleService)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy