diff --git a/codegen/build.gradle.kts b/codegen/build.gradle.kts index df6e5391c..11f523c7e 100644 --- a/codegen/build.gradle.kts +++ b/codegen/build.gradle.kts @@ -15,5 +15,5 @@ allprojects { group = "software.amazon.smithy.python" - version = "0.3.1" + version = "0.3.2" } diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/PythonSymbolProvider.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/PythonSymbolProvider.java index b738779c5..654d005cb 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/PythonSymbolProvider.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/PythonSymbolProvider.java @@ -351,8 +351,16 @@ public Symbol intEnumShape(IntEnumShape shape) { } private Symbol genericEnum(Shape shape) { - Symbol symbol = createGeneratedSymbolBuilder(shape, getDefaultShapeName(shape), SHAPES_FILE).build(); - return escaper.escapeSymbol(shape, symbol); + var enumSymbol = createGeneratedSymbolBuilder(shape, getDefaultShapeName(shape), SHAPES_FILE).build(); + + // We add this enum symbol as a property on a generic string/int symbol + // rather than returning the enum symbol directly because we only + // generate the enum constants for convenience. We actually want + // to pass around plain types rather than what is effectively + // a namespace class. + return createSymbolBuilder(shape, shape.isEnumShape() ? "str" : "int") + .putProperty(SymbolProperties.ENUM_SYMBOL, escaper.escapeSymbol(shape, enumSymbol)) + .build(); } @Override diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/SymbolProperties.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/SymbolProperties.java index 992b8af21..aa35a1da0 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/SymbolProperties.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/SymbolProperties.java @@ -35,6 +35,13 @@ public final class SymbolProperties { */ public static final Property STDLIB = Property.named("stdlib"); + /** + * Contains a symbol representing the class containing known enum values for the symbol. + * + *

In type signatures, the base int or str is used instead for forwards compatibility. + */ + public static final Property ENUM_SYMBOL = Property.named("enumSymbol"); + /** * Contains a symbol representing the unknown variant of a union. */ diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/EnumGenerator.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/EnumGenerator.java index b38106b96..d4b18a607 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/EnumGenerator.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/EnumGenerator.java @@ -11,6 +11,7 @@ import software.amazon.smithy.python.codegen.GenerationContext; import software.amazon.smithy.python.codegen.RuntimeTypes; import software.amazon.smithy.python.codegen.SmithyPythonDependency; +import software.amazon.smithy.python.codegen.SymbolProperties; import software.amazon.smithy.utils.SmithyInternalApi; /** @@ -36,7 +37,7 @@ public EnumGenerator(GenerationContext context, EnumShape enumShape) { @Override public void run() { - var enumSymbol = context.symbolProvider().toSymbol(shape); + var enumSymbol = context.symbolProvider().toSymbol(shape).expectProperty(SymbolProperties.ENUM_SYMBOL); context.writerDelegator().useShapeWriter(shape, writer -> { writer.addStdlibImport("enum", "StrEnum"); writer.addDependency(SmithyPythonDependency.SMITHY_CORE); diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/IntEnumGenerator.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/IntEnumGenerator.java index e9fb98ecf..771780e7b 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/IntEnumGenerator.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/IntEnumGenerator.java @@ -12,6 +12,7 @@ import software.amazon.smithy.python.codegen.PythonSettings; import software.amazon.smithy.python.codegen.RuntimeTypes; import software.amazon.smithy.python.codegen.SmithyPythonDependency; +import software.amazon.smithy.python.codegen.SymbolProperties; import software.amazon.smithy.utils.SmithyInternalApi; /** @@ -36,7 +37,7 @@ public IntEnumGenerator(GenerateIntEnumDirective { writer.addStdlibImport("enum", "IntEnum"); writer.addDependency(SmithyPythonDependency.SMITHY_CORE); diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/MemberDeserializerGenerator.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/MemberDeserializerGenerator.java index c14a93159..8e763cf87 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/MemberDeserializerGenerator.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/MemberDeserializerGenerator.java @@ -136,7 +136,9 @@ public Void integerShape(IntegerShape shape) { @Override public Void intEnumShape(IntEnumShape shape) { pushMemberState(); - var enumSymbol = context.symbolProvider().toSymbol(shape); + var enumSymbol = context.symbolProvider() + .toSymbol(shape) + .expectProperty(SymbolProperties.ENUM_SYMBOL); writer.write("$T(${deserializer:L}.read_integer(${C|}))", enumSymbol, writer.consumer(w -> writeSchema())); @@ -188,7 +190,9 @@ public Void stringShape(StringShape shape) { @Override public Void enumShape(EnumShape shape) { pushMemberState(); - var enumSymbol = context.symbolProvider().toSymbol(shape); + var enumSymbol = context.symbolProvider() + .toSymbol(shape) + .expectProperty(SymbolProperties.ENUM_SYMBOL); writer.write("$T(${deserializer:L}.read_string(${C|}))", enumSymbol, writer.consumer(w -> writeSchema())); diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/MemberErrorCorrectionGenerator.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/MemberErrorCorrectionGenerator.java index e2b9e4b4f..140894a47 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/MemberErrorCorrectionGenerator.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/MemberErrorCorrectionGenerator.java @@ -146,13 +146,17 @@ public Consumer mapShape(MapShape shape) { @Override public Consumer enumShape(EnumShape shape) { - var enumSymbol = context.symbolProvider().toSymbol(shape); + var enumSymbol = context.symbolProvider() + .toSymbol(shape) + .expectProperty(SymbolProperties.ENUM_SYMBOL); return writer -> writer.writeInline("$T._corrected(\"\")", enumSymbol); } @Override public Consumer intEnumShape(IntEnumShape shape) { - var enumSymbol = context.symbolProvider().toSymbol(shape); + var enumSymbol = context.symbolProvider() + .toSymbol(shape) + .expectProperty(SymbolProperties.ENUM_SYMBOL); // -1 is used (rather than 0) as the placeholder because it is least likely to // collide with a real member value. return writer -> writer.writeInline("$T._corrected(-1)", enumSymbol); diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/StructureGenerator.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/StructureGenerator.java index ee29f296e..996024634 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/StructureGenerator.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/StructureGenerator.java @@ -295,12 +295,14 @@ private String getDefaultValue(PythonWriter writer, MemberShape member) { return String.format("b'%s'", defaultNode.expectStringNode().getValue()); } else if (target.isEnumShape()) { // Wrap rather than emit a bare string so the value matches the field type. - var enumSymbol = symbolProvider.toSymbol(target); + var enumSymbol = symbolProvider.toSymbol(target) + .expectProperty(SymbolProperties.ENUM_SYMBOL); return String.format("%s(\"%s\")", writer.format("$T", enumSymbol), defaultNode.expectStringNode().getValue()); } else if (target.isIntEnumShape()) { - var enumSymbol = symbolProvider.toSymbol(target); + var enumSymbol = symbolProvider.toSymbol(target) + .expectProperty(SymbolProperties.ENUM_SYMBOL); return String.format("%s(%s)", writer.format("$T", enumSymbol), defaultNode.expectNumberNode().getValue()); diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/writer/PythonDelegator.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/writer/PythonDelegator.java index cc10ce5c1..0e6f5c7ca 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/writer/PythonDelegator.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/writer/PythonDelegator.java @@ -5,9 +5,13 @@ package software.amazon.smithy.python.codegen.writer; import software.amazon.smithy.build.FileManifest; +import software.amazon.smithy.codegen.core.Symbol; import software.amazon.smithy.codegen.core.SymbolProvider; import software.amazon.smithy.codegen.core.WriterDelegator; +import software.amazon.smithy.model.shapes.MemberShape; +import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.python.codegen.PythonSettings; +import software.amazon.smithy.python.codegen.SymbolProperties; import software.amazon.smithy.utils.SmithyInternalApi; /** @@ -23,7 +27,30 @@ public PythonDelegator( ) { super( fileManifest, - symbolProvider, + new EnumSymbolProviderWrapper(symbolProvider), new PythonWriter.PythonWriterFactory(settings)); } + + private static final class EnumSymbolProviderWrapper implements SymbolProvider { + + private final SymbolProvider wrapped; + + EnumSymbolProviderWrapper(SymbolProvider wrapped) { + this.wrapped = wrapped; + } + + @Override + public Symbol toSymbol(Shape shape) { + Symbol symbol = wrapped.toSymbol(shape); + if (shape.isEnumShape() || shape.isIntEnumShape()) { + symbol = symbol.expectProperty(SymbolProperties.ENUM_SYMBOL); + } + return symbol; + } + + @Override + public String toMemberName(MemberShape shape) { + return wrapped.toMemberName(shape); + } + } }