Skip to content

Commit

Permalink
Pre-generate encoders in RecordEncoderGenerator
Browse files Browse the repository at this point in the history
  • Loading branch information
sksamuel committed Apr 28, 2024
1 parent 6a8bc5d commit 742951b
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,31 @@ class RecordEncoderGenerator {
appendLine(" * This is a generated [Encoder] that encodes [${kclass.java.simpleName}]s to Avro [GenericRecord]s")
appendLine(" */")
appendLine("object ${kclass.java.simpleName}Encoder : Encoder<${kclass.java.simpleName}> {")
appendLine()
kclass.declaredMemberProperties.forEach { property ->
appendLine(" private val ${property.name}Encoder = ${encoderVal(property)}")
}
appendLine()
appendLine(" override fun encode(schema: Schema, value: ${kclass.java.simpleName}): GenericRecord {")
appendLine(" val record = GenericData.Record(schema)")
kclass.declaredMemberProperties.forEach { property ->
appendLine(" record.put(\"${property.name}\", ${encoderFor(property)})")
appendLine(" record.put(\"${property.name}\", ${encoderInvocation(property)})")
}
appendLine(" return record")
appendLine(" }")
appendLine("}")
}
}

private fun encoderFor(property: KProperty1<out Any, *>): String {
private fun encoderVal(property: KProperty1<out Any, *>): String {
val baseEncoder = encoderFor(property.returnType)
return if (property.returnType.isMarkedNullable) "NullEncoder($baseEncoder)" else baseEncoder
}

private fun encoderInvocation(property: KProperty1<out Any, *>): String {
val getSchema = "schema.getField(\"${property.name}\").schema()"
val getValue = "value.${property.name}"
val baseEncoder = encoderFor(property.returnType)
val encoder = if (property.returnType.isMarkedNullable) "NullEncoder($baseEncoder)" else baseEncoder
return "$encoder.encode($getSchema, $getValue)"
return "${property.name}Encoder.encode($getSchema, $getValue)"
}

private fun encoderFor(type: KType): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class Serde<T : Any>(
): Serde<T> {
val schema = ReflectionSchemaBuilder(true).schema(kclass)
val encoder = SpecificRecordEncoder(kclass, schema)
val decoder = SpecificRecordDecoder(kclass, schema)
val decoder: SpecificRecordDecoder<T> = SpecificRecordDecoder(kclass, schema)
return Serde(schema, encoder, decoder, options)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,28 @@ import org.apache.avro.generic.GenericRecord
* This is a generated [Encoder] that encodes [MyFoo]s to Avro [GenericRecord]s
*/
object MyFooEncoder : Encoder<MyFoo> {
private val bEncoder = BooleanEncoder
private val cEncoder = LongEncoder
private val listsEncoder = ListEncoder(IntEncoder)
private val mapsEncoder = MapEncoder(StringEncoder, DoubleEncoder)
private val sEncoder = NullEncoder(StringEncoder)
private val setsEncoder = SetEncoder(StringEncoder)
private val wineEncoder = NullEncoder(EnumEncoder())
override fun encode(schema: Schema, value: MyFoo): GenericRecord {
val record = GenericData.Record(schema)
record.put("b", BooleanEncoder.encode(schema.getField("b").schema(), value.b))
record.put("c", LongEncoder.encode(schema.getField("c").schema(), value.c))
record.put("lists", ListEncoder(IntEncoder).encode(schema.getField("lists").schema(), value.lists))
record.put("maps", MapEncoder(StringEncoder, DoubleEncoder).encode(schema.getField("maps").schema(), value.maps))
record.put("s", NullEncoder(StringEncoder).encode(schema.getField("s").schema(), value.s))
record.put("sets", SetEncoder(StringEncoder).encode(schema.getField("sets").schema(), value.sets))
record.put("wine", NullEncoder(EnumEncoder()).encode(schema.getField("wine").schema(), value.wine))
record.put("b", bEncoder.encode(schema.getField("b").schema(), value.b))
record.put("c", cEncoder.encode(schema.getField("c").schema(), value.c))
record.put("lists", listsEncoder.encode(schema.getField("lists").schema(), value.lists))
record.put("maps", mapsEncoder.encode(schema.getField("maps").schema(), value.maps))
record.put("s", sEncoder.encode(schema.getField("s").schema(), value.s))
record.put("sets", setsEncoder.encode(schema.getField("sets").schema(), value.sets))
record.put("wine", wineEncoder.encode(schema.getField("wine").schema(), value.wine))
return record
}
}
""".trim()
}

})


0 comments on commit 742951b

Please sign in to comment.