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

software.amazon.smithy.traitcodegen.generators.EnumShapeGenerator Maven / Gradle / Ivy

/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

package software.amazon.smithy.traitcodegen.generators;

import java.util.Objects;
import java.util.function.Consumer;
import software.amazon.smithy.codegen.core.Symbol;
import software.amazon.smithy.codegen.core.SymbolProvider;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.node.Node;
import software.amazon.smithy.model.node.ToNode;
import software.amazon.smithy.model.shapes.MemberShape;
import software.amazon.smithy.model.shapes.Shape;
import software.amazon.smithy.model.traits.EnumValueTrait;
import software.amazon.smithy.traitcodegen.GenerateTraitDirective;
import software.amazon.smithy.traitcodegen.sections.ClassSection;
import software.amazon.smithy.traitcodegen.sections.EnumVariantSection;
import software.amazon.smithy.traitcodegen.writer.TraitCodegenWriter;

/**
 * Effectively sealed base class for generating a Java Enum class from a Smithy model.
 *
 * 

The two public implementations provided by this base class are: *

*
{@link StringEnumShapeGenerator}
*
Generates a java enum from a Smithy {@link software.amazon.smithy.model.shapes.EnumShape}.
*
{@link IntEnumShapeGenerator}
*
Generates a java enum from a Smithy {@link software.amazon.smithy.model.shapes.IntEnumShape}.
*
*/ abstract class EnumShapeGenerator implements Consumer { // Private constructor to make abstract class effectively sealed. private EnumShapeGenerator() {} @Override public void accept(GenerateTraitDirective directive) { directive.context().writerDelegator().useShapeWriter(directive.shape(), writer -> writeEnum(directive.shape(), directive.symbolProvider(), writer, directive.model())); } public void writeEnum(Shape enumShape, SymbolProvider provider, TraitCodegenWriter writer, Model model) { writeEnum(enumShape, provider, writer, model, true); } /** * Writes an Enum class from an enum shape. * * @param enumShape enum shape to generate enum class for. * @param provider symbol provider. * @param writer writer to write generated code to. * @param model smithy model used for code generation. * @param isStandaloneClass flag indicating if enum is a standalone class (i.e. defined in its own class file). */ public void writeEnum(Shape enumShape, SymbolProvider provider, TraitCodegenWriter writer, Model model, boolean isStandaloneClass ) { Symbol enumSymbol = provider.toSymbol(enumShape); writer.pushState(new ClassSection(enumShape)) .putContext("standalone", isStandaloneClass) .openBlock("public enum $B ${?standalone}implements $T ${/standalone}{", "}", enumSymbol, ToNode.class, () -> { writeVariants(enumShape, provider, writer); writer.newLine(); writeValueField(writer); writer.newLine(); writeConstructor(enumSymbol, writer); writeValueGetter(writer); writer.newLine(); writeFromMethod(enumSymbol, writer); // Only generate From and To Node when we are in a standalone class. if (isStandaloneClass) { writeToNode(writer); new FromNodeGenerator(writer, enumSymbol, enumShape, provider, model).run(); } }) .popState(); } abstract String getVariantTemplate(); abstract Class getValueType(); abstract Object getEnumValue(MemberShape member); private void writeVariants(Shape enumShape, SymbolProvider provider, TraitCodegenWriter writer) { for (MemberShape member : enumShape.members()) { writer.pushState(new EnumVariantSection(member)); writer.write(getVariantTemplate() + ",", provider.toMemberName(member), getEnumValue(member)); writer.popState(); } writer.write("UNKNOWN(null);"); } private void writeValueField(TraitCodegenWriter writer) { writer.write("private final $T value;", getValueType()); } private void writeValueGetter(TraitCodegenWriter writer) { writer.openBlock("public $T getValue() {", "}", getValueType(), () -> writer.writeWithNoFormatting("return value;")); } private void writeToNode(TraitCodegenWriter writer) { writer.override(); writer.openBlock("public $T toNode() {", "}", Node.class, () -> writer.write("return $T.from(value);", Node.class)); writer.newLine(); } private void writeConstructor(Symbol enumSymbol, TraitCodegenWriter writer) { writer.openBlock("$B($T value) {", "}", enumSymbol, getValueType(), () -> writer.write("this.value = value;")); writer.newLine(); } private void writeFromMethod(Symbol enumSymbol, TraitCodegenWriter writer) { writer.writeDocString(writer.format("Create a {@code $1B} from a value in a model.\n\n" + "

Any unknown value is returned as {@code UNKNOWN}.\n" + "@param value Value to create enum from.\n" + "@return Returns the {@link $1B} enum value.", enumSymbol)); writer.openBlock("public static $B from($T value) {", "}", enumSymbol, getValueType(), () -> { writer.write("$T.requireNonNull(value, \"Enum value should not be null.\");", Objects.class); writer.openBlock("for ($B val: values()) {", "}", enumSymbol, () -> writer.openBlock("if ($T.equals(val.getValue(), value)) {", "}", Objects.class, () -> writer.writeWithNoFormatting("return val;"))); writer.writeWithNoFormatting("return UNKNOWN;"); }); writer.newLine(); } /** * Generates a Java Enum class from a smithy {@link software.amazon.smithy.model.shapes.EnumShape}. */ public static final class StringEnumShapeGenerator extends EnumShapeGenerator { @Override String getVariantTemplate() { return "$L($S)"; } @Override Class getValueType() { return String.class; } @Override Object getEnumValue(MemberShape member) { return member.expectTrait(EnumValueTrait.class).expectStringValue(); } } /** * Generates a Java Enum class from a smithy {@link software.amazon.smithy.model.shapes.IntEnumShape}. */ public static final class IntEnumShapeGenerator extends EnumShapeGenerator { @Override String getVariantTemplate() { return "$L($L)"; } @Override Class getValueType() { return Integer.class; } @Override Object getEnumValue(MemberShape member) { return member.expectTrait(EnumValueTrait.class).expectIntValue(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy