Skip to content

Commit c45129e

Browse files
authored
Using the ClientMethodMapper extension points and hardening the paging parameter should-hide-check (#7337)
This PR has the following changes - 1. Taking advantages of refactoring done in [#7015](#7015) for `ClientMethodMapper` there by deleting the additional code we no longer needed. 2. Centralizing the derivation and lookup of paging parameters to `PagingMetadata` and `MethodPageDetails `. 3. Removing relaxed paging parameter lookup instead using common strict lookup in all places (azure, client-core etc..). The AutoRest CI run is [green](https://dev.azure.com/azure-sdk/internal/_build/results?buildId=4878954&view=results) with this PR's last commit [80bf3a9].
1 parent fa0cd0d commit c45129e

File tree

18 files changed

+474
-1855
lines changed

18 files changed

+474
-1855
lines changed

packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/mapper/ClientMethodMapper.java

Lines changed: 89 additions & 102 deletions
Large diffs are not rendered by default.

packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/mapper/ClientMethodParameterProcessor.java

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import com.microsoft.typespec.http.client.generator.core.extension.model.codemodel.Parameter;
77
import com.microsoft.typespec.http.client.generator.core.extension.model.codemodel.Request;
8+
import com.microsoft.typespec.http.client.generator.core.extension.model.codemodel.RequestParameterLocation;
89
import com.microsoft.typespec.http.client.generator.core.model.clientmodel.ClassType;
910
import com.microsoft.typespec.http.client.generator.core.model.clientmodel.ClientMethodParameter;
1011
import com.microsoft.typespec.http.client.generator.core.model.clientmodel.GenericType;
@@ -16,41 +17,45 @@
1617
import java.util.HashMap;
1718
import java.util.List;
1819
import java.util.Map;
20+
import java.util.stream.Collectors;
21+
import java.util.stream.Stream;
1922

2023
final class ClientMethodParameterProcessor {
2124

22-
static ClientMethodParameterProcessor.Result process(Request request, List<Parameter> codeModelParameters,
23-
boolean mapFluxByteBufferToBinaryData, boolean isProtocolMethod) {
25+
static ClientMethodParametersDetails process(Request request, boolean mapFluxByteBufferToBinaryData,
26+
boolean isProtocolMethod) {
2427

25-
final List<ClientMethodParameter> parameters = new ArrayList<>();
26-
final List<String> requiredParameterExpressions = new ArrayList<>();
28+
final List<Parameter> codeModelParameters = getCodeModelParameters(request, isProtocolMethod);
29+
final List<ParametersTuple> parametersTuples = new ArrayList<>();
30+
final List<String> requiredNullableParameterExpressions = new ArrayList<>();
2731
final Map<String, String> validateParameterExpressions = new HashMap<>();
2832
final boolean isJsonPatch = MethodUtil.isContentTypeInRequest(request, "application/json-patch+json");
2933

3034
final ParametersTransformationProcessor transformationProcessor
3135
= new ParametersTransformationProcessor(isProtocolMethod);
32-
for (Parameter parameter : codeModelParameters) {
33-
final ClientMethodParameter clientMethodParameter
34-
= toClientMethodParameter(parameter, isJsonPatch, mapFluxByteBufferToBinaryData, isProtocolMethod);
35-
if (request.getSignatureParameters().contains(parameter)) {
36-
parameters.add(clientMethodParameter);
36+
for (Parameter codeModelParameter : codeModelParameters) {
37+
final ClientMethodParameter clientMethodParameter = toClientMethodParameter(codeModelParameter, isJsonPatch,
38+
mapFluxByteBufferToBinaryData, isProtocolMethod);
39+
final ParametersTuple tuple = new ParametersTuple(codeModelParameter, clientMethodParameter);
40+
if (request.getSignatureParameters().contains(codeModelParameter)) {
41+
parametersTuples.add(tuple);
3742
}
38-
transformationProcessor.addParameter(clientMethodParameter, parameter);
43+
transformationProcessor.addParameter(tuple);
3944

40-
if (!parameter.isConstant() && parameter.getGroupedBy() == null) {
45+
if (!codeModelParameter.isConstant() && codeModelParameter.getGroupedBy() == null) {
4146
final MethodParameter methodParameter;
4247
final String expression;
43-
if (parameter.getImplementation() != Parameter.ImplementationLocation.CLIENT) {
48+
if (codeModelParameter.getImplementation() != Parameter.ImplementationLocation.CLIENT) {
4449
methodParameter = clientMethodParameter;
4550
expression = methodParameter.getName();
4651
} else {
47-
ProxyMethodParameter proxyParameter = Mappers.getProxyParameterMapper().map(parameter);
52+
ProxyMethodParameter proxyParameter = Mappers.getProxyParameterMapper().map(codeModelParameter);
4853
methodParameter = proxyParameter;
4954
expression = proxyParameter.getParameterReference();
5055
}
5156

5257
if (methodParameter.isRequired() && methodParameter.isReferenceClientType()) {
53-
requiredParameterExpressions.add(expression);
58+
requiredNullableParameterExpressions.add(expression);
5459
}
5560
final String validation = methodParameter.getClientType().validate(expression);
5661
if (validation != null) {
@@ -60,8 +65,26 @@ static ClientMethodParameterProcessor.Result process(Request request, List<Param
6065
}
6166
final ParameterTransformations parameterTransformations = transformationProcessor.process(request);
6267

63-
return new ClientMethodParameterProcessor.Result(parameters, requiredParameterExpressions,
64-
validateParameterExpressions, parameterTransformations, hasNonRequiredParameters(parameters));
68+
return new ClientMethodParametersDetails(parametersTuples, requiredNullableParameterExpressions,
69+
validateParameterExpressions, parameterTransformations);
70+
}
71+
72+
private static List<Parameter> getCodeModelParameters(Request request, boolean isProtocolMethod) {
73+
final Stream<Parameter> codeModelParameters;
74+
if (isProtocolMethod) {
75+
// Required path, body, header and query parameters are allowed
76+
codeModelParameters = request.getParameters().stream().filter(p -> {
77+
RequestParameterLocation location = p.getProtocol().getHttp().getIn();
78+
return p.isRequired()
79+
&& (location == RequestParameterLocation.PATH
80+
|| location == RequestParameterLocation.BODY
81+
|| location == RequestParameterLocation.HEADER
82+
|| location == RequestParameterLocation.QUERY);
83+
});
84+
} else {
85+
codeModelParameters = request.getParameters().stream().filter(p -> !p.isFlattened());
86+
}
87+
return codeModelParameters.collect(Collectors.toList());
6588
}
6689

6790
private static ClientMethodParameter toClientMethodParameter(Parameter parameter, boolean isJsonPatch,
@@ -82,26 +105,4 @@ private static ClientMethodParameter toClientMethodParameter(Parameter parameter
82105
return clientMethodParameter;
83106
}
84107
}
85-
86-
private static boolean hasNonRequiredParameters(List<ClientMethodParameter> parameters) {
87-
return parameters.stream().anyMatch(p -> !p.isRequired() && !p.isConstant());
88-
}
89-
90-
static final class Result {
91-
final List<ClientMethodParameter> parameters;
92-
final List<String> requiredParameterExpressions;
93-
final Map<String, String> validateParameterExpressions;
94-
final ParameterTransformations parameterTransformations;
95-
final boolean hasNonRequiredParameters;
96-
97-
private Result(List<ClientMethodParameter> parameters, List<String> requiredParameterExpressions,
98-
Map<String, String> validateParameterExpressions, ParameterTransformations parameterTransformations,
99-
boolean hasNonRequiredParameters) {
100-
this.parameters = parameters;
101-
this.requiredParameterExpressions = requiredParameterExpressions;
102-
this.validateParameterExpressions = validateParameterExpressions;
103-
this.parameterTransformations = parameterTransformations;
104-
this.hasNonRequiredParameters = hasNonRequiredParameters;
105-
}
106-
}
107108
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.microsoft.typespec.http.client.generator.core.mapper;
5+
6+
import com.microsoft.typespec.http.client.generator.core.extension.model.codemodel.Parameter;
7+
import com.microsoft.typespec.http.client.generator.core.extension.model.codemodel.Request;
8+
import com.microsoft.typespec.http.client.generator.core.model.clientmodel.ClientMethod;
9+
import com.microsoft.typespec.http.client.generator.core.model.clientmodel.ClientMethodParameter;
10+
import com.microsoft.typespec.http.client.generator.core.model.clientmodel.MethodPageDetails;
11+
import com.microsoft.typespec.http.client.generator.core.model.clientmodel.ParameterTransformations;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.stream.Collectors;
15+
import java.util.stream.Stream;
16+
17+
/**
18+
* Holds the details of the parameters for a {@link ClientMethod}, produced by
19+
* {@link ClientMethodParameterProcessor#process(Request, boolean, boolean)}.
20+
*/
21+
final class ClientMethodParametersDetails {
22+
/**
23+
* The list of parameter tuples, where each tuple contains a code model {@link Parameter}
24+
* and its corresponding {@link ClientMethodParameter}.
25+
*/
26+
final List<ParametersTuple> parametersTuples;
27+
/**
28+
* The list of parameter access expressions for parameters that are required but nullable.
29+
* These expressions are used to generate checks for null values.
30+
*/
31+
final List<String> requiredNullableParameterExpressions;
32+
/**
33+
* A map associating parameter access expressions with their corresponding validation expressions.
34+
* Each entry specifies how to generate validation checks for parameter.
35+
*/
36+
final Map<String, String> validateParameterExpressions;
37+
/**
38+
* The set of parameter transformations that describe how input parameters are mapped or transformed
39+
* before being sent to the service.
40+
*/
41+
final ParameterTransformations parameterTransformations;
42+
43+
ClientMethodParametersDetails(List<ParametersTuple> parametersTuples,
44+
List<String> requiredNullableParameterExpressions, Map<String, String> validateParameterExpressions,
45+
ParameterTransformations parameterTransformations) {
46+
this.parametersTuples = parametersTuples;
47+
this.requiredNullableParameterExpressions = requiredNullableParameterExpressions;
48+
this.validateParameterExpressions = validateParameterExpressions;
49+
this.parameterTransformations = parameterTransformations;
50+
}
51+
52+
/**
53+
* Gets a stream of all parameter tuples, each containing a code model {@link Parameter}
54+
* and its corresponding {@link ClientMethodParameter}.
55+
*
56+
* @return a stream of {@link ParametersTuple}.
57+
*/
58+
Stream<ParametersTuple> getParameterTuples() {
59+
return this.parametersTuples.stream();
60+
}
61+
62+
/**
63+
* Gets a list of all {@link ClientMethodParameter} instances.
64+
*
65+
* @return a list of {@link ClientMethodParameter} instances.
66+
*/
67+
List<ClientMethodParameter> getClientMethodParameters() {
68+
return this.parametersTuples.stream().map(t -> t.clientMethodParameter).collect(Collectors.toList());
69+
}
70+
71+
/**
72+
* Retrieves the {@link ClientMethodParameter} corresponding to the given code model {@link Parameter}.
73+
*
74+
* @param codeModelParameter the code model parameter to look up.
75+
* @return the matching {@link ClientMethodParameter}, or {@code null} if not found.
76+
*/
77+
ClientMethodParameter getClientMethodParameter(Parameter codeModelParameter) {
78+
return this.parametersTuples.stream()
79+
.filter(t -> t.codeModelParameter == codeModelParameter)
80+
.map(t -> t.clientMethodParameter)
81+
.findFirst()
82+
.orElse(null);
83+
}
84+
85+
/**
86+
* Determines if there are any parameters that are optional (neither required nor constant).
87+
*
88+
* @return {@code true} if at least one non-required, non-constant parameter exists; otherwise, {@code false}.
89+
*/
90+
boolean hasNonRequiredParameters() {
91+
return this.parametersTuples.stream()
92+
.map(t -> t.clientMethodParameter)
93+
.anyMatch(p -> !p.isRequired() && !p.isConstant());
94+
}
95+
96+
/**
97+
* Determines if there are any parameters that are optional (neither required nor constant),
98+
* excluding those that should be hidden according to the provided {@link MethodPageDetails}.
99+
*
100+
* @param pageDetails the page details used to determine which parameters to exclude.
101+
* @return {@code true} if at least one non-required, non-constant, non-hidden parameter exists; otherwise,
102+
* {@code false}.
103+
*/
104+
boolean hasNonRequiredParameters(MethodPageDetails pageDetails) {
105+
return this.parametersTuples.stream()
106+
.map(t -> t.clientMethodParameter)
107+
.filter(p -> !pageDetails.shouldHideParameter(p))
108+
.anyMatch(p -> !p.isRequired() && !p.isConstant());
109+
}
110+
}

0 commit comments

Comments
 (0)