diff --git a/extension-base/src/main/java/com/azure/autorest/extension/base/plugin/JavaSettings.java b/extension-base/src/main/java/com/azure/autorest/extension/base/plugin/JavaSettings.java index dea5783ce4..178994ec02 100644 --- a/extension-base/src/main/java/com/azure/autorest/extension/base/plugin/JavaSettings.java +++ b/extension-base/src/main/java/com/azure/autorest/extension/base/plugin/JavaSettings.java @@ -34,7 +34,8 @@ public class JavaSettings { private static Logger logger; private final boolean useKeyCredential; - private final boolean noCustomHeaders; + private boolean noCustomHeaders; + static void setHeader(String value) { if ("MICROSOFT_MIT".equals(value)) { header = MICROSOFT_MIT_LICENSE_HEADER + "\n" + String.format(DEFAULT_CODE_GENERATION_HEADER, VERSION); @@ -170,7 +171,8 @@ public static JavaSettings getInstance() { getBooleanValue(host, "disable-required-property-annotation", false), getBooleanValue(host, "enable-page-size", false), getBooleanValue(host, "use-key-credential", false), - getBooleanValue(host, "null-byte-array-maps-to-empty-array", false) + getBooleanValue(host, "null-byte-array-maps-to-empty-array", false), + getBooleanValue(host, "graal-vm-config", false) ); } return instance; @@ -326,7 +328,8 @@ private JavaSettings(AutorestSettings autorestSettings, boolean disableRequiredPropertyAnnotation, boolean pageSizeEnabled, boolean useKeyCredential, - boolean nullByteArrayMapsToEmptyArray) { + boolean nullByteArrayMapsToEmptyArray, + boolean generateGraalVmConfig) { this.autorestSettings = autorestSettings; this.modelerSettings = new ModelerSettings(modelerSettings); @@ -425,6 +428,7 @@ private JavaSettings(AutorestSettings autorestSettings, this.pageSizeEnabled = pageSizeEnabled; this.useKeyCredential = useKeyCredential; this.nullByteArrayMapsToEmptyArray = nullByteArrayMapsToEmptyArray; + this.generateGraalVmConfig = generateGraalVmConfig; } @@ -902,6 +906,12 @@ public boolean isPageSizeEnabled() { return pageSizeEnabled; } + private final boolean generateGraalVmConfig; + + public boolean isGenerateGraalVmConfig() { + return generateGraalVmConfig; + } + public static class PollingDetails { @JsonProperty("strategy") private String strategy; diff --git a/fluentgen/src/main/java/com/azure/autorest/fluent/FluentGen.java b/fluentgen/src/main/java/com/azure/autorest/fluent/FluentGen.java index d10c7d506a..098172b5e0 100755 --- a/fluentgen/src/main/java/com/azure/autorest/fluent/FluentGen.java +++ b/fluentgen/src/main/java/com/azure/autorest/fluent/FluentGen.java @@ -272,6 +272,11 @@ FluentJavaPackage handleTemplate(Client client) { javaPackage.addPackageInfo(packageInfo.getPackage(), "package-info", packageInfo); } + // GraalVM config + if (javaSettings.isGenerateGraalVmConfig()) { + javaPackage.addGraalVmConfig("com.azure.resourcemanager", FluentUtils.getArtifactId(), client.getGraalVmConfig()); + } + // Samples if (fluentPremiumExamples != null) { for (FluentExample example : fluentPremiumExamples) { diff --git a/fluentnamer/readme.md b/fluentnamer/readme.md index e0a9fba274..692075b9da 100644 --- a/fluentnamer/readme.md +++ b/fluentnamer/readme.md @@ -62,4 +62,5 @@ client-logger: true generate-client-interfaces: true required-parameter-client-methods: true client-flattened-annotation-target: none +graal-vm-config: true ``` diff --git a/javagen/src/main/java/com/azure/autorest/Javagen.java b/javagen/src/main/java/com/azure/autorest/Javagen.java index 55e307d9df..1277596e57 100644 --- a/javagen/src/main/java/com/azure/autorest/Javagen.java +++ b/javagen/src/main/java/com/azure/autorest/Javagen.java @@ -241,6 +241,11 @@ protected JavaPackage writeToTemplates(CodeModel codeModel, Client client, JavaS } } + // GraalVM config + if (settings.isGenerateGraalVmConfig()) { + javaPackage.addGraalVmConfig(Project.AZURE_GROUP_ID, ClientModelUtil.getArtifactId(), client.getGraalVmConfig()); + } + // Service version if (settings.isDataPlaneClient()) { String packageName = settings.getPackage(); diff --git a/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java b/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java index 493783e702..5e0d32b35c 100644 --- a/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java +++ b/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java @@ -28,6 +28,7 @@ import com.azure.autorest.model.clientmodel.Client; import com.azure.autorest.model.clientmodel.ClientBuilder; import com.azure.autorest.model.clientmodel.ClientBuilderTrait; +import com.azure.autorest.model.clientmodel.ClientException; import com.azure.autorest.model.clientmodel.ClientMethod; import com.azure.autorest.model.clientmodel.ClientMethodExample; import com.azure.autorest.model.clientmodel.ClientMethodType; @@ -111,7 +112,7 @@ public Client map(CodeModel codeModel) { builder.enums(enumTypes); // exception - builder.exceptions(codeModel.getOperationGroups().stream() + List exceptions = codeModel.getOperationGroups().stream() .flatMap(og -> og.getOperations().stream()) .flatMap(o -> o.getExceptions().stream()) .map(Response::getSchema) @@ -120,7 +121,8 @@ public Client map(CodeModel codeModel) { .map(s -> Mappers.getExceptionMapper().map((ObjectSchema) s)) .filter(Objects::nonNull) .distinct() - .collect(Collectors.toList())); + .collect(Collectors.toList()); + builder.exceptions(exceptions); builder.xmlSequenceWrappers(parseXmlSequenceWrappers(codeModel, settings)); @@ -317,6 +319,13 @@ public Client map(CodeModel codeModel) { builder.liveTests(LiveTestsMapper.getInstance().map(codeModel.getTestModel())); } + builder.graalVmConfig(Mappers.getGraalVmConfigMapper() + .map(new GraalVmConfigMapper.ServiceAndModel( + serviceClientsMap.keySet(), + exceptions, + clientModels, + enumTypes))); + return builder.build(); } diff --git a/javagen/src/main/java/com/azure/autorest/mapper/DefaultMapperFactory.java b/javagen/src/main/java/com/azure/autorest/mapper/DefaultMapperFactory.java index 08a3a2e9cd..82cd709df4 100644 --- a/javagen/src/main/java/com/azure/autorest/mapper/DefaultMapperFactory.java +++ b/javagen/src/main/java/com/azure/autorest/mapper/DefaultMapperFactory.java @@ -118,4 +118,9 @@ public UnionMapper getUnionMapper() { public UnionModelMapper getUnionModelMapper() { return UnionModelMapper.getInstance(); } + + @Override + public GraalVmConfigMapper getGraalVmConfigMapper() { + return GraalVmConfigMapper.getInstance(); + } } diff --git a/javagen/src/main/java/com/azure/autorest/mapper/GraalVmConfigMapper.java b/javagen/src/main/java/com/azure/autorest/mapper/GraalVmConfigMapper.java new file mode 100644 index 0000000000..092b72a942 --- /dev/null +++ b/javagen/src/main/java/com/azure/autorest/mapper/GraalVmConfigMapper.java @@ -0,0 +1,83 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.autorest.mapper; + +import com.azure.autorest.extension.base.plugin.JavaSettings; +import com.azure.autorest.model.clientmodel.ClientException; +import com.azure.autorest.model.clientmodel.ClientModel; +import com.azure.autorest.model.clientmodel.EnumType; +import com.azure.autorest.model.clientmodel.GraalVmConfig; +import com.azure.autorest.model.clientmodel.ServiceClient; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class GraalVmConfigMapper implements IMapper { + + public static class ServiceAndModel { + private final Collection serviceClients; + private final Collection exceptions; + private final Collection models; + private final Collection enums; + + public ServiceAndModel(Collection serviceClients, + Collection exceptions, + Collection models, + Collection enums) { + this.serviceClients = serviceClients; + this.exceptions = exceptions; + this.models = models; + this.enums = enums; + } + } + + private static final GraalVmConfigMapper INSTANCE = new GraalVmConfigMapper(); + + protected GraalVmConfigMapper() { + } + + public static GraalVmConfigMapper getInstance() { + return INSTANCE; + } + + @Override + public GraalVmConfig map(ServiceAndModel data) { + List proxies; + List reflects; + + // Reflect + reflects = data.exceptions.stream() + .map(e -> e.getPackage() + "." + e.getName()) + .collect(Collectors.toList()); + if (!JavaSettings.getInstance().isStreamStyleSerialization()) { + reflects.addAll(data.models.stream() + .map(e -> e.getPackage() + "." + e.getName()) + .collect(Collectors.toList())); + reflects.addAll(data.enums.stream() + .map(m -> m.getPackage() + "." + m.getName()) + .collect(Collectors.toList())); + } + + // Proxy + proxies = data.serviceClients.stream() + .flatMap(sc -> { + if (sc.getMethodGroupClients() != null) { + return sc.getMethodGroupClients().stream(); + } else { + return Stream.empty(); + } + }) + .filter(m -> m.getProxy() != null) + .map(m -> m.getPackage() + "." + m.getClassName() + "$" + m.getProxy().getName()) + .collect(Collectors.toList()); + proxies.addAll(data.serviceClients.stream() + .filter(sc -> sc.getProxy() != null) + .map(sc -> sc.getPackage() + "." + sc.getClassName() + "$" + sc.getProxy().getName()) + .collect(Collectors.toList())); + + return new GraalVmConfig(proxies, reflects, JavaSettings.getInstance().isFluent()); + } +} diff --git a/javagen/src/main/java/com/azure/autorest/mapper/MapperFactory.java b/javagen/src/main/java/com/azure/autorest/mapper/MapperFactory.java index 99e1c832c8..08ec5d4f5c 100644 --- a/javagen/src/main/java/com/azure/autorest/mapper/MapperFactory.java +++ b/javagen/src/main/java/com/azure/autorest/mapper/MapperFactory.java @@ -50,4 +50,6 @@ public interface MapperFactory { UnionMapper getUnionMapper(); UnionModelMapper getUnionModelMapper(); + + GraalVmConfigMapper getGraalVmConfigMapper(); } diff --git a/javagen/src/main/java/com/azure/autorest/mapper/Mappers.java b/javagen/src/main/java/com/azure/autorest/mapper/Mappers.java index 86056eb040..ee41367600 100644 --- a/javagen/src/main/java/com/azure/autorest/mapper/Mappers.java +++ b/javagen/src/main/java/com/azure/autorest/mapper/Mappers.java @@ -102,4 +102,8 @@ public static UnionMapper getUnionMapper() { public static UnionModelMapper getUnionModelMapper() { return factory.getUnionModelMapper(); } + + public static GraalVmConfigMapper getGraalVmConfigMapper() { + return factory.getGraalVmConfigMapper(); + } } diff --git a/javagen/src/main/java/com/azure/autorest/model/clientmodel/Client.java b/javagen/src/main/java/com/azure/autorest/model/clientmodel/Client.java index cce341af79..a811bf30a5 100644 --- a/javagen/src/main/java/com/azure/autorest/model/clientmodel/Client.java +++ b/javagen/src/main/java/com/azure/autorest/model/clientmodel/Client.java @@ -63,6 +63,7 @@ public class Client { private final List liveTests; private final List unionModels; private final List clientMethodExamples; + private final GraalVmConfig graalVmConfig; /** * Create a new Client with the provided values. @@ -88,7 +89,8 @@ private Client(String clientName, String clientDescription, List enums ServiceClient serviceClient, List serviceClients, ModuleInfo moduleInfo, List syncClients, List asyncClients, List clientBuilders, List protocolExamples, - List liveTests, List unionModels, List clientMethodExamples + List liveTests, List unionModels, List clientMethodExamples, + GraalVmConfig graalVmConfig ) { this.clientName = clientName; this.clientDescription = clientDescription; @@ -109,6 +111,7 @@ private Client(String clientName, String clientDescription, List enums this.liveTests = liveTests; this.unionModels = unionModels; this.clientMethodExamples = clientMethodExamples; + this.graalVmConfig = graalVmConfig; } public final String getClientName() { @@ -193,6 +196,11 @@ public List getClientMethodExamples() { return clientMethodExamples; } + /** @return the Graal VM config */ + public GraalVmConfig getGraalVmConfig() { + return graalVmConfig; + } + public static class Builder { private String clientName; private String clientDescription; @@ -213,6 +221,7 @@ public static class Builder { private List liveTests = Collections.emptyList(); private List unionModels = Collections.emptyList(); private List clientMethodExamples = Collections.emptyList(); + private GraalVmConfig graalVmConfig; /** * Sets the name of this service client. @@ -394,6 +403,11 @@ public Builder liveTests(List liveTests) { return this; } + public Builder graalVmConfig(GraalVmConfig graalVmConfig) { + this.graalVmConfig = graalVmConfig; + return this; + } + public Client build() { if (serviceClient == null && !serviceClients.isEmpty()) { serviceClient = serviceClients.iterator().next(); @@ -416,7 +430,8 @@ public Client build() { protocolExamples, liveTests, unionModels, - clientMethodExamples + clientMethodExamples, + graalVmConfig ); } } diff --git a/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java new file mode 100644 index 0000000000..9ed87d6b2d --- /dev/null +++ b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java @@ -0,0 +1,88 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.autorest.model.clientmodel; + +import com.azure.autorest.util.TemplateUtil; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class GraalVmConfig { + + private final List proxies; + private final List reflects; + private final boolean fluent; + + public GraalVmConfig(List proxies, List reflects, boolean fluent) { + this.proxies = proxies; + this.reflects = reflects; + this.fluent = fluent; + } + + private static class ReflectConfig { + @JsonProperty("name") + private final String name; + @JsonProperty("allDeclaredConstructors") + private final boolean allDeclaredConstructors = true; + @JsonProperty("allDeclaredFields") + private final boolean allDeclaredFields = true; + @JsonProperty("allDeclaredMethods") + private final boolean allDeclaredMethods = true; + + private ReflectConfig(String name) { + this.name = name; + } + } + + private static class ResourceConfig { + + private static class Pattern { + @JsonProperty("pattern") + private final String pattern; + + private Pattern(String pattern) { + this.pattern = pattern; + } + } + + private static class Resource { + @JsonProperty("includes") + private final List includes; + + public Resource(List includes) { + this.includes = includes; + } + } + + @JsonProperty("resources") + private final Resource resources; + private final List bundles = Collections.emptyList(); + + private ResourceConfig(String artifactId) { + this.resources = new Resource(Collections.singletonList( + new Pattern("\\Q" + artifactId + ".properties" + "\\E"))); + } + } + + public boolean generateResourceConfig() { + return !this.fluent; + } + + // TODO: Template + public String toProxyConfigJson() { + List> result = proxies.stream().map(Collections::singletonList).collect(Collectors.toList()); + return TemplateUtil.prettyPrintToJson(result); + } + + public String toReflectConfigJson() { + List result = reflects.stream().map(ReflectConfig::new).collect(Collectors.toList()); + return TemplateUtil.prettyPrintToJson(result); + } + + public String toResourceConfigJson(String artifactId) { + return TemplateUtil.prettyPrintToJson(new ResourceConfig(artifactId)); + } +} diff --git a/javagen/src/main/java/com/azure/autorest/model/javamodel/JavaPackage.java b/javagen/src/main/java/com/azure/autorest/model/javamodel/JavaPackage.java index 1f75a42513..15f3aa9e17 100644 --- a/javagen/src/main/java/com/azure/autorest/model/javamodel/JavaPackage.java +++ b/javagen/src/main/java/com/azure/autorest/model/javamodel/JavaPackage.java @@ -13,6 +13,7 @@ import com.azure.autorest.model.clientmodel.ClientResponse; import com.azure.autorest.model.clientmodel.ClientMethodExample; import com.azure.autorest.model.clientmodel.EnumType; +import com.azure.autorest.model.clientmodel.GraalVmConfig; import com.azure.autorest.model.clientmodel.MethodGroupClient; import com.azure.autorest.model.clientmodel.ModuleInfo; import com.azure.autorest.model.clientmodel.PackageInfo; @@ -40,6 +41,7 @@ import com.azure.autorest.util.PossibleCredentialException; import org.slf4j.Logger; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -298,6 +300,21 @@ public void addTestProxyAssetsJson(Project project) { textFiles.add(textFile); } + public final void addGraalVmConfig(String groupId, String artifactId, GraalVmConfig graalVmConfig) { + String metaInfPath = Paths.get("src", "main", "resources", "META-INF", "native-image", groupId, artifactId).toString(); + + TextFile proxyConfigFile = new TextFile(Paths.get(metaInfPath, "proxy-config.json").toString(), graalVmConfig.toProxyConfigJson()); + textFiles.add(proxyConfigFile); + + TextFile reflectConfigFile = new TextFile(Paths.get(metaInfPath, "reflect-config.json").toString(), graalVmConfig.toReflectConfigJson()); + textFiles.add(reflectConfigFile); + + if (graalVmConfig.generateResourceConfig()) { + TextFile resourceConfigFile = new TextFile(Paths.get(metaInfPath, "resource-config.json").toString(), graalVmConfig.toResourceConfigJson(artifactId)); + textFiles.add(resourceConfigFile); + } + } + protected void checkDuplicateFile(String filePath) { if (filePaths.contains(filePath)) { // throw new IllegalStateException(String.format("Name conflict for output file '%1$s'.", filePath)); diff --git a/javagen/src/main/java/com/azure/autorest/model/projectmodel/Project.java b/javagen/src/main/java/com/azure/autorest/model/projectmodel/Project.java index d7c4905490..5412eba97d 100644 --- a/javagen/src/main/java/com/azure/autorest/model/projectmodel/Project.java +++ b/javagen/src/main/java/com/azure/autorest/model/projectmodel/Project.java @@ -40,10 +40,12 @@ public class Project { private static final Logger LOGGER = new PluginLogger(Javagen.getPluginInstance(), Project.class); + public static final String AZURE_GROUP_ID = "com.azure"; + protected String serviceName; protected String serviceDescription; protected String namespace; - protected String groupId = "com.azure"; + protected String groupId = AZURE_GROUP_ID; protected String artifactId; protected String version = "1.0.0-beta.1"; protected final List pomDependencyIdentifiers = new ArrayList<>(); diff --git a/javagen/src/main/java/com/azure/autorest/template/TestProxyAssetsTemplate.java b/javagen/src/main/java/com/azure/autorest/template/TestProxyAssetsTemplate.java index 3b0e76bd70..b9e8e8b7e2 100644 --- a/javagen/src/main/java/com/azure/autorest/template/TestProxyAssetsTemplate.java +++ b/javagen/src/main/java/com/azure/autorest/template/TestProxyAssetsTemplate.java @@ -4,14 +4,11 @@ package com.azure.autorest.template; import com.azure.autorest.model.projectmodel.Project; +import com.azure.autorest.util.TemplateUtil; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; public class TestProxyAssetsTemplate { - static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - private static class Assets { @JsonProperty("AssetsRepo") private String assetsRepo = "Azure/azure-sdk-assets"; @@ -42,10 +39,6 @@ public String write(Project project) { group = segments[segments.length - 1]; } asserts.setTagPrefix(String.format("java/%1$s/%2$s", group, project.getArtifactId())); - try { - return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(asserts); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + return TemplateUtil.prettyPrintToJson(asserts); } } diff --git a/javagen/src/main/java/com/azure/autorest/util/TemplateUtil.java b/javagen/src/main/java/com/azure/autorest/util/TemplateUtil.java index cdf4af9b9a..fa217006b7 100644 --- a/javagen/src/main/java/com/azure/autorest/util/TemplateUtil.java +++ b/javagen/src/main/java/com/azure/autorest/util/TemplateUtil.java @@ -19,6 +19,9 @@ import com.azure.autorest.model.javamodel.JavaFileContents; import com.azure.autorest.model.javamodel.JavaType; import com.azure.autorest.template.Templates; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import org.slf4j.Logger; import java.io.BufferedReader; @@ -37,6 +40,8 @@ public class TemplateUtil { private static final Logger LOGGER = new PluginLogger(Javagen.getPluginInstance(), TemplateUtil.class); + private static final ObjectMapper PRETTY_PRINT_MAPPER = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + // begin of constant for template replacement, used in ResourceUtil.loadTextFromResource public static final String SERVICE_NAME = "service-name"; public static final String SERVICE_DESCRIPTION = "service-description"; @@ -54,6 +59,20 @@ public class TemplateUtil { public static final String DATE_UTC = "date-utc"; // end of constant for template replacement + /** + * Print object to JSON string with indent. + * + * @param jsonObject the Java object + * @return the JSON string + */ + public static String prettyPrintToJson(Object jsonObject) { + try { + return PRETTY_PRINT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + /** * Load text from resources, with string replacement. * diff --git a/javagen/src/test/java/com/azure/autorest/template/TestProxyAssertsTemplateTests.java b/javagen/src/test/java/com/azure/autorest/template/TestProxyAssertsTemplateTests.java index 08f5072c13..bd91b4e9eb 100644 --- a/javagen/src/test/java/com/azure/autorest/template/TestProxyAssertsTemplateTests.java +++ b/javagen/src/test/java/com/azure/autorest/template/TestProxyAssertsTemplateTests.java @@ -7,6 +7,7 @@ import com.azure.autorest.model.projectmodel.Project; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Assert; import org.junit.Test; @@ -30,7 +31,7 @@ public void testAssertsTemplateWrite() throws JsonProcessingException { String output = new TestProxyAssetsTemplate().write(project); - JsonNode jsonNode = TestProxyAssetsTemplate.OBJECT_MAPPER.readTree(output); + JsonNode jsonNode = new ObjectMapper().readTree(output); Assert.assertEquals("Azure/azure-sdk-assets", jsonNode.get("AssetsRepo").asText()); Assert.assertEquals("java", jsonNode.get("AssetsRepoPrefixPath").asText()); Assert.assertEquals("java/openai/azure-ai-openai", jsonNode.get("TagPrefix").asText()); diff --git a/readme.md b/readme.md index 560de39687..2cac2cea51 100644 --- a/readme.md +++ b/readme.md @@ -71,7 +71,7 @@ Settings can be provided on the command line through `--name:value` or in a READ |`--generate-client-as-impl`|Append "Impl" to the names of service clients and method groups and place them in the `implementation` sub-package. Default is false.| |`--generate-client-interfaces`|Implies `--generate-client-as-impl` and generates interfaces for all the "Impl"s. Default is false.| |`--generate-sync-async-clients`|Implies `--generate-client-as-impl` and generates sync and async convenience layer clients for all the "Impl"s. Default is false.| -|`--generate-builder-per-client`| Requires `--generate-sync-async-clients`, and generates one ClientBuilder for each Client. Default is false.| +|`--generate-builder-per-client`|Requires `--generate-sync-async-clients`, and generates one ClientBuilder for each Client. Default is false.| |`--implementation-subpackage=STRING`|The sub-package that the Service client and Method Group client implementation classes will be put into. Default is `implementation`.| |`--models-subpackage=STRING`|The sub-package that Enums, Exceptions, and Model types will be put into. Default is `models`.| |`--sync-methods=all\|essential\|none`|Specifies mode for generating sync wrappers. Supported value are
  `essential` - generates only one sync returning body or header (default)
  `all` - generates one sync method for each async method
  `none` - does not generate any sync methods| @@ -98,6 +98,7 @@ Settings can be provided on the command line through `--name:value` or in a READ |`--use-input-stream-for-binary`|Indicates that `InputStream` is used for binary response body. By default, `BinaryData` is used.| |`--enable-page-size`|Indicates that `maxpagesize` query parameter be supplied via `byPage` API in `PagedFlux` or `PagedIterable`, instead of via client method parameter.| |`--use-key-credential`|Indicates that builder uses `KeyCredential` for API key.| +|`--graal-vm-config`|Generates GraalVM config under `resources/META-INF/native-image`.| ## Settings for minimal data-plane clients