Skip to content

Commit

Permalink
add DSL overloads, paginators, and better builder integration for DDB…
Browse files Browse the repository at this point in the history
… Mapper ops codegen (#1409)
  • Loading branch information
ianbotsf authored Sep 19, 2024
1 parent 15a9472 commit 21f1bd5
Show file tree
Hide file tree
Showing 48 changed files with 1,464 additions and 573 deletions.
20 changes: 13 additions & 7 deletions hll/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,16 @@ val sdkVersion: String by project
// capture locally - scope issue with custom KMP plugin
val libraries = libs

val optinAnnotations = listOf(
"aws.smithy.kotlin.runtime.InternalApi",
"aws.sdk.kotlin.runtime.InternalSdkApi",
"kotlin.RequiresOptIn",
)

subprojects {
if (!needsKmpConfigured) return@subprojects
if (!needsKmpConfigured) {
return@subprojects
}

group = "aws.sdk.kotlin"
version = sdkVersion
Expand All @@ -45,6 +53,10 @@ subprojects {
sourceSets {
// dependencies available for all subprojects

all {
optinAnnotations.forEach(languageSettings::optIn)
}

named("commonTest") {
dependencies {
implementation(libraries.kotest.assertions.core)
Expand All @@ -60,12 +72,6 @@ subprojects {
}
}

kotlin.sourceSets.all {
// Allow subprojects to use internal APIs
// See https://kotlinlang.org/docs/reference/opt-in-requirements.html#opting-in-to-using-api
listOf("kotlin.RequiresOptIn").forEach { languageSettings.optIn(it) }
}

dependencies {
dokkaPlugin(project(":dokka-aws"))
}
Expand Down
10 changes: 10 additions & 0 deletions hll/dynamodb-mapper/dynamodb-mapper-codegen/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,18 @@ dependencies {
testImplementation(libs.kotlin.test.junit5)
}

val optinAnnotations = listOf(
"aws.smithy.kotlin.runtime.InternalApi",
"aws.sdk.kotlin.runtime.InternalSdkApi",
"kotlin.RequiresOptIn",
)

kotlin {
explicitApi()

sourceSets.all {
optinAnnotations.forEach(languageSettings::optIn)
}
}

tasks.test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package aws.sdk.kotlin.hll.dynamodbmapper.codegen.annotations

import aws.sdk.kotlin.hll.codegen.core.CodeGeneratorFactory
import aws.sdk.kotlin.hll.codegen.ksp.processors.HllKspProcessor
import aws.sdk.kotlin.hll.codegen.rendering.RenderOptions.VisibilityAttribute
import aws.sdk.kotlin.hll.codegen.rendering.Visibility
import aws.sdk.kotlin.hll.dynamodbmapper.DynamoDbItem
Expand All @@ -19,17 +20,11 @@ import com.google.devtools.ksp.validate

private val annotationName = DynamoDbItem::class.qualifiedName!!

public class AnnotationsProcessor(private val environment: SymbolProcessorEnvironment) : SymbolProcessor {
private var invoked = false
public class AnnotationsProcessor(private val environment: SymbolProcessorEnvironment) : HllKspProcessor(environment) {
private val logger = environment.logger
private val codeGenerator = environment.codeGenerator

override fun process(resolver: Resolver): List<KSAnnotated> {
if (invoked) {
return listOf()
}
invoked = true

override fun processImpl(resolver: Resolver): List<KSAnnotated> {
logger.info("Searching for symbols annotated with $annotationName")
val annotated = resolver.getSymbolsWithAnnotation(annotationName)
val invalid = annotated.filterNot { it.validate() }.toList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ internal class SchemaRenderer(

private fun renderBuilder() {
val members = properties.map(Member.Companion::from).toSet()
BuilderRenderer(this, classType, members, ctx).render()
BuilderRenderer(this, classType, classType, members, ctx).render()
}

private fun renderItemConverter() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package aws.sdk.kotlin.hll.dynamodbmapper.codegen.model

import aws.sdk.kotlin.runtime.InternalSdkApi

@InternalSdkApi
public object MapperPkg {
@InternalSdkApi
public object Hl {
public val Base: String = "aws.sdk.kotlin.hll.dynamodbmapper"
public val Annotations: String = "$Base.annotations"
public val Items: String = "$Base.items"
public val Model: String = "$Base.model"
public val Ops: String = "$Base.operations"
public val PipelineImpl: String = "$Base.pipeline.internal"
public val Values: String = "$Base.values"
public val CollectionValues: String = "$Values.collections"
public val ScalarValues: String = "$Values.scalars"
public val SmithyTypeValues: String = "$Values.smithytypes"
}

@InternalSdkApi
public object Ll {
public val Base: String = "aws.sdk.kotlin.services.dynamodb"
public val Model: String = "$Base.model"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,117 +4,129 @@ import aws.sdk.kotlin.hll.codegen.model.Type
import aws.sdk.kotlin.hll.codegen.model.TypeRef
import aws.sdk.kotlin.hll.codegen.model.TypeVar
import aws.sdk.kotlin.hll.codegen.model.Types
import aws.sdk.kotlin.hll.codegen.util.Pkg

/**
* A container object for various DynamoDbMapper [Type] instances
*/
internal object MapperTypes {
// Low-level types
val AttributeValue = TypeRef(Pkg.Ll.Model, "AttributeValue")
val AttributeValue = TypeRef(MapperPkg.Ll.Model, "AttributeValue")
val AttributeMap = Types.Kotlin.map(Types.Kotlin.String, AttributeValue)

// High-level types
val DynamoDbMapper = TypeRef(Pkg.Hl.Base, "DynamoDbMapper")
val DynamoDbMapper = TypeRef(MapperPkg.Hl.Base, "DynamoDbMapper")

object Annotations {
val ManualPagination = TypeRef(MapperPkg.Hl.Annotations, "ManualPagination")
}

object Items {
fun itemSchema(typeVar: String) = TypeRef(Pkg.Hl.Items, "ItemSchema", listOf(TypeVar(typeVar)))
fun itemSchemaPartitionKey(objectType: TypeRef, pkType: TypeRef) = TypeRef(Pkg.Hl.Items, "ItemSchema.PartitionKey", listOf(objectType, pkType))
fun itemSchemaCompositeKey(objectType: TypeRef, pkType: TypeRef, skType: TypeRef) = TypeRef(Pkg.Hl.Items, "ItemSchema.CompositeKey", listOf(objectType, pkType, skType))
fun keySpec(keyType: TypeRef) = TypeRef(Pkg.Hl.Items, "KeySpec", genericArgs = listOf(keyType))
val KeySpecNumber = TypeRef(Pkg.Hl.Items, "KeySpec.Number")
val KeySpecString = TypeRef(Pkg.Hl.Items, "KeySpec.String")
val KeySpecByteArray = TypeRef(Pkg.Hl.Items, "KeySpec.ByteArray")
val AttributeDescriptor = TypeRef(Pkg.Hl.Items, "AttributeDescriptor")
fun itemConverter(objectType: TypeRef) = TypeRef(Pkg.Hl.Items, "ItemConverter", genericArgs = listOf(objectType))
val SimpleItemConverter = TypeRef(Pkg.Hl.Items, "SimpleItemConverter")
fun itemSchema(typeVar: String) =
TypeRef(MapperPkg.Hl.Items, "ItemSchema", genericArgs = listOf(TypeVar(typeVar)))

fun itemSchemaPartitionKey(objectType: TypeRef, pkType: TypeRef) =
TypeRef(MapperPkg.Hl.Items, "ItemSchema.PartitionKey", genericArgs = listOf(objectType, pkType))

fun itemSchemaCompositeKey(objectType: TypeRef, pkType: TypeRef, skType: TypeRef) =
TypeRef(MapperPkg.Hl.Items, "ItemSchema.CompositeKey", genericArgs = listOf(objectType, pkType, skType))

fun keySpec(keyType: TypeRef) = TypeRef(MapperPkg.Hl.Items, "KeySpec", genericArgs = listOf(keyType))
val KeySpecByteArray = TypeRef(MapperPkg.Hl.Items, "KeySpec.ByteArray")
val KeySpecNumber = TypeRef(MapperPkg.Hl.Items, "KeySpec.Number")
val KeySpecString = TypeRef(MapperPkg.Hl.Items, "KeySpec.String")
val AttributeDescriptor = TypeRef(MapperPkg.Hl.Items, "AttributeDescriptor")

fun itemConverter(objectType: TypeRef) =
TypeRef(MapperPkg.Hl.Items, "ItemConverter", genericArgs = listOf(objectType))

val SimpleItemConverter = TypeRef(MapperPkg.Hl.Items, "SimpleItemConverter")
}

object Model {
fun tablePartitionKey(objectType: TypeRef, pkType: TypeRef) = TypeRef(
Pkg.Hl.Model,
MapperPkg.Hl.Model,
"Table.PartitionKey",
genericArgs = listOf(objectType, pkType),
)
fun tableCompositeKey(objectType: TypeRef, pkType: TypeRef, skType: TypeRef) = TypeRef(
Pkg.Hl.Model,
MapperPkg.Hl.Model,
"Table.CompositeKey",
genericArgs = listOf(objectType, pkType, skType),
)
val toItem = TypeRef(Pkg.Hl.Model, "toItem")
val toItem = TypeRef(MapperPkg.Hl.Model, "toItem")
}

object Values {
fun valueConverter(value: Type) = TypeRef(Pkg.Hl.Values, "ValueConverter", genericArgs = listOf(value))
val ItemToValueConverter = TypeRef(Pkg.Hl.Values, "ItemToValueConverter")
fun valueConverter(value: Type) = TypeRef(MapperPkg.Hl.Values, "ValueConverter", genericArgs = listOf(value))
val ItemToValueConverter = TypeRef(MapperPkg.Hl.Values, "ItemToValueConverter")

object Collections {
val ListConverter = TypeRef(Pkg.Hl.CollectionValues, "ListConverter")
val MapConverter = TypeRef(Pkg.Hl.CollectionValues, "MapConverter")

val StringSetConverter = TypeRef(Pkg.Hl.CollectionValues, "StringSetConverter")
val CharSetConverter = TypeRef(Pkg.Hl.CollectionValues, "CharSetConverter")
val CharArraySetConverter = TypeRef(Pkg.Hl.CollectionValues, "CharArraySetConverter")

val ByteSetConverter = TypeRef(Pkg.Hl.CollectionValues, "ByteSetConverter")
val DoubleSetConverter = TypeRef(Pkg.Hl.CollectionValues, "DoubleSetConverter")
val FloatSetConverter = TypeRef(Pkg.Hl.CollectionValues, "FloatSetConverter")
val IntSetConverter = TypeRef(Pkg.Hl.CollectionValues, "IntSetConverter")
val LongSetConverter = TypeRef(Pkg.Hl.CollectionValues, "LongSetConverter")
val ShortSetConverter = TypeRef(Pkg.Hl.CollectionValues, "ShortSetConverter")

val UByteSetConverter = TypeRef(Pkg.Hl.CollectionValues, "UByteSetConverter")
val UIntSetConverter = TypeRef(Pkg.Hl.CollectionValues, "UIntSetConverter")
val ULongSetConverter = TypeRef(Pkg.Hl.CollectionValues, "ULongSetConverter")
val UShortSetConverter = TypeRef(Pkg.Hl.CollectionValues, "UShortSetConverter")
val ListConverter = TypeRef(MapperPkg.Hl.CollectionValues, "ListConverter")
val MapConverter = TypeRef(MapperPkg.Hl.CollectionValues, "MapConverter")

val StringSetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "StringSetConverter")
val CharSetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "CharSetConverter")
val CharArraySetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "CharArraySetConverter")

val ByteSetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "ByteSetConverter")
val DoubleSetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "DoubleSetConverter")
val FloatSetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "FloatSetConverter")
val IntSetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "IntSetConverter")
val LongSetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "LongSetConverter")
val ShortSetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "ShortSetConverter")

val UByteSetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "UByteSetConverter")
val UIntSetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "UIntSetConverter")
val ULongSetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "ULongSetConverter")
val UShortSetConverter = TypeRef(MapperPkg.Hl.CollectionValues, "UShortSetConverter")
}

object Scalars {
fun enumConverter(enumType: Type) = TypeRef(Pkg.Hl.ScalarValues, "EnumConverter", genericArgs = listOf(enumType))

val BooleanConverter = TypeRef(Pkg.Hl.ScalarValues, "BooleanConverter")
val StringConverter = TypeRef(Pkg.Hl.ScalarValues, "StringConverter")
val CharConverter = TypeRef(Pkg.Hl.ScalarValues, "CharConverter")
val CharArrayConverter = TypeRef(Pkg.Hl.ScalarValues, "CharArrayConverter")

val ByteConverter = TypeRef(Pkg.Hl.ScalarValues, "ByteConverter")
val ByteArrayConverter = TypeRef(Pkg.Hl.ScalarValues, "ByteArrayConverter")
val DoubleConverter = TypeRef(Pkg.Hl.ScalarValues, "DoubleConverter")
val FloatConverter = TypeRef(Pkg.Hl.ScalarValues, "FloatConverter")
val IntConverter = TypeRef(Pkg.Hl.ScalarValues, "IntConverter")
val LongConverter = TypeRef(Pkg.Hl.ScalarValues, "LongConverter")
val ShortConverter = TypeRef(Pkg.Hl.ScalarValues, "ShortConverter")
val UByteConverter = TypeRef(Pkg.Hl.ScalarValues, "UByteConverter")
val UIntConverter = TypeRef(Pkg.Hl.ScalarValues, "UIntConverter")
val ULongConverter = TypeRef(Pkg.Hl.ScalarValues, "ULongConverter")
val UShortConverter = TypeRef(Pkg.Hl.ScalarValues, "UShortConverter")

val BooleanToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "BooleanToStringConverter")
val CharArrayToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "TextConverters.CharArrayToStringConverter")
val CharToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "TextConverters.CharToStringConverter")
val StringToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "TextConverters.StringToStringConverter")
val ByteToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "NumberConverters.ByteToStringConverter")
val DoubleToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "NumberConverters.DoubleToStringConverter")
val FloatToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "NumberConverters.FloatToStringConverter")
val IntToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "NumberConverters.IntToStringConverter")
val LongToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "NumberConverters.LongToStringConverter")
val ShortToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "NumberConverters.ShortToStringConverter")
val UByteToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "NumberConverters.UByteToStringConverter")
val UIntToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "NumberConverters.UIntToStringConverter")
val ULongToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "NumberConverters.ULongToStringConverter")
val UShortToStringConverter = TypeRef(Pkg.Hl.ScalarValues, "NumberConverters.UShortToStringConverter")
fun enumConverter(enumType: Type) = TypeRef(MapperPkg.Hl.ScalarValues, "EnumConverter", genericArgs = listOf(enumType))

val BooleanConverter = TypeRef(MapperPkg.Hl.ScalarValues, "BooleanConverter")
val StringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "StringConverter")
val CharConverter = TypeRef(MapperPkg.Hl.ScalarValues, "CharConverter")
val CharArrayConverter = TypeRef(MapperPkg.Hl.ScalarValues, "CharArrayConverter")

val ByteConverter = TypeRef(MapperPkg.Hl.ScalarValues, "ByteConverter")
val ByteArrayConverter = TypeRef(MapperPkg.Hl.ScalarValues, "ByteArrayConverter")
val DoubleConverter = TypeRef(MapperPkg.Hl.ScalarValues, "DoubleConverter")
val FloatConverter = TypeRef(MapperPkg.Hl.ScalarValues, "FloatConverter")
val IntConverter = TypeRef(MapperPkg.Hl.ScalarValues, "IntConverter")
val LongConverter = TypeRef(MapperPkg.Hl.ScalarValues, "LongConverter")
val ShortConverter = TypeRef(MapperPkg.Hl.ScalarValues, "ShortConverter")
val UByteConverter = TypeRef(MapperPkg.Hl.ScalarValues, "UByteConverter")
val UIntConverter = TypeRef(MapperPkg.Hl.ScalarValues, "UIntConverter")
val ULongConverter = TypeRef(MapperPkg.Hl.ScalarValues, "ULongConverter")
val UShortConverter = TypeRef(MapperPkg.Hl.ScalarValues, "UShortConverter")

val BooleanToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "BooleanToStringConverter")
val CharArrayToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "TextConverters.CharArrayToStringConverter")
val CharToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "TextConverters.CharToStringConverter")
val StringToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "TextConverters.StringToStringConverter")
val ByteToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "NumberConverters.ByteToStringConverter")
val DoubleToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "NumberConverters.DoubleToStringConverter")
val FloatToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "NumberConverters.FloatToStringConverter")
val IntToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "NumberConverters.IntToStringConverter")
val LongToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "NumberConverters.LongToStringConverter")
val ShortToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "NumberConverters.ShortToStringConverter")
val UByteToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "NumberConverters.UByteToStringConverter")
val UIntToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "NumberConverters.UIntToStringConverter")
val ULongToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "NumberConverters.ULongToStringConverter")
val UShortToStringConverter = TypeRef(MapperPkg.Hl.ScalarValues, "NumberConverters.UShortToStringConverter")
}

object SmithyTypes {
val DefaultInstantConverter = TypeRef(Pkg.Hl.SmithyTypeValues, "InstantConverter.Default")
val UrlConverter = TypeRef(Pkg.Hl.SmithyTypeValues, "UrlConverter")
val DefaultDocumentConverter = TypeRef(Pkg.Hl.SmithyTypeValues, "DocumentConverter.Default")
val DefaultInstantConverter = TypeRef(MapperPkg.Hl.SmithyTypeValues, "InstantConverter.Default")
val UrlConverter = TypeRef(MapperPkg.Hl.SmithyTypeValues, "UrlConverter")
val DefaultDocumentConverter = TypeRef(MapperPkg.Hl.SmithyTypeValues, "DocumentConverter.Default")
}
}

object PipelineImpl {
val HReqContextImpl = TypeRef(Pkg.Hl.PipelineImpl, "HReqContextImpl")
val MapperContextImpl = TypeRef(Pkg.Hl.PipelineImpl, "MapperContextImpl")
val Operation = TypeRef(Pkg.Hl.PipelineImpl, "Operation")
val HReqContextImpl = TypeRef(MapperPkg.Hl.PipelineImpl, "HReqContextImpl")
val MapperContextImpl = TypeRef(MapperPkg.Hl.PipelineImpl, "MapperContextImpl")
val Operation = TypeRef(MapperPkg.Hl.PipelineImpl, "Operation")
}
}
Loading

0 comments on commit 21f1bd5

Please sign in to comment.