Search in sources :

Example 1 with EvaluatedParams

use of io.quarkus.qute.EvaluatedParams in project quarkus by quarkusio.

the class MessageBundleProcessor method implementResolve.

private void implementResolve(String defaultBundleImpl, ClassCreator bundleCreator, Map<String, MethodInfo> keyMap) {
    MethodCreator resolve = bundleCreator.getMethodCreator("resolve", CompletionStage.class, EvalContext.class);
    String resolveMethodPrefix = bundleCreator.getClassName().contains("/") ? bundleCreator.getClassName().substring(bundleCreator.getClassName().lastIndexOf('/') + 1) : bundleCreator.getClassName();
    ResultHandle evalContext = resolve.getMethodParam(0);
    ResultHandle name = resolve.invokeInterfaceMethod(Descriptors.GET_NAME, evalContext);
    ResultHandle ret = resolve.newInstance(MethodDescriptor.ofConstructor(CompletableFuture.class));
    // First handle dynamic messages, i.e. the "message" virtual method
    BytecodeCreator dynamicMessage = resolve.ifTrue(resolve.invokeVirtualMethod(Descriptors.EQUALS, resolve.load(MESSAGE), name)).trueBranch();
    ResultHandle evaluatedMessageKey = dynamicMessage.invokeStaticMethod(Descriptors.EVALUATED_PARAMS_EVALUATE_MESSAGE_KEY, evalContext);
    ResultHandle paramsReady = dynamicMessage.readInstanceField(Descriptors.EVALUATED_PARAMS_STAGE, evaluatedMessageKey);
    // Define function called when the message key is ready
    FunctionCreator whenCompleteFun = dynamicMessage.createFunction(BiConsumer.class);
    dynamicMessage.invokeInterfaceMethod(Descriptors.CF_WHEN_COMPLETE, paramsReady, whenCompleteFun.getInstance());
    BytecodeCreator whenComplete = whenCompleteFun.getBytecode();
    AssignableResultHandle whenThis = whenComplete.createVariable(DescriptorUtils.extToInt(bundleCreator.getClassName()));
    whenComplete.assign(whenThis, dynamicMessage.getThis());
    AssignableResultHandle whenRet = whenComplete.createVariable(CompletableFuture.class);
    whenComplete.assign(whenRet, ret);
    AssignableResultHandle whenEvalContext = whenComplete.createVariable(EvalContext.class);
    whenComplete.assign(whenEvalContext, evalContext);
    BranchResult throwableIsNull = whenComplete.ifNull(whenComplete.getMethodParam(1));
    BytecodeCreator success = throwableIsNull.trueBranch();
    // Return if the name is null or NOT_FOUND
    ResultHandle resultNotFound = success.invokeStaticMethod(Descriptors.NOT_FOUND_FROM_EC, whenEvalContext);
    BytecodeCreator nameIsNull = success.ifNull(whenComplete.getMethodParam(0)).trueBranch();
    nameIsNull.invokeVirtualMethod(Descriptors.COMPLETABLE_FUTURE_COMPLETE, whenRet, resultNotFound);
    nameIsNull.returnValue(null);
    BytecodeCreator nameNotFound = success.ifTrue(success.invokeVirtualMethod(Descriptors.EQUALS, whenComplete.getMethodParam(0), resultNotFound)).trueBranch();
    nameNotFound.invokeVirtualMethod(Descriptors.COMPLETABLE_FUTURE_COMPLETE, whenRet, resultNotFound);
    nameNotFound.returnValue(null);
    // Evaluate the rest of the params
    ResultHandle evaluatedMessageParams = success.invokeStaticMethod(Descriptors.EVALUATED_PARAMS_EVALUATE_MESSAGE_PARAMS, whenEvalContext);
    // Delegate to BundleClassName_resolve_0 (the first group of messages)
    ResultHandle res0Ret = success.invokeVirtualMethod(MethodDescriptor.ofMethod(bundleCreator.getClassName(), resolveMethodPrefix + "_resolve_0", CompletableFuture.class, String.class, EvaluatedParams.class, CompletableFuture.class), whenThis, whenComplete.getMethodParam(0), evaluatedMessageParams, whenRet);
    BytecodeCreator ret0Null = success.ifNull(res0Ret).trueBranch();
    ret0Null.invokeVirtualMethod(Descriptors.COMPLETABLE_FUTURE_COMPLETE, whenRet, resultNotFound);
    BytecodeCreator failure = throwableIsNull.falseBranch();
    failure.invokeVirtualMethod(Descriptors.COMPLETABLE_FUTURE_COMPLETE_EXCEPTIONALLY, whenRet, whenComplete.getMethodParam(1));
    whenComplete.returnValue(null);
    // Return from the resolve method
    dynamicMessage.returnValue(ret);
    // Proceed with generated messages
    // We do group messages to workaround limits of a JVM method body
    ResultHandle evaluatedParams = resolve.invokeStaticMethod(Descriptors.EVALUATED_PARAMS_EVALUATE, evalContext);
    final int groupLimit = 300;
    int groupIndex = 0;
    int resolveIndex = 0;
    MethodCreator resolveGroup = null;
    for (Entry<String, MethodInfo> entry : keyMap.entrySet()) {
        if (resolveGroup == null || groupIndex++ >= groupLimit) {
            groupIndex = 0;
            String resolveMethodName = resolveMethodPrefix + "_resolve_" + resolveIndex++;
            if (resolveGroup != null) {
                // Delegate to the next "resolve_x" method
                resolveGroup.returnValue(resolveGroup.invokeVirtualMethod(MethodDescriptor.ofMethod(bundleCreator.getClassName(), resolveMethodName, CompletableFuture.class, String.class, EvaluatedParams.class, CompletableFuture.class), resolveGroup.getThis(), resolveGroup.getMethodParam(0), resolveGroup.getMethodParam(1), resolveGroup.getMethodParam(2)));
            }
            resolveGroup = bundleCreator.getMethodCreator(resolveMethodName, CompletableFuture.class, String.class, EvaluatedParams.class, CompletableFuture.class).setModifiers(0);
            if (resolveIndex == 1) {
                ResultHandle resRet = resolve.invokeVirtualMethod(MethodDescriptor.ofMethod(bundleCreator.getClassName(), resolveMethodName, CompletableFuture.class, String.class, EvaluatedParams.class, CompletableFuture.class), resolve.getThis(), name, evaluatedParams, ret);
                resolve.ifNotNull(resRet).trueBranch().returnValue(resRet);
            }
        }
        addMessageMethod(resolveGroup, entry.getKey(), entry.getValue(), resolveGroup.getMethodParam(0), resolveGroup.getMethodParam(1), resolveGroup.getMethodParam(2), bundleCreator.getClassName());
    }
    if (resolveGroup != null) {
        // Last group - return null
        resolveGroup.returnValue(resolveGroup.loadNull());
    }
    if (defaultBundleImpl != null) {
        resolve.returnValue(resolve.invokeSpecialMethod(MethodDescriptor.ofMethod(defaultBundleImpl, "resolve", CompletionStage.class, EvalContext.class), resolve.getThis(), evalContext));
    } else {
        resolve.returnValue(resolve.invokeStaticMethod(Descriptors.RESULTS_NOT_FOUND_EC, evalContext));
    }
}
Also used : BranchResult(io.quarkus.gizmo.BranchResult) CompletableFuture(java.util.concurrent.CompletableFuture) FunctionCreator(io.quarkus.gizmo.FunctionCreator) MethodCreator(io.quarkus.gizmo.MethodCreator) EvaluatedParams(io.quarkus.qute.EvaluatedParams) ResultHandle(io.quarkus.gizmo.ResultHandle) AssignableResultHandle(io.quarkus.gizmo.AssignableResultHandle) BytecodeCreator(io.quarkus.gizmo.BytecodeCreator) AssignableResultHandle(io.quarkus.gizmo.AssignableResultHandle) MethodInfo(org.jboss.jandex.MethodInfo)

Aggregations

AssignableResultHandle (io.quarkus.gizmo.AssignableResultHandle)1 BranchResult (io.quarkus.gizmo.BranchResult)1 BytecodeCreator (io.quarkus.gizmo.BytecodeCreator)1 FunctionCreator (io.quarkus.gizmo.FunctionCreator)1 MethodCreator (io.quarkus.gizmo.MethodCreator)1 ResultHandle (io.quarkus.gizmo.ResultHandle)1 EvaluatedParams (io.quarkus.qute.EvaluatedParams)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 MethodInfo (org.jboss.jandex.MethodInfo)1