override def apply()

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 =>