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

net.jbock.context.StatefulParser Maven / Gradle / Ivy

There is a newer version: 5.18
Show newest version
package net.jbock.context;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import net.jbock.annotated.AnnotatedOption;
import net.jbock.annotated.AnnotatedParameter;
import net.jbock.annotated.AnnotatedParameters;
import net.jbock.convert.Mapping;
import net.jbock.processor.SourceElement;

import javax.inject.Inject;
import java.util.List;

import static javax.lang.model.element.Modifier.PRIVATE;
import static javax.lang.model.element.Modifier.STATIC;

/**
 * Defines the inner class StatefulParser
 */
@ContextScope
public class StatefulParser {

    private final StatefulParseMethod statefulParseMethod;
    private final GeneratedTypes generatedTypes;
    private final SourceElement sourceElement;
    private final List> namedOptions;
    private final List> positionalParameters;
    private final List> repeatablePositionalParameters;
    private final CommonFields commonFields;
    private final BuildMethod buildMethod;
    private final TryParseOptionMethod tryParseOptionMethod;
    private final ReadOptionNameMethod readOptionNameMethod;

    @Inject
    StatefulParser(
            GeneratedTypes generatedTypes,
            StatefulParseMethod statefulParseMethod,
            SourceElement sourceElement,
            List> namedOptions,
            List> positionalParameters,
            List> repeatablePositionalParameters,
            CommonFields commonFields,
            BuildMethod buildMethod,
            TryParseOptionMethod tryParseOptionMethod,
            ReadOptionNameMethod readOptionNameMethod) {
        this.generatedTypes = generatedTypes;
        this.statefulParseMethod = statefulParseMethod;
        this.sourceElement = sourceElement;
        this.namedOptions = namedOptions;
        this.positionalParameters = positionalParameters;
        this.repeatablePositionalParameters = repeatablePositionalParameters;
        this.commonFields = commonFields;
        this.buildMethod = buildMethod;
        this.tryParseOptionMethod = tryParseOptionMethod;
        this.readOptionNameMethod = readOptionNameMethod;
    }

    TypeSpec define() {
        TypeSpec.Builder spec = TypeSpec.classBuilder(generatedTypes.statefulParserType())
                .addModifiers(PRIVATE, STATIC)
                .addMethod(statefulParseMethod.define());
        spec.addField(commonFields.suspiciousPattern());
        if (!namedOptions.isEmpty()) {
            spec.addMethod(readOptionNameMethod.get());
            spec.addMethod(tryParseOptionMethod.get());
            spec.addMethod(privateConstructor());
            spec.addField(commonFields.optionNames());
            spec.addField(commonFields.optionParsers());
        }
        if (!positionalParameters.isEmpty()) {
            spec.addField(commonFields.params());
        }
        if (!repeatablePositionalParameters.isEmpty() || sourceElement.isSuperCommand()) {
            spec.addField(commonFields.rest());
        }
        spec.addMethod(buildMethod.get());
        return spec.build();
    }

    private MethodSpec privateConstructor() {
        CodeBlock.Builder code = CodeBlock.builder();
        for (Mapping namedOption : namedOptions) {
            String enumConstant = namedOption.enumName().enumConstant();
            for (String dashedName : namedOption.sourceMethod().names()) {
                code.addStatement("$N.put($S, $T.$L)",
                        commonFields.optionNames(), dashedName, sourceElement.optionEnumType(),
                        enumConstant);
            }
            code.addStatement("$N.put($T.$L, new $T())",
                    commonFields.optionParsers(), sourceElement.optionEnumType(),
                    enumConstant, optionParserType(namedOption));
        }
        return MethodSpec.constructorBuilder()
                .addCode(code.build())
                .build();
    }

    private ClassName optionParserType(Mapping param) {
        if (param.isRepeatable()) {
            return generatedTypes.repeatableOptionParserType();
        }
        if (param.modeFlag()) {
            return generatedTypes.flagParserType();
        }
        return generatedTypes.regularOptionParserType();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy