All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.helidon.codegen.CodegenContextBase Maven / Gradle / Ivy

/*
 * Copyright (c) 2023, 2024 Oracle and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.helidon.codegen;

import java.util.HashSet;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;

import io.helidon.codegen.spi.AnnotationMapper;
import io.helidon.codegen.spi.AnnotationMapperProvider;
import io.helidon.codegen.spi.CodegenProvider;
import io.helidon.codegen.spi.ElementMapper;
import io.helidon.codegen.spi.ElementMapperProvider;
import io.helidon.codegen.spi.TypeMapper;
import io.helidon.codegen.spi.TypeMapperProvider;
import io.helidon.common.HelidonServiceLoader;
import io.helidon.common.types.TypeName;

/**
 * Base of codegen context implementation taking care of the common parts of the API.
 */
public abstract class CodegenContextBase implements CodegenContext {
    private final List elementMappers;
    private final List typeMappers;
    private final List annotationMappers;
    private final Set> supportedOptions;
    private final Set supportedPackages;
    private final Set supportedAnnotations;
    private final CodegenOptions options;
    private final CodegenFiler filer;
    private final CodegenLogger logger;
    private final CodegenScope scope;

    /**
     * Create a new instance with the common parts of the API.
     *
     * @param options           codegen options for the current environment
     * @param additionalOptions additional options to add to the list of supported options
     * @param filer             filer abstraction for the current environment
     * @param logger            logger abstraction for the current environment
     * @param scope             scope of the current environment
     */
    protected CodegenContextBase(CodegenOptions options,
                                 Set> additionalOptions,
                                 CodegenFiler filer,
                                 CodegenLogger logger,
                                 CodegenScope scope) {
        this.options = options;
        this.filer = filer;
        this.logger = logger;
        this.scope = scope;
        Set> supportedOptions = new HashSet<>(additionalOptions);
        Set supportedPackages = new HashSet<>();
        Set supportedAnnotations = new HashSet<>();

        this.annotationMappers = HelidonServiceLoader.create(
                        ServiceLoader.load(AnnotationMapperProvider.class,
                                           CodegenContextBase.class.getClassLoader()))
                .stream()
                .peek(it -> addSupported(it, supportedOptions, supportedPackages, supportedAnnotations))
                .map(it -> it.create(options))
                .toList();

        this.elementMappers = HelidonServiceLoader.create(
                        ServiceLoader.load(ElementMapperProvider.class,
                                           CodegenContextBase.class.getClassLoader()))
                .stream()
                .peek(it -> addSupported(it, supportedOptions, supportedPackages, supportedAnnotations))
                .map(it -> it.create(options))
                .toList();

        this.typeMappers = HelidonServiceLoader.create(
                        ServiceLoader.load(TypeMapperProvider.class,
                                           CodegenContextBase.class.getClassLoader()))
                .stream()
                .peek(it -> addSupported(it, supportedOptions, supportedPackages, supportedAnnotations))
                .map(it -> it.create(options))
                .toList();

        this.supportedOptions = Set.copyOf(supportedOptions);
        this.supportedPackages = Set.copyOf(supportedPackages);
        this.supportedAnnotations = Set.copyOf(supportedAnnotations);

        supportedOptions.forEach(it -> it.findValue(options));
    }

    @Override
    public List elementMappers() {
        return elementMappers;
    }

    @Override
    public List typeMappers() {
        return typeMappers;
    }

    @Override
    public List annotationMappers() {
        return annotationMappers;
    }

    @Override
    public Set mapperSupportedAnnotations() {
        return supportedAnnotations;
    }

    @Override
    public Set mapperSupportedAnnotationPackages() {
        return supportedPackages;
    }

    @Override
    public Set> supportedOptions() {
        return supportedOptions;
    }

    @Override
    public CodegenFiler filer() {
        return filer;
    }

    @Override
    public CodegenLogger logger() {
        return logger;
    }

    @Override
    public CodegenScope scope() {
        return scope;
    }

    @Override
    public CodegenOptions options() {
        return options;
    }

    private static void addSupported(CodegenProvider provider,
                                     Set> supportedOptions,
                                     Set supportedPackages,
                                     Set supportedAnnotations) {
        supportedOptions.addAll(provider.supportedOptions());
        supportedAnnotations.addAll(provider.supportedAnnotations());
        provider.supportedAnnotationPackages()
                .stream()
                .map(it -> it.endsWith(".*") ? it : it + ".*")
                .forEach(supportedPackages::add);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy