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

format.scavro.trees.ScavroObjectTree.scala Maven / Gradle / Ivy

There is a newer version: 1.0.0-RC23
Show newest version
package avrohugger
package format
package scavro
package trees

import converters.ScalaConverter

import treehugger.forest._
import definitions._
import treehuggerDSL._

import org.apache.avro.Schema

import scala.collection.JavaConversions._

object ScavroObjectTree {

  // for generating enums
  def toObjectDef(
    classStore: ClassStore, 
    schema: Schema,
    maybeBaseTrait: Option[String],
    maybeFlags: Option[List[Long]]) = {
      
    val objectDef = (maybeBaseTrait, maybeFlags) match {
      case (Some(baseTrait), Some(flags)) =>
        OBJECTDEF(schema.getName)
          .withFlags(flags:_*)
          .withParents("Enumeration")
          .withParents(baseTrait) 
      case (Some (baseTrait), None) => 
        OBJECTDEF(schema.getName)
          .withParents(baseTrait) 
          .withParents("Enumeration")
      case (None, Some(flags)) =>
        OBJECTDEF(schema.getName)
          .withFlags(flags:_*)
          .withParents("Enumeration")
      case (None, None) => 
        OBJECTDEF(schema.getName)
          .withParents("Enumeration")
    }
    
    val objectTree = objectDef := BLOCK(
      TYPEVAR(schema.getName) := REF("Value"),
      VAL(schema.getEnumSymbols.mkString(", ")) := REF("Value")
    )
    
    val treeWithScalaDoc = ScalaDocGen.docToScalaDoc(Left(schema), objectTree)
    treeWithScalaDoc
  }

  // for generating companion objects of case class records 
  def toCompanionDef(
    classStore: ClassStore, 
    schema: Schema,
    ScalaClass: Symbol,
    JavaClass: Symbol,
    typeMatcher: TypeMatcher,
    maybeFlags: Option[List[Long]]) = {

    val AvroMetadata =
      TYPE_REF(REF("AvroMetadata")) APPLYTYPE(ScalaClass, JavaClass)
    val Class =
      TYPE_REF(REF("Class")) APPLYTYPE(JavaClass)
    val AvroReader =
      TYPE_REF(REF("AvroReader")) APPLYTYPE(ScalaClass)
    val toAvroType =
      TYPE_REF(LAMBDA(PARAM("j", JavaClass)) ==> TYPE_REF(ScalaClass))

    val javaClassAccessors: List[Tree] =
      schema.getFields.toList.map(avroField => {
        val nameGet = "get" + avroField.name.head.toUpper + avroField.name.tail
        val getterTree = REF("j") DOT nameGet
        val scalaConverter = new ScalaConverter(typeMatcher)
        scalaConverter.convertFromJava(avroField.schema, getterTree)
      })

    val objectDef = maybeFlags match {
      case Some(flags) => OBJECTDEF(ScalaClass).withFlags(flags:_*)
      case None => OBJECTDEF(ScalaClass)
    }
   
    // adapted from https://github.com/oysterbooks/scavro/blob/code_generation/src/main/scala/oyster/scavro/plugin/ScalaCodegen.scala
    val objectTree = {
      val anonReaderDef = ANONDEF(AvroReader)
      val avroType = TYPE_REF(Class)
      val javaType = TYPE_REF(JavaClass)
      val scalaTypeApplied = TYPE_REF(ScalaClass) APPLY(javaClassAccessors:_*)
      objectDef := BLOCK (
        DEF("reader") withFlags(Flags.IMPLICIT) := NEW(anonReaderDef := BLOCK(
          TYPEVAR("J") withFlags(Flags.OVERRIDE) := REF(JavaClass)
        )),
        VAL("metadata", TYPE_REF(AvroMetadata))
          withFlags(Flags.IMPLICIT) := NEW(ANONDEF(AvroMetadata) := BLOCK(
            VAL("avroClass", avroType) 
              withFlags(Flags.OVERRIDE) := REF("classOf") APPLYTYPE(JavaClass),
            VAL("schema") withFlags(Flags.OVERRIDE) withType("Schema") := 
              javaType DOT "getClassSchema" APPLY(),
            VAL("fromAvro", TYPE_REF(PAREN(javaType)) TYPE_=> ScalaClass)
              withFlags(Flags.OVERRIDE) := BLOCK(
                LAMBDA(PARAM("j", JavaClass)) ==> scalaTypeApplied
              )
          )
        )
      )
    }

    objectTree
  
  }
  
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy