Progress on native generator

This commit is contained in:
Ugljesa Jovanovic authored and Ugljesa Jovanovic committed 2020-08-01 18:07:12 +02:00
1 parent c975bdb248
commit 97c631ecb7
10 files changed
+371 -49

No files matched your search

@@ -72,10 +72,12 @@ data class CustomTypeDefinition(override val typeName: TypeName) : GeneralTypeDe
enum class TypeDefinition(override val typeName: TypeName) : GeneralTypeDefinition {
ARRAY_OF_UBYTES(UByteArray::class.asTypeName()),
ARRAY_OF_UBYTES_LONG_SIZE(UByteArray::class.asTypeName()),
ARRAY_OF_UBYTES_NO_SIZE(UByteArray::class.asTypeName()),
LONG(Long::class.asTypeName()),
INT(Int::class.asTypeName()),
STRING(String::class.asTypeName())
STRING(String::class.asTypeName()),
UNIT(Unit::class.asTypeName())
}
fun fileDef(name: String, body: KotlinFileDefinition.() -> Unit) : KotlinFileDefinition {
@@ -132,33 +134,4 @@ fun funcDef(
}
object LibSodiumDefinitions {
val testKotlinFile = fileDef("DebugTest") {
+classDef("Hashing") {
+innerClassDef(
"Sha256State",
"com.goterl.lazycode.lazysodium.interfaces.Hash.State256",
"Sha256State",
"crypto_hash_sha256_state"
)
+funcDef(
"crypto_hash_sha256_init",
TypeDefinition.INT
) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha256State"))))
}
}
+classDef("GenericHash") {
+funcDef(
"crypto_generichash_init",
TypeDefinition.INT
) {
+ParameterDefinition("state", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE)
+ParameterDefinition("key", TypeDefinition.ARRAY_OF_UBYTES)
+ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturn = true)
}
}
}
}
@@ -0,0 +1,89 @@
package com.ionspin.kotlin.crypto.generator.libsodium.definitions
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 01-Aug-2020
*/
object LibSodiumDefinitions {
val testKotlinFile = fileDef("DebugTest") {
+classDef("Crypto") {
/*
--------------- SHA256
*/
+innerClassDef(
"Sha256State",
"com.goterl.lazycode.lazysodium.interfaces.Hash.State256",
"Sha256State",
"crypto_hash_sha256_state"
)
+funcDef(
"crypto_hash_sha256_init",
TypeDefinition.INT
) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha256State"))))
}
+funcDef("crypto_hash_sha256_update", TypeDefinition.UNIT) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha256State"))))
+ParameterDefinition("input", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE)
}
+funcDef("crypto_hash_sha256_final", TypeDefinition.UNIT) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha256State"))))
+ParameterDefinition("out", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE)
}
/*
--------------- SHA512
*/
+innerClassDef(
"Sha512State",
"com.goterl.lazycode.lazysodium.interfaces.Hash.State512",
"Sha512State",
"crypto_hash_sha512_state"
)
+funcDef(
"crypto_hash_sha512_init",
TypeDefinition.INT
) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State"))))
}
+funcDef("crypto_hash_sha512_update", TypeDefinition.UNIT) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State"))))
+ParameterDefinition("input", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE)
}
+funcDef("crypto_hash_sha512_final", TypeDefinition.UNIT) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State"))))
+ParameterDefinition("out", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE)
}
/*
* ------------- GENERIC HASH (BLAKE2B)
*/
+innerClassDef(
"GenericHashState",
"ByteArray",
"Uint8Array",
"crypto_generichash_blake2b_state"
)
+funcDef(
"crypto_generichash_init",
TypeDefinition.INT
) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("GenericHashState"))))
+ParameterDefinition("key", TypeDefinition.ARRAY_OF_UBYTES)
+ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturn = true)
}
}
}
}
@@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.generator.libsodium.generator
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.LibSodiumDefinitions
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.packageName
import java.io.File
/**
@@ -10,12 +11,16 @@ import java.io.File
*/
object Coordinator {
fun run(packageName: String) {
fun run() {
val commonFileSpec = CommonLibsodiumGenerator.createCommonFile(packageName, LibSodiumDefinitions.testKotlinFile)
val jvmFileSpec = JvmLibsodiumGenerator.createJvmFile(packageName, LibSodiumDefinitions.testKotlinFile)
val nativeFileSpec = NativeLibsodiumGenerator.createNativeFile(packageName, LibSodiumDefinitions.testKotlinFile)
val commonFile = File("multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/")
commonFileSpec.writeTo(commonFile)
val jvmFile = File("multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/")
jvmFileSpec.writeTo(jvmFile)
val nativeFile = File("multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/")
nativeFileSpec.writeTo(nativeFile)
}
}
@@ -61,6 +61,7 @@ object JvmLibsodiumGenerator {
returnModifierName = paramDefinition.parameterName
}
}
if (methodDefinition.returnType == TypeDefinition.ARRAY_OF_UBYTES) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
@@ -79,6 +80,15 @@ object JvmLibsodiumGenerator {
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType == TypeDefinition.UNIT) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("sodium.${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType is CustomTypeDefinition) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
@@ -107,7 +117,10 @@ object JvmLibsodiumGenerator {
if (paramDefinition.parameterType is TypeDefinition) {
when(paramDefinition.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES -> {
paramsBuilder.append(paramDefinition.parameterName + ".asByteArray()" + separator + paramDefinition.parameterName + ".size, ")
paramsBuilder.append(paramDefinition.parameterName + ".asByteArray(), " + paramDefinition.parameterName + ".size" + separator)
}
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
paramsBuilder.append(paramDefinition.parameterName + ".asByteArray(), " + paramDefinition.parameterName + ".size.toLong()" + separator)
}
TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> {
paramsBuilder.append(paramDefinition.parameterName + ".asByteArray()" + separator)
@@ -0,0 +1,150 @@
package com.ionspin.kotlin.crypto.generator.libsodium.generator
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.*
import com.squareup.kotlinpoet.*
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 31-Jul-2020
*/
object NativeLibsodiumGenerator {
fun createNativeFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec {
val fileBuilder = FileSpec.builder(packageName, fileDefinition.name)
fileBuilder.addImport("kotlinx.cinterop", "toCValues")
fileBuilder.addImport("kotlinx.cinterop", "convert")
fileBuilder.addImport("kotlinx.cinterop", "ptr")
// val sodiumProperty = PropertySpec.builder("sodium", ClassName.bestGuess("com.goterl.lazycode.lazysodium.SodiumJava"))
// sodiumProperty.initializer(CodeBlock.of("SodiumJava()"))
// fileBuilder.addProperty(sodiumProperty.build())
for (commonClassDefinition in fileDefinition.commonClassList) {
//Create type-aliases
commonClassDefinition.innerClasses.forEach {
fileBuilder.addTypeAlias(createJvmInnerClassSpec(it, MultiplatformModifier.ACTUAL))
}
val commonClassSpec = createClass(
commonClassDefinition,
MultiplatformModifier.ACTUAL,
::createNativeFunctionImplementation
)
fileBuilder.addType(commonClassSpec)
}
val file = fileBuilder.build()
file.writeTo(System.out)
return file
}
fun createJvmInnerClassSpec(
innerClassDefinition: InnerClassDefinition,
multiplatformModifier: MultiplatformModifier
): TypeAliasSpec {
val innerClassBuilder =
TypeAliasSpec.builder(innerClassDefinition.name, ClassName("libsodium", innerClassDefinition.nativeName))
innerClassBuilder.modifiers += multiplatformModifier.modifierList
return innerClassBuilder.build()
}
fun createNativeFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec {
val methodBuilder = FunSpec.builder(methodDefinition.name)
methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList
var returnModifierFound = false
var returnModifierName = ""
for (paramDefinition in methodDefinition.parameterList) {
val parameterSpec =
ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName)
methodBuilder.addParameter(parameterSpec.build())
if (paramDefinition.modifiesReturn) {
if (returnModifierFound == true) {
throw RuntimeException("Return modifier already found")
}
returnModifierFound = true
returnModifierName = paramDefinition.parameterName
}
}
if (methodDefinition.returnType == TypeDefinition.ARRAY_OF_UBYTES) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return libsodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType == TypeDefinition.INT) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return libsodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType == TypeDefinition.UNIT) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("libsodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType is CustomTypeDefinition) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return libsodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
methodBuilder.returns(methodDefinition.returnType.typeName)
return methodBuilder.build()
}
fun paramsToString(methodDefinition: FunctionDefinition): String {
val paramsBuilder = StringBuilder()
paramsBuilder.append("(")
methodDefinition.parameterList.forEachIndexed { index, paramDefinition ->
val separator = if (index == methodDefinition.parameterList.size - 1) {
""
} else {
", "
}
if (paramDefinition.parameterType is CustomTypeDefinition) {
paramsBuilder.append(paramDefinition.parameterName + ".ptr" + separator)
}
if (paramDefinition.parameterType is TypeDefinition) {
when (paramDefinition.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES -> {
paramsBuilder.append(paramDefinition.parameterName + ".toCValues(), " + paramDefinition.parameterName + ".size.convert()" + separator)
}
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
paramsBuilder.append(paramDefinition.parameterName + ".toCValues(), " + paramDefinition.parameterName + ".size.convert()" + separator)
}
TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> {
paramsBuilder.append(paramDefinition.parameterName + ".toCValues()" + separator)
}
TypeDefinition.LONG -> {
paramsBuilder.append(paramDefinition.parameterName + ".convert()" + separator)
}
TypeDefinition.INT -> {
paramsBuilder.append(paramDefinition.parameterName + ".convert()" + separator)
}
TypeDefinition.STRING -> {
paramsBuilder.append(paramDefinition.parameterName + separator)
}
}
}
}
paramsBuilder.append(')')
return paramsBuilder.toString()
}
}
@@ -11,9 +11,8 @@ import org.junit.Test
* on 31-Jul-2020
*/
class DebugTest {
val packageName = "debug.test"
@Test
fun debugTest() {
Coordinator.run(packageName)
Coordinator.run()
}
}