This in an extension of proposal 111, discussion here Java annotations for Kotlin sugar · Issue #110 · Kotlin/KEEP · GitHub
The goal is to enhance the integration between Kotlin and Java CPS methods.
Annotations
This proposal requires two new annotations: Suspend
and ContinuationAdapter
.
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.BINARY)
annotation class Suspend()
@Target(AnnotationTarget.TYPE, AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.BINARY)
annotation class ContinuationAdapter(val value: String)
@Suspend
annotation
The @Suspend
annotation marks a CPS method, this method must have at least one argument and the last one must be of Continuation
type. The return value is always ignored.
Note: Continuation
interface is in experimental state now, however the final design of the interface does not affect this proposal.
The Java method:
@Suspend
public void compute(Continuation<Result> continuation);
can be invoked like a regular Kotlin’s suspending method
val result : Result = compute()
@ContinuationAdapter
annotation
The @ContinuationAdapter
annotation allows to specify a different type for last method parameter, the annotation’s value
is the full class name of the adapter.
This annotations allows to use any type as CPS parameter. The wrapper must implement the proprietary interface and must have a constructor taking a single argument of Continuation
type.
For example the AWS Java API uses the base class AsyncHandler
(AsyncHandler (AWS SDK for Java - 1.12.294)), so the adapter is
public AsyncHandlerAdapter <REQUEST, RESULT> : AsyncHandler<REQUEST, RESULT> {
private final Continuation<RESULT> continuation;
public AsyncHandlerAdapter(Continuation<RESULT> continuation) {
this.continuation = continuation;
}
public void onSuccess(REQUEST request, RESULT result) {
continuation.resume(result); // subject to change
}
public onError(Exception exception) {
continuation.resumeWithException(exception); // subject to change
}
}
So the class AmazonDynamoDBAsync
can become
@ContinuationAdapter("mypackage.AsyncHandlerAdapter")
public class AmazonDynamoDBAsync {
@Suspend
public Future<GetItemResult> getItemAsync(GetItemRequest getItemRequest, AsyncHandler<GetItemRequest,GetItemResult> asyncHandler)
// ...
and it can be used by Kotlin
val getItemResult = amazonDynamoDBAsync.getItemAsync(getItemRequest)
This proposal should cover many asynchronous libraries, like Vert.x, Memcached.
I missed some use case?