This commit is contained in:
Ugljesa Jovanovic 2020-07-31 17:37:49 +02:00 committed by Ugljesa Jovanovic
parent 53325cdba6
commit c5082a0f47
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
8 changed files with 226 additions and 33 deletions

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.generator.libsodium.definitions
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.TypeName
import com.squareup.kotlinpoet.asTypeName
@ -46,7 +47,7 @@ class FunctionDefinition(
val jsName: String,
val nativeName: String,
val parameterList: MutableList<ParameterDefinition> = mutableListOf(),
val returnType: TypeDefinition
val returnType: GeneralTypeDefinition
) {
operator fun ParameterDefinition.unaryPlus() {
parameterList.add(this)
@ -55,11 +56,19 @@ class FunctionDefinition(
class ParameterDefinition(
val parameterName: String,
val parameterType: TypeDefinition
val parameterType: GeneralTypeDefinition,
val modifiesReturn: Boolean = false
)
enum class TypeDefinition(val typeName: TypeName) {
interface GeneralTypeDefinition {
val typeName : TypeName
}
data class CustomTypeDefinition(override val typeName: TypeName) : GeneralTypeDefinition
enum class TypeDefinition(override val typeName: TypeName) : GeneralTypeDefinition {
ARRAY_OF_UBYTES(UByteArray::class.asTypeName()),
ARRAY_OF_UBYTES_NO_SIZE(UByteArray::class.asTypeName()),
LONG(Long::class.asTypeName()),
INT(Int::class.asTypeName()),
STRING(String::class.asTypeName())
@ -100,7 +109,8 @@ fun funcDef(
javaName: String,
jsName: String,
nativeName: String,
returnType: TypeDefinition, body: FunctionDefinition.() -> Unit
returnType: GeneralTypeDefinition,
body: FunctionDefinition.() -> Unit
): FunctionDefinition {
val function = FunctionDefinition(name, javaName, jsName, nativeName, returnType = returnType)
function.body()
@ -109,20 +119,37 @@ fun funcDef(
object LibSodiumDefinitions {
val testKotlinFile = fileDef("Test.kt") {
val testKotlinFile = fileDef("DebugTest") {
+classDef("Hashing") {
+innerClassDef(
"Sha256State",
"Hash.State256",
"com.goterl.lazycode.lazysodium.interfaces.Hash.State256",
"Sha256State",
"crypto_hash_sha256_state"
)
+funcDef(
"test", "test", "test", "test", TypeDefinition.ARRAY_OF_UBYTES
"init",
"crypto_hash_sha256_init",
"crypto_hash_sha256_init",
"crypto_hash_sha256_init",
TypeDefinition.INT
) {
+ParameterDefinition("first", TypeDefinition.ARRAY_OF_UBYTES)
+ParameterDefinition("second", TypeDefinition.LONG)
+ParameterDefinition("third", TypeDefinition.STRING)
+ParameterDefinition("state", CustomTypeDefinition(ClassName.bestGuess("Sha256State")))
}
}
+classDef("GenericHash") {
+funcDef(
"init",
"crypto_generichash_init",
"crypto_generichash_init",
"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)
}
}
}

View File

@ -1,7 +1,7 @@
package com.ionspin.kotlin.crypto.generator.libsodium.generator
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ClassDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition
import com.squareup.kotlinpoet.*
@ -11,7 +11,7 @@ import com.squareup.kotlinpoet.*
* on 31-Jul-2020
*/
enum class MultiplatformModifier(val modifierList : List<KModifier>) {
enum class MultiplatformModifier(val modifierList: List<KModifier>) {
EXPECT(listOf(KModifier.EXPECT)),
ACTUAL(listOf(KModifier.ACTUAL)),
NONE(listOf())
@ -22,8 +22,16 @@ object CommonLibsodiumGenerator {
fun createCommonFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec {
val fileBuilder = FileSpec.builder(packageName, fileDefinition.name)
for (commonClassDefinition in fileDefinition.commonClassList) {
//Create expected inner classes that will be represented by type-aliases
commonClassDefinition.innerClasses.forEach {
fileBuilder.addType(createCommonInnerClassSpec(it, MultiplatformModifier.EXPECT))
}
val commonClassSpec =
createClass(commonClassDefinition, MultiplatformModifier.EXPECT, ::createCommonMethodSpec)
createClass(
commonClassDefinition,
MultiplatformModifier.EXPECT,
::createCommonMethodSpec
)
fileBuilder.addType(commonClassSpec)
}
val file = fileBuilder.build()
@ -31,6 +39,16 @@ object CommonLibsodiumGenerator {
return file
}
fun createCommonInnerClassSpec(
innerClassDefinition: InnerClassDefinition,
multiplatformModifier: MultiplatformModifier
): TypeSpec {
val innerClassBuilder = TypeSpec.classBuilder(innerClassDefinition.name)
innerClassBuilder.modifiers += multiplatformModifier.modifierList
return innerClassBuilder.build()
}
fun createCommonMethodSpec(methodDefinition: FunctionDefinition): FunSpec {
val methodBuilder = FunSpec.builder(methodDefinition.name)
for (paramDefinition in methodDefinition.parameterList) {

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.generator.libsodium.generator
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.LibSodiumDefinitions
import java.io.File
/**
* Created by Ugljesa Jovanovic
@ -10,7 +11,11 @@ import com.ionspin.kotlin.crypto.generator.libsodium.definitions.LibSodiumDefini
object Coordinator {
fun run(packageName: String) {
CommonLibsodiumGenerator.createCommonFile(packageName, LibSodiumDefinitions.testKotlinFile)
JvmLibsodiumGenerator.createJvmFile(packageName, LibSodiumDefinitions.testKotlinFile)
val commonFileSpec = CommonLibsodiumGenerator.createCommonFile(packageName, LibSodiumDefinitions.testKotlinFile)
val jvmFileSpec = JvmLibsodiumGenerator.createJvmFile(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)
}
}

View File

@ -1,10 +1,7 @@
package com.ionspin.kotlin.crypto.generator.libsodium.generator
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.ParameterSpec
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.*
import com.squareup.kotlinpoet.*
/**
* Created by Ugljesa Jovanovic
@ -14,10 +11,22 @@ import com.squareup.kotlinpoet.ParameterSpec
object JvmLibsodiumGenerator {
fun createJvmFile(packageName: String, fileDefinition: KotlinFileDefinition) : FileSpec {
fun createJvmFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec {
val fileBuilder = FileSpec.builder(packageName, fileDefinition.name)
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) {
val commonClassSpec = createClass(commonClassDefinition, MultiplatformModifier.ACTUAL, ::createJvmFunctionImplementation)
//Create type-aliases
commonClassDefinition.innerClasses.forEach {
fileBuilder.addTypeAlias(createJvmInnerClassSpec(it, MultiplatformModifier.ACTUAL))
}
val commonClassSpec = createClass(
commonClassDefinition,
MultiplatformModifier.ACTUAL,
::createJvmFunctionImplementation
)
fileBuilder.addType(commonClassSpec)
}
val file = fileBuilder.build()
@ -25,17 +34,101 @@ object JvmLibsodiumGenerator {
return file
}
fun createJvmFunctionImplementation(methodDefinition: FunctionDefinition) : FunSpec {
fun createJvmInnerClassSpec(
innerClassDefinition: InnerClassDefinition,
multiplatformModifier: MultiplatformModifier
): TypeAliasSpec {
val innerClassBuilder = TypeAliasSpec.builder(innerClassDefinition.name, ClassName.bestGuess(innerClassDefinition.javaName))
innerClassBuilder.modifiers += multiplatformModifier.modifierList
return innerClassBuilder.build()
}
fun createJvmFunctionImplementation(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")
}
methodBuilder.addStatement("val test1 = ${methodDefinition.javaName}")
returnModifierFound = true
returnModifierName = paramDefinition.parameterName
}
}
if (methodDefinition.returnType == TypeDefinition.ARRAY_OF_UBYTES) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return sodium.${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType == TypeDefinition.INT) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return sodium.${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType is CustomTypeDefinition) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return sodium.${methodDefinition.javaName}")
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 + separator)
}
if (paramDefinition.parameterType is TypeDefinition) {
when(paramDefinition.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES -> {
paramsBuilder.append(paramDefinition.parameterName + ".asByteArray()" + separator + paramDefinition.parameterName + ".size, ")
}
TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> {
paramsBuilder.append(paramDefinition.parameterName + ".asByteArray()" + separator)
}
TypeDefinition.LONG -> {
paramsBuilder.append(paramDefinition.parameterName + separator)
}
TypeDefinition.INT -> {
paramsBuilder.append(paramDefinition.parameterName + separator)
}
TypeDefinition.STRING -> {
paramsBuilder.append(paramDefinition.parameterName + separator)
}
}
}
}
paramsBuilder.append(')')
return paramsBuilder.toString()
}
}

View File

@ -2,10 +2,8 @@ package com.ionspin.kotlin.crypto.generator.libsodium.generator
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ClassDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition
import com.squareup.kotlinpoet.FileSpec
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.TypeSpec
/**
@ -13,14 +11,13 @@ import com.squareup.kotlinpoet.TypeSpec
* ugljesa.jovanovic@ionspin.com
* on 31-Jul-2020
*/
fun createClass(classDefinition: ClassDefinition, multiplatformModifier: MultiplatformModifier, methodCreator : (FunctionDefinition) -> FunSpec) : TypeSpec {
fun createClass(
classDefinition: ClassDefinition,
multiplatformModifier: MultiplatformModifier,
methodCreator: (FunctionDefinition) -> FunSpec
): TypeSpec {
val commonClassBuilder = TypeSpec.classBuilder(classDefinition.name)
commonClassBuilder.modifiers += multiplatformModifier.modifierList
for (innerClassDefinition in classDefinition.innerClasses) {
val innerClassBuilder = TypeSpec.classBuilder(innerClassDefinition.name)
innerClassBuilder.modifiers += multiplatformModifier.modifierList
commonClassBuilder.addType(innerClassBuilder.build())
}
for (methodDefinition in classDefinition.methods) {
commonClassBuilder.addFunction(methodCreator(methodDefinition))
}

View File

@ -0,0 +1,19 @@
package debug.test
import Sha256State
import kotlin.Int
import kotlin.UByteArray
expect class Sha256State
expect class Hashing {
fun init(state: Sha256State): Int
}
expect class GenericHash {
fun init(
state: UByteArray,
key: UByteArray,
outlen: Int
): Int
}

View File

@ -0,0 +1,29 @@
package debug.test
import Sha256State
import com.goterl.lazycode.lazysodium.SodiumJava
import com.goterl.lazycode.lazysodium.interfaces.Hash
import kotlin.Int
import kotlin.UByteArray
val sodium: SodiumJava = SodiumJava()
actual typealias Sha256State = Hash.State256
actual class Hashing {
actual fun init(state: Sha256State): Int {
println("Debug")
return sodium.crypto_hash_sha256_init(state)
}
}
actual class GenericHash {
actual fun init(
state: UByteArray,
key: UByteArray,
outlen: Int
): Int {
println("Debug")
return sodium.crypto_generichash_init(state.asByteArray(), key.asByteArray(), key.size, outlen)
}
}

View File

@ -0,0 +1,5 @@
package debug.test
import libsodium.crypto_hash_sha256_state
actual typealias Sha256State = crypto_hash_sha256_state