SourceMethodService.java

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

import io.kaumei.jdbc.anno.ProcessorEnvironment;
import io.kaumei.jdbc.anno.ProcessorSteps;
import io.kaumei.jdbc.anno.ctx.Context;
import org.jspecify.annotations.Nullable;

import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

import static java.util.Objects.requireNonNull;

public class SourceMethodService implements ProcessorSteps {
    // ----- services
    private final Context ctx;
    // ----- state
    private final Map<ExecutableElement, SourceMethod> methods = new LinkedHashMap<>();

    public SourceMethodService(Context ctx) {
        this.ctx = requireNonNull(ctx);
    }

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

    @Override
    public void process(ProcessorEnvironment roundEnv) {
        for (var entry : roundEnv.jdbcInterfaces()) {
            this.ctx.logger.acceptWithDebugFlag(entry, this::resolveMethods);
        }
    }

    private void resolveMethods(TypeElement iface) {
        this.ctx.logger.info("Resolve methods", iface);
        // ----- process methods
        for (var child : iface.getEnclosedElements()) {
            if (!child.getModifiers().contains(Modifier.STATIC)
                    && !child.getModifiers().contains(Modifier.DEFAULT)
                    && child.getKind() == ElementKind.METHOD
                    && child instanceof ExecutableElement method) {
                resolveMethod(method);
            }
        }
    }

    private void resolveMethod(ExecutableElement method) {
        var source = SourceMethod.of(this.ctx, method);
        var old = methods.put(method, source);
        if (old != null) {
            throw new IllegalStateException("duplicate: " + method);
        }
    }

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

    public SourceMethod get(ExecutableElement method) {
        return Objects.requireNonNull(methods.get(method));
    }

    public @Nullable SourceMethod getOpt(ExecutableElement method) {
        return methods.get(method);
    }

    public Collection<SourceMethod> values() {
        return methods.values();
    }
}