in scio-avro/src/main/scala/com/spotify/scio/avro/types/SchemaProvider.scala [47:105]
override def apply(t: universe.Type): Schema = toSchema(tpe)._1
}
)
}
private def toSchema(tpe: Type): (Schema, Any) = tpe match {
case t if t =:= typeOf[Boolean] =>
(Schema.create(Schema.Type.BOOLEAN), null)
case t if t =:= typeOf[Int] => (Schema.create(Schema.Type.INT), null)
case t if t =:= typeOf[Long] => (Schema.create(Schema.Type.LONG), null)
case t if t =:= typeOf[Float] => (Schema.create(Schema.Type.FLOAT), null)
case t if t =:= typeOf[Double] => (Schema.create(Schema.Type.DOUBLE), null)
case t if t =:= typeOf[String] => (Schema.create(Schema.Type.STRING), null)
case t if t =:= typeOf[ByteString] =>
(Schema.create(Schema.Type.BYTES), null)
case t if t =:= typeOf[Array[Byte]] =>
(Schema.create(Schema.Type.BYTES), null)
case t if t.erasure =:= typeOf[Option[_]].erasure =>
val s = toSchema(t.typeArgs.head)._1
(Schema.createUnion(Schema.create(Schema.Type.NULL), s), JsonProperties.NULL_VALUE)
case t if t.erasure <:< typeOf[scala.collection.Map[String, _]].erasure =>
val s = toSchema(t.typeArgs.tail.head)._1
(Schema.createMap(s), emptyMap())
case t if t.erasure <:< typeOf[List[_]].erasure =>
val s = toSchema(t.typeArgs.head)._1
(Schema.createArray(s), emptyList())
case t if isCaseClass(t) =>
val fields = toFields(t)
val doc = recordDoc(t)
val name = t.typeSymbol.name.toString.split("\\$").head
val pkg = t.typeSymbol.owner.fullName
(Schema.createRecord(name, doc.orNull, pkg, false, fields.asJava), null)
case _ => throw new RuntimeException(s"Unsupported type: $tpe")
}
private def toField(f: (Symbol, Option[String])): Field = {
val (symbol, doc) = f
val name = symbol.name.toString
val tpe = symbol.asMethod.returnType
val (schema, default) = toSchema(tpe)
new Field(name, schema, doc.orNull, default)
}
private def toFields(t: Type): List[Field] =
getFields(t).iterator.map(toField).toList
private def getFields(t: Type): Iterable[(Symbol, Option[String])] =
t.decls.filter(isField) zip fieldDoc(t)
private def recordDoc(t: Type): Option[String] = {
val tpe = "com.spotify.scio.avro.types.doc"
t.typeSymbol.annotations
.find(_.tree.tpe.toString == tpe)
.map { a =>