From 18fb9488ddcdbf6114e0eb8aed893d7f68af4847 Mon Sep 17 00:00:00 2001 From: Peter Sorotokin Date: Wed, 10 Apr 2024 10:28:49 -0700 Subject: [PATCH] Added imports for generated serializer/deserializer functions. Signed-off-by: Peter Sorotokin --- .../cbor/annotation/CborSerializable.kt | 2 +- .../cbor/processor/CborSymbolProcessor.kt | 32 +++++++++++++++---- .../identity/cbor/processor/CodeBuilder.kt | 16 +++++++++- .../EvidenceRequestCreatePassphrase.kt | 5 +-- .../SimpleIssuingAuthorityProofingGraph.kt | 4 +-- .../provisioncredential/EvidenceRequest.kt | 6 +--- 6 files changed, 44 insertions(+), 21 deletions(-) diff --git a/cbor-processor/src/main/kotlin/com/android/identity/cbor/annotation/CborSerializable.kt b/cbor-processor/src/main/kotlin/com/android/identity/cbor/annotation/CborSerializable.kt index 5afa636cc..fcfdcf927 100644 --- a/cbor-processor/src/main/kotlin/com/android/identity/cbor/annotation/CborSerializable.kt +++ b/cbor-processor/src/main/kotlin/com/android/identity/cbor/annotation/CborSerializable.kt @@ -1,7 +1,7 @@ package com.android.identity.cbor.annotation @Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.SOURCE) +@Retention(AnnotationRetention.BINARY) annotation class CborSerializable( /** * Optional parameter for sealed class hierarchies to define the key that carries type id. diff --git a/cbor-processor/src/main/kotlin/com/android/identity/cbor/processor/CborSymbolProcessor.kt b/cbor-processor/src/main/kotlin/com/android/identity/cbor/processor/CborSymbolProcessor.kt index 88516ba0e..e138c57c5 100644 --- a/cbor-processor/src/main/kotlin/com/android/identity/cbor/processor/CborSymbolProcessor.kt +++ b/cbor-processor/src/main/kotlin/com/android/identity/cbor/processor/CborSymbolProcessor.kt @@ -121,13 +121,14 @@ class CborSymbolProcessor( } emptyLine() - block("fun ${deserializerName(classDeclaration)}(dataItem: DataItem): $baseName") { + val deserializer = deserializerName(classDeclaration, true) + block("fun $deserializer(dataItem: DataItem): $baseName") { val typeKey = getTypeKey(annotation) line("val type = dataItem[\"$typeKey\"].asTstr") block("return when (type)") { for (subclass in subclasses) { val typeId = getTypeId(classDeclaration, subclass) - line("\"$typeId\" -> ${deserializerName(subclass)}(dataItem)") + line("\"$typeId\" -> ${deserializerName(subclass, false)}(dataItem)") } line("else -> throw IllegalArgumentException(\"wrong type: \$type\")") } @@ -200,7 +201,8 @@ class CborSymbolProcessor( val dataItem = varName("dataItem") emptyLine() - block("fun ${deserializerName(classDeclaration)}($dataItem: DataItem): $baseName") { + val deserializer = deserializerName(classDeclaration, true) + block("fun $deserializer($dataItem: DataItem): $baseName") { val constructorParameters = mutableListOf() classDeclaration.getAllProperties().forEach { property -> val fieldName = property.simpleName.asString() @@ -314,10 +316,16 @@ class CborSymbolProcessor( return null } - private fun deserializerName(classDeclaration: KSClassDeclaration): String { + private fun deserializerName( + classDeclaration: KSClassDeclaration, forDeclaration: Boolean): String { val baseName = classDeclaration.simpleName.asString() return if (hasCompanion(classDeclaration)) { - "${baseName}.Companion.fromDataItem" + if (forDeclaration) { + "${baseName}.Companion.fromDataItem" + } else { + // for call + "${baseName}.fromDataItem" + } } else { "${baseName}_fromDataItem" } @@ -334,7 +342,8 @@ class CborSymbolProcessor( type: KSType ): String { val declaration = type.declaration - when (declaration.qualifiedName!!.asString()) { + val qualifiedName = declaration.qualifiedName!!.asString() + when (qualifiedName) { "kotlin.collections.Map" -> with(codeBuilder) { val map = varName("map") @@ -388,6 +397,10 @@ class CborSymbolProcessor( ) { "$code.name" } else { + codeBuilder.importQualifiedName(qualifiedName) + if (findAnnotation(declaration, annotationSerializable) != null) { + codeBuilder.importFunctionName("toDataItem", declaration.packageName.asString()) + } "$code.toDataItem" } } @@ -461,7 +474,12 @@ class CborSymbolProcessor( "${typeRef(codeBuilder, type)}.valueOf($code.asTstr)" } else { codeBuilder.importQualifiedName(qualifiedName) - "${deserializerName(declaration as KSClassDeclaration)}($code)" + val deserializer = deserializerName(declaration as KSClassDeclaration, false) + if (findAnnotation(declaration, annotationSerializable) != null) { + val shortName = deserializer.substring(deserializer.lastIndexOf(".") + 1) + codeBuilder.importFunctionName(shortName, declaration.packageName.asString()) + } + "${deserializer}($code)" } } } diff --git a/cbor-processor/src/main/kotlin/com/android/identity/cbor/processor/CodeBuilder.kt b/cbor-processor/src/main/kotlin/com/android/identity/cbor/processor/CodeBuilder.kt index 8d0335e39..4b807f3b9 100644 --- a/cbor-processor/src/main/kotlin/com/android/identity/cbor/processor/CodeBuilder.kt +++ b/cbor-processor/src/main/kotlin/com/android/identity/cbor/processor/CodeBuilder.kt @@ -15,11 +15,19 @@ import java.io.Writer */ class CodeBuilder( private val classesToImport: MutableMap = mutableMapOf(), // simple to fully qualified name + private val functionsToImport: MutableMap> = mutableMapOf(), // function name to package set private var indentDepth: Int = 0, private val varCounts: MutableMap = mutableMapOf() ) { private val code: MutableList = mutableListOf() + /** + * Add and import for a function from a given package. + */ + fun importFunctionName(function: String, packageName: String) { + functionsToImport.computeIfAbsent(function) { mutableSetOf() }.add(packageName); + } + /** * Add given class to import list, simple class name can then be used in the code * to refer to it. @@ -66,7 +74,8 @@ class CodeBuilder( * called). */ fun insertionPoint(): CodeBuilder { - val builder = CodeBuilder(classesToImport, indentDepth, varCounts) + val builder = CodeBuilder( + classesToImport, functionsToImport, indentDepth, varCounts) code.add(builder) return builder } @@ -195,6 +204,11 @@ class CodeBuilder( classesToImport.forEach { (_, qualifiedName) -> file.write("import $qualifiedName\n") } + functionsToImport.forEach { (functionName, packageNames) -> + packageNames.forEach { packageName -> + file.write("import $packageName.$functionName\n") + } + } file.write("\n") writeCodeTo(file) file.close() diff --git a/wallet/src/main/java/com/android/identity/issuance/evidence/EvidenceRequestCreatePassphrase.kt b/wallet/src/main/java/com/android/identity/issuance/evidence/EvidenceRequestCreatePassphrase.kt index 19ef18b02..e65143e0e 100644 --- a/wallet/src/main/java/com/android/identity/issuance/evidence/EvidenceRequestCreatePassphrase.kt +++ b/wallet/src/main/java/com/android/identity/issuance/evidence/EvidenceRequestCreatePassphrase.kt @@ -11,10 +11,7 @@ import com.android.identity.securearea.PassphraseConstraints * @param length Length of the PIN */ data class EvidenceRequestCreatePassphrase ( - // TODO: use PassphraseConstraints instead when cbor-processor is fixed - val passphraseMinLength: Int, - val passphraseMaxLength: Int, - val passphraseRequireNumerical: Boolean, + val passphraseConstraints: PassphraseConstraints, val message: String, val verifyMessage: String, val assets: Map, diff --git a/wallet/src/main/java/com/android/identity/issuance/simple/SimpleIssuingAuthorityProofingGraph.kt b/wallet/src/main/java/com/android/identity/issuance/simple/SimpleIssuingAuthorityProofingGraph.kt index b8706106f..860ee8429 100644 --- a/wallet/src/main/java/com/android/identity/issuance/simple/SimpleIssuingAuthorityProofingGraph.kt +++ b/wallet/src/main/java/com/android/identity/issuance/simple/SimpleIssuingAuthorityProofingGraph.kt @@ -76,9 +76,7 @@ class SimpleIssuingAuthorityProofingGraph { passphraseConstraints: PassphraseConstraints, ) { val evidenceRequest = EvidenceRequestCreatePassphrase( - passphraseMinLength = passphraseConstraints.minLength, - passphraseMaxLength = passphraseConstraints.maxLength, - passphraseRequireNumerical = passphraseConstraints.requireNumerical, + passphraseConstraints = passphraseConstraints, message = message, verifyMessage = verifyMessage, assets = assets) diff --git a/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/provisioncredential/EvidenceRequest.kt b/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/provisioncredential/EvidenceRequest.kt index ac7ee06e9..ff26fdd63 100644 --- a/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/provisioncredential/EvidenceRequest.kt +++ b/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/provisioncredential/EvidenceRequest.kt @@ -238,11 +238,7 @@ fun EvidenceRequestCreatePassphraseView( var verifiedPassphrase by remember { mutableStateOf("") } var showMatchErrorText by remember { mutableStateOf(false) } - val constraints = PassphraseConstraints( - minLength = evidenceRequest.passphraseMinLength, - maxLength = evidenceRequest.passphraseMaxLength, - requireNumerical = evidenceRequest.passphraseRequireNumerical, - ) + val constraints = evidenceRequest.passphraseConstraints Row( modifier = Modifier.fillMaxWidth(),