[Fix] Don't generate oneof encoders if the proto doesn't contain the oneofs member variable

This commit is contained in:
hartie95 2024-08-26 01:54:35 +02:00
parent c2d036b62f
commit 6957fb67e1

View File

@ -38,15 +38,15 @@ open class DataGenerator(
}
override fun addBody(file: OutputStream, classInfo: ClassInfo) {
classInfo.oneOfs.values.forEach {
logger.info("OneOf: ${it}")
val oneOfClasses = it.oneOfTypes.mapNotNull { classInfoCache[it] }
classInfo.oneOfs.values.forEach { oneOfData ->
logger.info("OneOf: $oneOfData")
val oneOfClasses = oneOfData.oneOfTypes.mapNotNull { classInfoCache[it] }
// TODO OneOfEntry handling with name mapping
val oneOfClassMap = it.oneOfClassMap.mapNotNull { classInfoCache[it.value]?.let { value -> it.key to value } }.toMap()
val oneOfClassMap = oneOfData.oneOfClassMap.mapNotNull { classInfoCache[it.value]?.let { value -> it.key to value } }.toMap()
//file.id(4) +="public sealed class ${it.wrapperName}<T: ProtoModel>(val value: T) : ProtoModel {\n"
file.id(4) +="public sealed class ${it.wrapperName}<T>(val value: T) : ProtoModel {\n"
file.id(8) +="public class ${it.unknownName}() : ${it.wrapperName}<UnknownModel>(UnknownModel())\n"
file.id(4) +="public sealed class ${oneOfData.wrapperName}<T>(val value: T) : ProtoModel {\n"
file.id(8) +="public class ${oneOfData.unknownName}() : ${oneOfData.wrapperName}<UnknownModel>(UnknownModel())\n"
file.id(8) +="public class UnknownModel() : ProtoModel{\n"
file.id(12) +="override fun encodeToByteArray(version: $VERSION_ENUM_CLASS): ByteArray? = null\n"
file.id(8) +="}\n"
@ -58,20 +58,26 @@ open class DataGenerator(
file.id(12) +="}\n"
file.id(8) +="}\n"
oneOfClassMap.forEach { name, oneOfClass ->
val className = if(it.allowTypeBasedMapping) oneOfClass.name else name.getClassName()
file.id(8) +="public class ${className}(value:${oneOfClass.packageName}.${oneOfClass.name}) : ${it.wrapperName}<${oneOfClass.packageName}.${oneOfClass.name}>(value)\n"
val className = if(oneOfData.allowTypeBasedMapping) oneOfClass.name else name.getClassName()
file.id(8) +="public class ${className}(value:${oneOfClass.packageName}.${oneOfClass.name}) : ${oneOfData.wrapperName}<${oneOfClass.packageName}.${oneOfClass.name}>(value)\n"
}
classInfo.protoSet.forEach { protoData ->
classInfo.protoSet.forEach protoSetFor@{ protoData ->
// check that the oneOf variable is actually part of the proto
if(protoData.members.values.none { it.isPrimaryConstructorMember && it.name.equals(oneOfData.variableName, true) }) {
return@protoSetFor
}
val functionName = protoData.encodeFunctionName
file.id(8) += "internal fun $functionName() : ${protoData.absoluteClassName}.${it.wrapperName}<*>? {\n"
file.id(8) += "internal fun $functionName() : ${protoData.absoluteClassName}.${oneOfData.wrapperName}<*>? {\n"
file.id(12) +="return when (this) {\n"
oneOfClassMap.forEach { fieldName, oneOfClass ->
val className = if(it.allowTypeBasedMapping) oneOfClass.name else fieldName.getClassName()
val className = if(oneOfData.allowTypeBasedMapping) oneOfClass.name else fieldName.getClassName()
protoData.members.forEach { member ->
if(member.value.type.starProjection().declaration.simpleName.asString().equals(oneOfClass.name, true) && compareIgnoreCase(member.key, fieldName)) {
val accessor = if(oneOfClass.isProtoModel) "value.${functionName}()" else "value"
file.id(16) += "is ${className} -> $accessor.let {\n"
file.id(20) += "${protoData.packageName}.${protoData.className}.${it.wrapperName}.${member.value.name.capitalizeFirstLetter()}(it)\n"
file.id(20) += "${protoData.packageName}.${protoData.className}.${oneOfData.wrapperName}.${member.value.name.capitalizeFirstLetter()}(it)\n"
file.id(16) += "}\n"
}
}
@ -81,22 +87,28 @@ open class DataGenerator(
file.id(8)+="}\n"
}
file.id(8) += "public companion object {\n"
classInfo.protoSet.forEach { protoData ->
classInfo.protoSet.forEach protoSetFor@{ protoData ->
// check that the oneOf variable is actually part of the proto
if(protoData.members.values.none { it.isPrimaryConstructorMember && it.name.equals(oneOfData.variableName, true) }) {
return@protoSetFor
}
val functionName = protoData.parseFunctionName
file.id(12) += "internal fun $functionName(value: ${protoData.absoluteClassName}.${it.wrapperName}<*>) : ${it.wrapperName}<*>? {\n"
file.id(12) += "internal fun $functionName(value: ${protoData.absoluteClassName}.${oneOfData.wrapperName}<*>) : ${oneOfData.wrapperName}<*>? {\n"
file.id(16) +="return when (value) {\n"
oneOfClassMap.forEach { fieldName, oneOfClass ->
protoData.members.forEach { member ->
val className = if(it.allowTypeBasedMapping) oneOfClass.name else fieldName.getClassName()
if(member.value.type.starProjection().declaration.simpleName.asString().equals(oneOfClass.name, true) && compareIgnoreCase(member.key, fieldName)) {
val className = if(oneOfData.allowTypeBasedMapping) oneOfClass.name else fieldName.getClassName()
if(member.value.type.starProjection().declaration.simpleName.asString().equals(oneOfClass.name, true) &&
compareIgnoreCase(member.key, fieldName) && member.value.isPrimaryConstructorMember) {
val accessor = if(oneOfClass.isProtoModel) "${oneOfClass.packageName}.${oneOfClass.name}.${protoData.parseFunctionName}(value.value)" else "value.value"
file.id(20) += "is ${protoData.packageName}.${protoData.className}.${it.wrapperName}.${member.value.name.capitalizeFirstLetter()} -> \n"
file.id(20) += "is ${protoData.packageName}.${protoData.className}.${oneOfData.wrapperName}.${member.value.name.capitalizeFirstLetter()} -> \n"
//file.id(24) += "${className}(${oneOfClass.packageName}.${oneOfClass.name}.${protoData.parseFunctionName}(value.value))\n"
file.id(24) += "${className}($accessor)\n"
}
}
}
file.id(20) +="else -> ${it.unknownName}()\n"
file.id(20) +="else -> ${oneOfData.unknownName}()\n"
file.id(16) +="}\n"
file.id(12)+="}\n"
}