diff --git a/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/mapper/MapperUtils.java b/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/mapper/MapperUtils.java index 72dc862ed3..eab48abe10 100644 --- a/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/mapper/MapperUtils.java +++ b/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/mapper/MapperUtils.java @@ -30,12 +30,27 @@ public final class MapperUtils { /** * Create enum client type from code model. - * @param enumType code model schema for enum - * @param expandable whether it's expandable enum + * + * @param enumType code model schema for enum + * @param expandable whether it's expandable enum * @param useCodeModelNameForEnumMember whether to use code model enum member name for client enum member name * @return enum client type */ public static IType createEnumType(ChoiceSchema enumType, boolean expandable, boolean useCodeModelNameForEnumMember) { + return createEnumType(enumType, expandable, useCodeModelNameForEnumMember, null, null); + } + + /** + * Create enum client type from code model. + * + * @param enumType code model schema for enum + * @param expandable whether it's expandable enum + * @param useCodeModelNameForEnumMember whether to use code model enum member name for client enum member name + * @param serializationMethodName method name for serialization + * @param deserializationMethodName method name for deserialization + * @return enum client type + */ + public static IType createEnumType(ChoiceSchema enumType, boolean expandable, boolean useCodeModelNameForEnumMember, String serializationMethodName, String deserializationMethodName) { JavaSettings settings = JavaSettings.getInstance(); String enumTypeName = enumType.getLanguage().getJava().getName(); @@ -82,17 +97,19 @@ public static IType createEnumType(ChoiceSchema enumType, boolean expandable, bo } return new EnumType.Builder() - .packageName(enumPackage) - .name(enumTypeName) - .description(description) - .expandable(expandable) - .values(enumValues) - .elementType(Mappers.getSchemaMapper().map(enumType.getChoiceType())) - .implementationDetails(new ImplementationDetails.Builder() - .usages(SchemaUtil.mapSchemaContext(enumType.getUsage())) - .build()) - .crossLanguageDefinitionId(enumType.getCrossLanguageDefinitionId()) - .build(); + .packageName(enumPackage) + .name(enumTypeName) + .description(description) + .expandable(expandable) + .values(enumValues) + .elementType(Mappers.getSchemaMapper().map(enumType.getChoiceType())) + .implementationDetails(new ImplementationDetails.Builder() + .usages(SchemaUtil.mapSchemaContext(enumType.getUsage())) + .build()) + .crossLanguageDefinitionId(enumType.getCrossLanguageDefinitionId()) + .fromMethodName(deserializationMethodName) + .toMethodName(serializationMethodName) + .build(); } } diff --git a/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/model/clientmodel/ClassType.java b/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/model/clientmodel/ClassType.java index 4723530ff2..0463a45160 100644 --- a/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/model/clientmodel/ClassType.java +++ b/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/model/clientmodel/ClassType.java @@ -3,6 +3,7 @@ package com.microsoft.typespec.http.client.generator.core.model.clientmodel; +import com.azure.core.util.ExpandableEnum; import com.microsoft.typespec.http.client.generator.core.extension.model.extensionmodel.XmsExtensions; import com.microsoft.typespec.http.client.generator.core.extension.plugin.JavaSettings; import com.microsoft.typespec.http.client.generator.core.util.TemplateUtil; @@ -159,6 +160,7 @@ private static ClassType.Builder getClassTypeBuilder(Class classKey) { public static final ClassType RESPONSE = getClassTypeBuilder(Response.class).build(); public static final ClassType SIMPLE_RESPONSE = getClassTypeBuilder(SimpleResponse.class).build(); public static final ClassType EXPANDABLE_STRING_ENUM = getClassTypeBuilder(ExpandableStringEnum.class).build(); + public static final ClassType EXPANDABLE_ENUM = getClassTypeBuilder(ExpandableEnum.class).build(); public static final ClassType HTTP_PIPELINE_BUILDER = getClassTypeBuilder(HttpPipelineBuilder.class).build(); public static final ClassType KEY_CREDENTIAL_POLICY = getClassTypeBuilder(KeyCredentialPolicy.class).build(); public static final ClassType KEY_CREDENTIAL_TRAIT = getClassTypeBuilder(KeyCredentialTrait.class).build(); diff --git a/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/model/clientmodel/EnumType.java b/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/model/clientmodel/EnumType.java index 010187d5f0..21140eea9c 100644 --- a/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/model/clientmodel/EnumType.java +++ b/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/model/clientmodel/EnumType.java @@ -3,6 +3,7 @@ package com.microsoft.typespec.http.client.generator.core.model.clientmodel; +import com.azure.core.util.CoreUtils; import com.microsoft.typespec.http.client.generator.core.util.CodeNamer; import java.util.List; @@ -35,19 +36,24 @@ public class EnumType implements IType { private final ImplementationDetails implementationDetails; private String crossLanguageDefinitionId; + private final String fromMethodName; + private final String toMethodName; /** * Create a new Enum with the provided properties. - * @param name The name of the new Enum. - * @param description The description of the Enum. - * @param expandable Whether this will be an ExpandableStringEnum type. - * @param values The values of the Enum. + * + * @param name The name of the new Enum. + * @param description The description of the Enum. + * @param expandable Whether this will be an ExpandableStringEnum type. + * @param values The values of the Enum. + * @param fromMethodName The method name used to convert JSON to the enum type. + * @param toMethodName The method name used to convert the enum type to JSON. */ private EnumType(String packageKeyword, String name, String description, boolean expandable, List values, IType elementType, ImplementationDetails implementationDetails, - String crossLanguageDefinitionId) { + String crossLanguageDefinitionId, String fromMethodName, String toMethodName) { this.name = name; this.packageName = packageKeyword; this.description = description; @@ -56,6 +62,8 @@ private EnumType(String packageKeyword, String name, String description, this.elementType = elementType; this.implementationDetails = implementationDetails; this.crossLanguageDefinitionId = crossLanguageDefinitionId; + this.fromMethodName = fromMethodName; + this.toMethodName = toMethodName; } public String getCrossLanguageDefinitionId() { @@ -134,7 +142,9 @@ public final String defaultValueExpression(String sourceExpression) { * @return The method name used to convert JSON to the enum type. */ public final String getFromMethodName() { - return "from" + CodeNamer.toPascalCase(elementType.getClientType().toString()); + return CoreUtils.isNullOrEmpty(fromMethodName) + ? "from" + CodeNamer.toPascalCase(elementType.getClientType().toString()) + : fromMethodName; } /** @@ -143,7 +153,9 @@ public final String getFromMethodName() { * @return The method name used to convert the enum type to JSON. */ public final String getToMethodName() { - return "to" + CodeNamer.toPascalCase(elementType.getClientType().toString()); + return CoreUtils.isNullOrEmpty(toMethodName) + ? "to" + CodeNamer.toPascalCase(elementType.getClientType().toString()) + : toMethodName; } @Override @@ -231,6 +243,8 @@ public static class Builder { private ImplementationDetails implementationDetails; private String crossLanguageDefinitionId; + private String fromMethodName; + private String toMethodName; /** * Sets the name of the Enum. @@ -309,6 +323,16 @@ public Builder crossLanguageDefinitionId(String crossLanguageDefinitionId) { return this; } + public Builder fromMethodName(String fromMethodName) { + this.fromMethodName = fromMethodName; + return this; + } + + public Builder toMethodName(String toMethodName) { + this.toMethodName = toMethodName; + return this; + } + /** * @return an immutable EnumType instance with the configurations on this builder. */ @@ -321,8 +345,8 @@ public EnumType build() { values, elementType, implementationDetails, - crossLanguageDefinitionId - ); + crossLanguageDefinitionId, + fromMethodName, toMethodName); } } } diff --git a/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/template/EnumTemplate.java b/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/template/EnumTemplate.java index 39a229a3ab..aadb608265 100644 --- a/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/template/EnumTemplate.java +++ b/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/template/EnumTemplate.java @@ -40,7 +40,7 @@ public final void write(EnumType enumType, JavaFile javaFile) { if (enumType.getExpandable()) { if(settings.isBranded()) { - writeExpandableStringEnum(enumType, javaFile, settings); + writeBrandedExpandableEnum(enumType, javaFile, settings); } else { writeExpandableStringEnumInterface(enumType, javaFile, settings); } @@ -49,6 +49,17 @@ public final void write(EnumType enumType, JavaFile javaFile) { } } + /** + * Extension point for expandable enum implementation of branded flavor. + * + * @param enumType enumType to write implementation + * @param javaFile javaFile to write into + * @param settings {@link JavaSettings} instance + */ + protected void writeBrandedExpandableEnum(EnumType enumType, JavaFile javaFile, JavaSettings settings) { + writeExpandableStringEnum(enumType, javaFile, settings); + } + private void writeExpandableStringEnumInterface(EnumType enumType, JavaFile javaFile, JavaSettings settings) { Set imports = new HashSet<>(); imports.add("java.util.Collection"); diff --git a/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/TypeSpecPlugin.java b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/TypeSpecPlugin.java index 2b15e43907..8dc661413b 100644 --- a/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/TypeSpecPlugin.java +++ b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/TypeSpecPlugin.java @@ -16,12 +16,14 @@ import com.microsoft.typespec.http.client.generator.core.model.javamodel.JavaPackage; import com.microsoft.typespec.http.client.generator.core.preprocessor.Preprocessor; import com.microsoft.typespec.http.client.generator.core.preprocessor.tranformer.Transformer; +import com.microsoft.typespec.http.client.generator.core.template.Templates; import com.microsoft.typespec.http.client.generator.core.util.ClientModelUtil; import com.azure.core.util.CoreUtils; import com.azure.json.JsonReader; import com.azure.json.ReadValueCallback; import com.microsoft.typespec.http.client.generator.mapper.TypeSpecMapperFactory; import com.microsoft.typespec.http.client.generator.model.EmitterOptions; +import com.microsoft.typespec.http.client.generator.template.TypeSpecTemplateFactory; import com.microsoft.typespec.http.client.generator.util.FileUtil; import com.microsoft.typespec.http.client.generator.util.ModelUtil; import org.slf4j.Logger; @@ -287,6 +289,7 @@ public TypeSpecPlugin(EmitterOptions options, boolean sdkIntegration) { LOGGER.info("Namespace: {}", JavaSettings.getInstance().getPackage()); Mappers.setFactory(new TypeSpecMapperFactory()); + Templates.setFactory(new TypeSpecTemplateFactory()); } @SuppressWarnings("unchecked") diff --git a/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/fluent/TypeSpecFluentMapperFactory.java b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/fluent/TypeSpecFluentMapperFactory.java index 43ba72a224..2e5093e799 100644 --- a/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/fluent/TypeSpecFluentMapperFactory.java +++ b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/fluent/TypeSpecFluentMapperFactory.java @@ -5,6 +5,7 @@ import com.microsoft.typespec.http.client.generator.core.mapper.ChoiceMapper; import com.microsoft.typespec.http.client.generator.core.mapper.SealedChoiceMapper; +import com.microsoft.typespec.http.client.generator.mapper.TypeSpecChoiceMapper; import com.microsoft.typespec.http.client.generator.mgmt.mapper.FluentMapperFactory; import com.microsoft.typespec.http.client.generator.core.mapper.ClientMapper; import com.microsoft.typespec.http.client.generator.core.mapper.ModelMapper; @@ -42,7 +43,7 @@ public ModelPropertyMapper getModelPropertyMapper() { @Override public ChoiceMapper getChoiceMapper() { - return ChoiceMapper.getInstance(); + return TypeSpecChoiceMapper.getInstance(); } @Override diff --git a/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/fluent/TypeSpecFluentPlugin.java b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/fluent/TypeSpecFluentPlugin.java index 059a9a874e..1272b060f4 100644 --- a/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/fluent/TypeSpecFluentPlugin.java +++ b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/fluent/TypeSpecFluentPlugin.java @@ -8,6 +8,7 @@ import com.microsoft.typespec.http.client.generator.core.extension.model.Message; import com.microsoft.typespec.http.client.generator.core.extension.model.codemodel.CodeModel; import com.microsoft.typespec.http.client.generator.core.extension.plugin.JavaSettings; +import com.microsoft.typespec.http.client.generator.core.template.Templates; import com.microsoft.typespec.http.client.generator.mgmt.FluentGen; import com.microsoft.typespec.http.client.generator.mgmt.mapper.FluentMapper; import com.microsoft.typespec.http.client.generator.mgmt.model.javamodel.FluentJavaPackage; @@ -89,6 +90,7 @@ public void writeFile(String fileName, String content, List sourceMap) { protected FluentMapper getFluentMapper() { FluentMapper fluentMapper = super.getFluentMapper(); Mappers.setFactory(new TypeSpecFluentMapperFactory()); + Templates.setFactory(new TypeSpecFluentTemplateFactory()); return fluentMapper; } diff --git a/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/fluent/TypeSpecFluentTemplateFactory.java b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/fluent/TypeSpecFluentTemplateFactory.java new file mode 100644 index 0000000000..9ea6e42b03 --- /dev/null +++ b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/fluent/TypeSpecFluentTemplateFactory.java @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.typespec.http.client.generator.fluent; + +import com.microsoft.typespec.http.client.generator.core.template.EnumTemplate; +import com.microsoft.typespec.http.client.generator.mgmt.template.FluentTemplateFactory; +import com.microsoft.typespec.http.client.generator.template.TypeSpecEnumTemplate; + +/** + * TypeSpec mgmt template factory. + */ +public class TypeSpecFluentTemplateFactory extends FluentTemplateFactory { + @Override + public EnumTemplate getEnumTemplate() { + return TypeSpecEnumTemplate.getInstance(); + } +} diff --git a/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/mapper/TypeSpecChoiceMapper.java b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/mapper/TypeSpecChoiceMapper.java new file mode 100644 index 0000000000..a9b7b15782 --- /dev/null +++ b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/mapper/TypeSpecChoiceMapper.java @@ -0,0 +1,29 @@ +package com.microsoft.typespec.http.client.generator.mapper; + +import com.microsoft.typespec.http.client.generator.core.extension.model.codemodel.ChoiceSchema; +import com.microsoft.typespec.http.client.generator.core.mapper.ChoiceMapper; +import com.microsoft.typespec.http.client.generator.core.mapper.MapperUtils; +import com.microsoft.typespec.http.client.generator.core.mapper.Mappers; +import com.microsoft.typespec.http.client.generator.core.model.clientmodel.ClassType; +import com.microsoft.typespec.http.client.generator.core.model.clientmodel.IType; + +public class TypeSpecChoiceMapper extends ChoiceMapper { + private static TypeSpecChoiceMapper INSTANCE = new TypeSpecChoiceMapper(); + + public static TypeSpecChoiceMapper getInstance() { + return INSTANCE; + } + private TypeSpecChoiceMapper() { + } + + @Override + public IType map(ChoiceSchema enumType) { + IType elementType = Mappers.getSchemaMapper().map(enumType.getChoiceType()); + boolean isStringEnum = elementType == ClassType.STRING; + if (isStringEnum) { + return MapperUtils.createEnumType(enumType, true, true); + } else { + return MapperUtils.createEnumType(enumType, true, true, "getValue", "fromValue"); + } + } +} diff --git a/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/mapper/TypeSpecMapperFactory.java b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/mapper/TypeSpecMapperFactory.java index 2552fbcba9..74df5b6eff 100644 --- a/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/mapper/TypeSpecMapperFactory.java +++ b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/mapper/TypeSpecMapperFactory.java @@ -3,6 +3,7 @@ package com.microsoft.typespec.http.client.generator.mapper; +import com.microsoft.typespec.http.client.generator.core.mapper.ChoiceMapper; import com.microsoft.typespec.http.client.generator.core.mapper.ClientMapper; import com.microsoft.typespec.http.client.generator.core.mapper.DefaultMapperFactory; import com.microsoft.typespec.http.client.generator.core.mapper.PrimitiveMapper; @@ -18,4 +19,9 @@ public ClientMapper getClientMapper() { public PrimitiveMapper getPrimitiveMapper() { return TypeSpecPrimitiveMapper.getInstance(); } + + @Override + public ChoiceMapper getChoiceMapper() { + return TypeSpecChoiceMapper.getInstance(); + } } diff --git a/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/template/TypeSpecEnumTemplate.java b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/template/TypeSpecEnumTemplate.java new file mode 100644 index 0000000000..f16af85edb --- /dev/null +++ b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/template/TypeSpecEnumTemplate.java @@ -0,0 +1,135 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.typespec.http.client.generator.template; + +import com.azure.core.util.CoreUtils; +import com.microsoft.typespec.http.client.generator.core.extension.plugin.JavaSettings; +import com.microsoft.typespec.http.client.generator.core.model.clientmodel.ClassType; +import com.microsoft.typespec.http.client.generator.core.model.clientmodel.ClientEnumValue; +import com.microsoft.typespec.http.client.generator.core.model.clientmodel.EnumType; +import com.microsoft.typespec.http.client.generator.core.model.clientmodel.IType; +import com.microsoft.typespec.http.client.generator.core.model.javamodel.JavaFile; +import com.microsoft.typespec.http.client.generator.core.model.javamodel.JavaModifier; +import com.microsoft.typespec.http.client.generator.core.model.javamodel.JavaVisibility; +import com.microsoft.typespec.http.client.generator.core.template.EnumTemplate; +import com.microsoft.typespec.http.client.generator.core.util.CodeNamer; + +import java.util.HashSet; +import java.util.Set; + +/** + * TypeSpec implementation for EnumTemplate. + */ +public class TypeSpecEnumTemplate extends EnumTemplate { + private static final TypeSpecEnumTemplate INSTANCE = new TypeSpecEnumTemplate(); + + public static TypeSpecEnumTemplate getInstance() { + return INSTANCE; + } + + @Override + protected void writeBrandedExpandableEnum(EnumType enumType, JavaFile javaFile, JavaSettings settings) { + if (enumType.getElementType() == ClassType.STRING) { + // if String, use ExpandableStringEnum implementation + super.writeBrandedExpandableEnum(enumType, javaFile, settings); + } else { + Set imports = new HashSet<>(); + imports.add("java.util.Collection"); + imports.add("java.lang.IllegalArgumentException"); + imports.add("java.util.Map"); + imports.add("java.util.concurrent.ConcurrentHashMap"); + imports.add("java.util.ArrayList"); + imports.add(ClassType.EXPANDABLE_ENUM.getFullName()); + if (!settings.isStreamStyleSerialization()) { + imports.add("com.fasterxml.jackson.annotation.JsonCreator"); + } + + addGeneratedImport(imports); + + javaFile.declareImport(imports); + javaFile.javadocComment(comment -> comment.description(enumType.getDescription())); + + String enumName = enumType.getName(); + IType elementType = enumType.getElementType(); + String typeName = elementType.getClientType().asNullable().toString(); + String pascalTypeName = CodeNamer.toPascalCase(typeName); + String declaration = enumName + " implements ExpandableEnum<" + pascalTypeName + ">"; + javaFile.publicFinalClass(declaration, classBlock -> { + classBlock.privateStaticFinalVariable(String.format("Map<%1$s, %2$s> VALUES = new ConcurrentHashMap<>()", pascalTypeName, enumName)); + + for (ClientEnumValue enumValue : enumType.getValues()) { + String value = enumValue.getValue(); + classBlock.javadocComment(CoreUtils.isNullOrEmpty(enumValue.getDescription()) + ? "Static value " + value + " for " + enumName + "." + : enumValue.getDescription()); + addGeneratedAnnotation(classBlock); + classBlock.publicStaticFinalVariable(String.format("%1$s %2$s = fromValue(%3$s)", enumName, + enumValue.getName(), elementType.defaultValueExpression(value))); + } + + classBlock.variable(pascalTypeName + " value", JavaVisibility.Private, JavaModifier.Final); + classBlock.privateConstructor(enumName + "(" + pascalTypeName + " value)", ctor -> { + ctor.line("this.value = value;"); + }); + + // fromValue(typeName) + classBlock.javadocComment(comment -> { + comment.description("Creates or finds a " + enumName); + comment.param("value", "a value to look for"); + comment.methodReturns("the corresponding " + enumName); + }); + + addGeneratedAnnotation(classBlock); + if (!settings.isStreamStyleSerialization()) { + classBlock.annotation("JsonCreator"); + } + + classBlock.publicStaticMethod(String.format("%1$s fromValue(%2$s value)", enumName, pascalTypeName), + function -> { + function.ifBlock("value == null", ifAction -> ifAction.line("throw new IllegalArgumentException(\"value can't be null\");")); + function.line(enumName + " member = VALUES.get(value);"); + function.ifBlock("member != null", ifAction -> { + ifAction.line("return member;"); + }); + function.methodReturn("VALUES.computeIfAbsent(value, key -> new " + enumName + "(key))"); + }); + + // values + classBlock.javadocComment(comment -> { + comment.description("Gets known " + enumName + " values."); + comment.methodReturns("Known " + enumName + " values."); + }); + addGeneratedAnnotation(classBlock); + classBlock.publicStaticMethod(String.format("Collection<%s> values()", enumName), + function -> function.methodReturn("new ArrayList<>(VALUES.values())")); + + // getValue + classBlock.javadocComment(comment -> { + comment.description("Gets the value of the " + enumName + " instance."); + comment.methodReturns("the value of the " + enumName + " instance."); + }); + + addGeneratedAnnotation(classBlock); + classBlock.annotation("Override"); + classBlock.publicMethod(pascalTypeName + " getValue()", + function -> function.methodReturn("this.value")); + + // toString + addGeneratedAnnotation(classBlock); + classBlock.annotation("Override"); + classBlock.method(JavaVisibility.Public, null, "String toString()", function -> function.methodReturn("getValue().toString()")); + + // equals + addGeneratedAnnotation(classBlock); + classBlock.annotation("Override"); + classBlock.method(JavaVisibility.Public, null, "boolean equals(Object obj)", function -> function.methodReturn(String.format("(obj instanceof %1$s) && ((%1$s) obj).getValue().equals(getValue())", enumName))); + + // hashcode + addGeneratedAnnotation(classBlock); + classBlock.annotation("Override"); + classBlock.method(JavaVisibility.Public, null, "int hashCode()", function -> function.methodReturn("getValue().hashCode()")); + }); + } + } +} diff --git a/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/template/TypeSpecTemplateFactory.java b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/template/TypeSpecTemplateFactory.java new file mode 100644 index 0000000000..bb2a6443cb --- /dev/null +++ b/packages/http-client-java/generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/template/TypeSpecTemplateFactory.java @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.typespec.http.client.generator.template; + +import com.microsoft.typespec.http.client.generator.core.template.DefaultTemplateFactory; +import com.microsoft.typespec.http.client.generator.core.template.EnumTemplate; + +/** + * TypeSpec template factory. + */ +public class TypeSpecTemplateFactory extends DefaultTemplateFactory { + @Override + public EnumTemplate getEnumTemplate() { + return TypeSpecEnumTemplate.getInstance(); + } +}