ConverterStaticSimple.java

/*
 * SPDX-FileCopyrightText: 2025 kaumei.io
 * SPDX-License-Identifier: Apache-2.0
 */
package io.kaumei.jdbc.anno.java2jdbc;

import com.palantir.javapoet.CodeBlock;
import io.kaumei.jdbc.anno.gen.KaumeiLib;
import io.kaumei.jdbc.anno.gen.TargetMethod;
import io.kaumei.jdbc.anno.model.OptionalFlag;
import io.kaumei.jdbc.anno.store.SearchKey;
import io.kaumei.jdbc.anno.store.SourceDV;

import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Name;
import javax.lang.model.type.TypeMirror;

import static io.kaumei.jdbc.anno.ctx.JavaModelUtils.getQualifiedClassName;

final class ConverterStaticSimple extends Java2JdbcConverter {

    record Placeholder(TypeMirror type, SourceDV source, ExecutableElement method,
                       SearchKey other) implements Java2JdbcConverter.Placeholder {
        @Override
        public SearchKey otherPlaceholder() {
            return other;
        }

        @Override
        public Java2JdbcConverter resolve(Java2JdbcConverter converter) {
            return new ConverterStaticSimple(this, converter);
        }
    }

    // ------------------------------------------------------------------------

    private final Name qualifiedTypeName;
    private final Name methodName;
    private final Java2JdbcConverter converter;

    private ConverterStaticSimple(Placeholder placeholder, Java2JdbcConverter converter) {
        super(placeholder.type, placeholder.source);
        this.qualifiedTypeName = getQualifiedClassName(placeholder.method);
        this.methodName = placeholder.method.getSimpleName();
        this.converter = converter;
    }

    @Override
    public void setParameter(TargetMethod builder, CodeBlock paramAccess, CodeBlock columnIndex, OptionalFlag optional) {
        builder.addComment("ConverterStaticSimple", "type", this.type(), "optional", optional);
        var localName = builder.tempVarName(paramAccess);
        if (optional.isNonNull()) {
            if (!this.type().getKind().isPrimitive()) {
                builder.beginControlFlow("if ($L == null)", paramAccess);
                builder.addStatement(KaumeiLib.throwNullPointerException(paramAccess));
                builder.endControlFlow();
            }
            builder.addStatement("var $L = $L.$N($L)", localName, this.qualifiedTypeName, this.methodName, paramAccess);
            converter.setParameter(builder, localName, columnIndex, optional);
        } else if (this.type().getKind().isPrimitive()) { // sanity-check
            throw new IllegalStateException("Primitive type must be non-null:" + this); // sanity-check
        } else if (this.converter.type().getKind().isPrimitive()) {
            builder.beginControlFlow("if ($L == null)", paramAccess);
            builder.addStatement(builder.setNull(this.converter.type(), columnIndex));
            builder.nextControlFlow("else");
            builder.addStatement("var $L = $L.$N($L)", localName, this.qualifiedTypeName, this.methodName, paramAccess);
            converter.setParameter(builder, localName, columnIndex, OptionalFlag.NON_NULL);
            builder.endControlFlow();
        } else {
            builder.addStatement("var $L = $L == null ? null : $L.$N($L)", localName, paramAccess, qualifiedTypeName, methodName, paramAccess);
            converter.setParameter(builder, localName, columnIndex, optional);
        }
    }
}