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

izumi.idealingua.translator.toprotobuf.ProtobufTranslator.scala Maven / Gradle / Ivy

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

import izumi.idealingua.model.il.ast.typed.TypeDef
import izumi.idealingua.model.il.ast.typed.TypeDef._
import izumi.idealingua.model.problems.IDLException
import izumi.idealingua.model.typespace.Typespace
import izumi.idealingua.translator.CompilerOptions._
import izumi.idealingua.translator.toprotobuf.extensions.ProtobufTranslatorExtension
import izumi.idealingua.translator.toprotobuf.products.RenderableCogenProduct
import izumi.idealingua.translator.{Translated, Translator}

object ProtobufTranslator {
  final val defaultExtensions: Seq[ProtobufTranslatorExtension] = Seq(
  )
}

class ProtobufTranslator(ts: Typespace, options: ProtobufTranslatorOptions) extends Translator {
  protected val ctx: PBTContext = new PBTContext(ts, options.extensions, options.manifest.options)

  def translate(): Translated = {
    val cogenTypes    = translateDefinitions(ctx.typespace.domain.types)
    val cogenServices = ctx.typespace.domain.services.map(ctx.serviceRenderer.defns)
    val cogen         = cogenTypes ++ cogenServices
    val modules       = ctx.modules.toSource(ctx.typespace.domain.id, ctx.modules.toModuleId(ctx.typespace.domain.id), cogen)
    Translated(ts, modules)
  }

  protected def translateDefinitions(definitions: Seq[TypeDef]): Seq[RenderableCogenProduct] = {
    checkEnumScopes(definitions)
    definitions.map {
      case i: Interface =>
        ctx.interfaceRenderer.defns(i)
      case d: DTO =>
        ctx.compositeRenderer.defns(d)
      case i: Enumeration =>
        ctx.enumRenderer.defns(i)
      case i: Identifier =>
        ctx.identifierRenderer.defns(i)
      case d: Adt =>
        ctx.adtRenderer.defns(d)
      case a: Alias =>
        ctx.aliasRenderer.defns(a)
    }
  }

  private def checkEnumScopes(definitions: Seq[TypeDef]): Unit = {
    val m = definitions.collect { case i: Enumeration => i }.map {
      e =>
        e.id.name -> e.members.map(_.value).toSet
    }
    m.foreach {
      case (name, members) =>
        m.foreach {
          case (name1, members1) if name1 != name =>
            val intersect = members1.intersect(members)
            if (intersect.nonEmpty) {
              throw new IDLException(
                s"[${ctx.typespace.domain.id}]: Protobuf can not generate ENUMs with same internals under one domain. $name1 and $name contains same elements: ${intersect
                    .mkString(",")}"
              )
            }
          case _ =>
        }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy