|
20 | 20 | import com.google.api.generator.engine.ast.Expr;
|
21 | 21 | import com.google.api.generator.engine.ast.ExprStatement;
|
22 | 22 | import com.google.api.generator.engine.ast.MethodInvocationExpr;
|
| 23 | +import com.google.api.generator.engine.ast.TryCatchStatement; |
23 | 24 | import com.google.api.generator.engine.ast.TypeNode;
|
24 | 25 | import com.google.api.generator.engine.ast.VaporReference;
|
25 | 26 | import com.google.api.generator.engine.ast.Variable;
|
26 | 27 | import com.google.api.generator.engine.ast.VariableExpr;
|
27 | 28 | import com.google.api.generator.gapic.composer.samplecode.SampleCodeWriter;
|
| 29 | +import com.google.api.generator.gapic.model.Method; |
| 30 | +import com.google.api.generator.gapic.model.MethodArgument; |
| 31 | +import com.google.api.generator.gapic.model.ResourceName; |
28 | 32 | import com.google.api.generator.gapic.utils.JavaStyle;
|
| 33 | +import com.google.common.annotations.VisibleForTesting; |
| 34 | +import com.google.common.base.Preconditions; |
| 35 | +import java.util.ArrayList; |
29 | 36 | import java.util.Arrays;
|
| 37 | +import java.util.List; |
| 38 | +import java.util.Map; |
| 39 | +import java.util.stream.Collectors; |
| 40 | +import java.util.stream.IntStream; |
30 | 41 |
|
31 | 42 | public class ServiceClientSampleCodeComposer {
|
32 |
| - // TODO(summerji): Add unit tests for ServiceClientSampleCodeComposer. |
33 | 43 |
|
34 | 44 | public static String composeClassHeaderCredentialsSampleCode(
|
| 45 | + // TODO(summerji): Add unit tests for composeClassHeaderCredentialsSampleCode. |
35 | 46 | TypeNode clientType, TypeNode settingsType) {
|
36 | 47 | // Initialize clientSettings with builder() method.
|
37 | 48 | // e.g. EchoSettings echoSettings =
|
@@ -105,6 +116,7 @@ public static String composeClassHeaderCredentialsSampleCode(
|
105 | 116 | }
|
106 | 117 |
|
107 | 118 | public static String composeClassHeaderEndpointSampleCode(
|
| 119 | + // TODO(summerji): Add unit tests for composeClassHeaderEndpointSampleCode. |
108 | 120 | TypeNode clientType, TypeNode settingsType) {
|
109 | 121 | // Initialize client settings with builder() method.
|
110 | 122 | // e.g. EchoSettings echoSettings = EchoSettings.newBuilder().setEndpoint("myEndpoint").build();
|
@@ -169,4 +181,141 @@ public static String composeClassHeaderEndpointSampleCode(
|
169 | 181 | ExprStatement.withExpr(initSettingsVarExpr),
|
170 | 182 | ExprStatement.withExpr(initClientVarExpr)));
|
171 | 183 | }
|
| 184 | + |
| 185 | + public static String composeRpcMethodHeaderSampleCode( |
| 186 | + Method method, |
| 187 | + TypeNode clientType, |
| 188 | + List<MethodArgument> arguments, |
| 189 | + Map<String, ResourceName> resourceNames) { |
| 190 | + // TODO(summerji): Add other types RPC methods' sample code. |
| 191 | + return SampleCodeWriter.write( |
| 192 | + composeUnaryRpcMethodSampleCode(method, clientType, arguments, resourceNames)); |
| 193 | + } |
| 194 | + |
| 195 | + @VisibleForTesting |
| 196 | + static TryCatchStatement composeUnaryRpcMethodSampleCode( |
| 197 | + Method method, |
| 198 | + TypeNode clientType, |
| 199 | + List<MethodArgument> arguments, |
| 200 | + Map<String, ResourceName> resourceNames) { |
| 201 | + VariableExpr clientVarExpr = |
| 202 | + VariableExpr.withVariable( |
| 203 | + Variable.builder() |
| 204 | + .setName(JavaStyle.toLowerCamelCase(clientType.reference().name())) |
| 205 | + .setType(clientType) |
| 206 | + .build()); |
| 207 | + // List of rpc method arguments' variable expressions. |
| 208 | + List<VariableExpr> rpcMethodArgVarExprs = |
| 209 | + arguments.stream() |
| 210 | + .map( |
| 211 | + arg -> |
| 212 | + VariableExpr.withVariable( |
| 213 | + Variable.builder() |
| 214 | + .setName(JavaStyle.toLowerCamelCase(arg.name())) |
| 215 | + .setType(arg.type()) |
| 216 | + .build())) |
| 217 | + .collect(Collectors.toList()); |
| 218 | + // List of rpc method arguments' default value expression. |
| 219 | + List<ResourceName> resourceNameList = |
| 220 | + resourceNames.values().stream().collect(Collectors.toList()); |
| 221 | + List<Expr> rpcMethodArgDefaultValueExprs = |
| 222 | + arguments.stream() |
| 223 | + .map( |
| 224 | + arg -> |
| 225 | + !isStringTypedResourceName(arg, resourceNames) |
| 226 | + ? DefaultValueComposer.createDefaultValue(arg, resourceNames) |
| 227 | + : MethodInvocationExpr.builder() |
| 228 | + .setExprReferenceExpr( |
| 229 | + DefaultValueComposer.createDefaultValue( |
| 230 | + resourceNames.get( |
| 231 | + arg.field().resourceReference().resourceTypeString()), |
| 232 | + resourceNameList, |
| 233 | + arg.field().name())) |
| 234 | + .setMethodName("toString") |
| 235 | + .setReturnType(TypeNode.STRING) |
| 236 | + .build()) |
| 237 | + .collect(Collectors.toList()); |
| 238 | + |
| 239 | + List<Expr> bodyExprs = new ArrayList<>(); |
| 240 | + Preconditions.checkState( |
| 241 | + rpcMethodArgVarExprs.size() == rpcMethodArgDefaultValueExprs.size(), |
| 242 | + "Expected the number of method arguments to match the number of default values."); |
| 243 | + bodyExprs.addAll( |
| 244 | + IntStream.range(0, rpcMethodArgVarExprs.size()) |
| 245 | + .mapToObj( |
| 246 | + i -> |
| 247 | + AssignmentExpr.builder() |
| 248 | + .setVariableExpr( |
| 249 | + (rpcMethodArgVarExprs.get(i)).toBuilder().setIsDecl(true).build()) |
| 250 | + .setValueExpr(rpcMethodArgDefaultValueExprs.get(i)) |
| 251 | + .build()) |
| 252 | + .collect(Collectors.toList())); |
| 253 | + // Invoke current method based on return type. |
| 254 | + // e.g. if return void, echoClient.echo(..); or, |
| 255 | + // e.g. if return other type, EchoResponse response = echoClient.echo(...); |
| 256 | + boolean returnsVoid = isProtoEmptyType(method.outputType()); |
| 257 | + if (returnsVoid) { |
| 258 | + bodyExprs.add( |
| 259 | + MethodInvocationExpr.builder() |
| 260 | + .setExprReferenceExpr(clientVarExpr) |
| 261 | + .setMethodName(JavaStyle.toLowerCamelCase(method.name())) |
| 262 | + .setArguments( |
| 263 | + rpcMethodArgVarExprs.stream().map(e -> (Expr) e).collect(Collectors.toList())) |
| 264 | + .setReturnType(clientType) |
| 265 | + .build()); |
| 266 | + } else { |
| 267 | + VariableExpr responseVarExpr = |
| 268 | + VariableExpr.withVariable( |
| 269 | + Variable.builder().setName("response").setType(method.outputType()).build()); |
| 270 | + MethodInvocationExpr clientMethodInvocationExpr = |
| 271 | + MethodInvocationExpr.builder() |
| 272 | + .setExprReferenceExpr(clientVarExpr) |
| 273 | + .setMethodName(JavaStyle.toLowerCamelCase(method.name())) |
| 274 | + .setArguments( |
| 275 | + rpcMethodArgVarExprs.stream().map(e -> (Expr) e).collect(Collectors.toList())) |
| 276 | + .setReturnType(responseVarExpr.variable().type()) |
| 277 | + .build(); |
| 278 | + bodyExprs.add( |
| 279 | + AssignmentExpr.builder() |
| 280 | + .setVariableExpr(responseVarExpr.toBuilder().setIsDecl(true).build()) |
| 281 | + .setValueExpr(clientMethodInvocationExpr) |
| 282 | + .build()); |
| 283 | + } |
| 284 | + |
| 285 | + return TryCatchStatement.builder() |
| 286 | + .setTryResourceExpr(assignClientVariableWithCreateMethodExpr(clientVarExpr)) |
| 287 | + .setTryBody( |
| 288 | + bodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())) |
| 289 | + .setIsSampleCode(true) |
| 290 | + .build(); |
| 291 | + } |
| 292 | + |
| 293 | + // ==================================Helpers===================================================// |
| 294 | + |
| 295 | + // Assign client variable expr with create client. |
| 296 | + // e.g EchoClient echoClient = EchoClient.create() |
| 297 | + private static AssignmentExpr assignClientVariableWithCreateMethodExpr( |
| 298 | + VariableExpr clientVarExpr) { |
| 299 | + return AssignmentExpr.builder() |
| 300 | + .setVariableExpr(clientVarExpr.toBuilder().setIsDecl(true).build()) |
| 301 | + .setValueExpr( |
| 302 | + MethodInvocationExpr.builder() |
| 303 | + .setStaticReferenceType(clientVarExpr.variable().type()) |
| 304 | + .setReturnType(clientVarExpr.variable().type()) |
| 305 | + .setMethodName("create") |
| 306 | + .build()) |
| 307 | + .build(); |
| 308 | + } |
| 309 | + |
| 310 | + private static boolean isStringTypedResourceName( |
| 311 | + MethodArgument arg, Map<String, ResourceName> resourceNames) { |
| 312 | + return arg.type().equals(TypeNode.STRING) |
| 313 | + && arg.field().hasResourceReference() |
| 314 | + && resourceNames.containsKey(arg.field().resourceReference().resourceTypeString()); |
| 315 | + } |
| 316 | + |
| 317 | + private static boolean isProtoEmptyType(TypeNode type) { |
| 318 | + return type.reference().pakkage().equals("com.google.protobuf") |
| 319 | + && type.reference().name().equals("Empty"); |
| 320 | + } |
172 | 321 | }
|
0 commit comments