Unverified Commit dde9646b authored by david-perez's avatar david-perez Committed by GitHub
Browse files

Correctly load client or server specific decorators from classpath (#1592)

The current approach that attempts to downcast never worked; all Rust
decorators were being loaded, and the cast was doing nothing, because
the generic type parameter is erased at runtime.

Attempting to downcast a generic class `C<T>` to `C<U>` where `U: T` is
not possible to do in Kotlin (and presumably all JVM-based languages)
_at runtime_. Not even when using reified type parameters of inline
functions. See https://kotlinlang.org/docs/generics.html#type-erasure
for details.

This commit thus goes for another approach, suggested in the linked
Stack Overflow question [0]: add a method to the loaded classes that
signals at runtime the generic type parameter (`ClientCodegenContext` or
`ServerCodegenContext`) they can work with, in order to filter them.

This commit also simplifies the way the Python server project loads the Python
server-specific decorators, by deleting the combined decorator
`PythonServerCodegenDecorator`, which was being loaded from the classpath, and
instead directly using `CombinedCodegenDecorator` and passing it the Python
server-specific decorators in the `extras` parameter.

[0]: https://stackoverflow.com/questions/5451734/loading-generic-service-implementations-via-java-util-serviceloader
parent 3a2de293
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -73,6 +73,9 @@ class AwsEndpointDecorator : RustCodegenDecorator<ClientCodegenContext> {
    ): List<LibRsCustomization> {
        return baseCustomizations + PubUseEndpoint(codegenContext.runtimeConfig)
    }

    override fun supportsCodegenContext(clazz: Class<out CoreCodegenContext>): Boolean =
        clazz.isAssignableFrom(ClientCodegenContext::class.java)
}

class EndpointConfigCustomization(private val coreCodegenContext: CoreCodegenContext, private val endpointData: ObjectNode) :
+3 −0
Original line number Diff line number Diff line
@@ -111,6 +111,9 @@ class AwsFluentClientDecorator : RustCodegenDecorator<ClientCodegenContext> {
            }
        }
    }

    override fun supportsCodegenContext(clazz: Class<out CoreCodegenContext>): Boolean =
        clazz.isAssignableFrom(ClientCodegenContext::class.java)
}

private class AwsFluentClientExtensions(types: Types) {
+3 −0
Original line number Diff line number Diff line
@@ -117,6 +117,9 @@ class AwsPresigningDecorator internal constructor(
        return presignableTransforms.fold(intermediate) { m, t -> t.transform(m) }
    }

    override fun supportsCodegenContext(clazz: Class<out CoreCodegenContext>): Boolean =
        clazz.isAssignableFrom(ClientCodegenContext::class.java)

    private fun addSyntheticOperations(model: Model): Model {
        val presignableOps = model.shapes()
            .filter { shape -> shape is OperationShape && presignableOperations.containsKey(shape.id) }
+4 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ import org.jsoup.nodes.TextNode
import software.amazon.smithy.model.traits.DocumentationTrait
import software.amazon.smithy.rust.codegen.rustlang.raw
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.ManifestCustomizations
@@ -110,6 +111,9 @@ class AwsReadmeDecorator : RustCodegenDecorator<ClientCodegenContext> {
        }
    }

    override fun supportsCodegenContext(clazz: Class<out CoreCodegenContext>): Boolean =
        clazz.isAssignableFrom(ClientCodegenContext::class.java)

    /**
     * Strips HTML from the description and makes it human-readable Markdown.
     */
+4 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ package software.amazon.smithy.rustsdk

import software.amazon.smithy.rust.codegen.rustlang.raw
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator

@@ -21,4 +22,7 @@ class CrateLicenseDecorator : RustCodegenDecorator<ClientCodegenContext> {
            it.raw(license)
        }
    }

    override fun supportsCodegenContext(clazz: Class<out CoreCodegenContext>): Boolean =
        clazz.isAssignableFrom(ClientCodegenContext::class.java)
}
Loading