Tijmen van der Kemp
08/20/2020, 8:22 PMA {
value1
value2
B {
value3
...
}
}
etc, done a million times before.
My task is to create the following: an external party comes in with an XML definition of which entities/values they want to receive, a la GraphQL / ProtoBuf. In addition to this, we need to create "standard" messages with predefined schemas, so not only do the external party give XML, our programmers also need to define some of those messages.
I want to do this last part type safe, so my first thought was a Kotlin DSL. I've got most of it working, it's kind of looking like this:
aScope = scope(AModel) {
addField(AModel.value1)
addEntity(BModel) {
addField(BModel.value3)
}
}
object AModel {
val value1 = field<String>()
val value2 = field<Int>()
}
This all works fine already, but I want it to be type-safe. For example, right now this is legal:
aScope = scope(AModel) {
addField(BModel.value3)
}
To add to the complexity, some entities have common fields, so like a good OO monkey I gave the Model objects abstract superclasses with more fields in them, which is nice, because you can do AModel.commonField and BModel.commonField and they're different unique fields :D
I think to accomplish this, I have to encode the enclosing Model class on a field somehow. Then I could do something like
fun Scope<ModelClass>.addField(field: Field<ModelClass>) { ... }
but I can't figure out how to do this without being extremely verbose like
object AModel {
val value1 = field<AModel, String>()
}
and even then I can't get the common fields to work, because I can't seem to pass the actual Model class upwards to the abstract superclass.
Any advice is welcome, and sorry for the book! Your help is much appreciated!
Kind regards, Tijmen