Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9232be3

Browse files
committed
[samplecode][1/3]Implement Pure Unary RPC sample code (#573)
1 parent fbd0ce7 commit 9232be3

File tree

13 files changed

+1330
-27
lines changed

13 files changed

+1330
-27
lines changed

src/main/java/com/google/api/generator/gapic/composer/Composer.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ public static List<GapicClass> generateServiceClasses(
6060
@Nonnull Map<String, ResourceName> resourceNames,
6161
@Nonnull Map<String, Message> messageTypes) {
6262
List<GapicClass> clazzes = new ArrayList<>();
63-
clazzes.addAll(generateStubClasses(service, serviceConfig, messageTypes));
64-
clazzes.addAll(generateClientSettingsClasses(service, messageTypes));
63+
clazzes.addAll(generateStubClasses(service, serviceConfig, messageTypes, resourceNames));
64+
clazzes.addAll(generateClientSettingsClasses(service, messageTypes, resourceNames));
6565
clazzes.addAll(generateMocksAndTestClasses(service, resourceNames, messageTypes));
6666
// TODO(miraleung): Generate test classes.
6767
return clazzes;
@@ -76,7 +76,10 @@ public static List<GapicClass> generateResourceNameHelperClasses(
7676
}
7777

7878
public static List<GapicClass> generateStubClasses(
79-
Service service, GapicServiceConfig serviceConfig, Map<String, Message> messageTypes) {
79+
Service service,
80+
GapicServiceConfig serviceConfig,
81+
Map<String, Message> messageTypes,
82+
Map<String, ResourceName> resourceNames) {
8083
List<GapicClass> clazzes = new ArrayList<>();
8184
clazzes.add(ServiceStubClassComposer.instance().generate(service, messageTypes));
8285
clazzes.add(
@@ -87,9 +90,10 @@ public static List<GapicClass> generateStubClasses(
8790
}
8891

8992
public static List<GapicClass> generateClientSettingsClasses(
90-
Service service, Map<String, Message> messageTypes) {
93+
Service service, Map<String, Message> messageTypes, Map<String, ResourceName> resourceNames) {
9194
List<GapicClass> clazzes = new ArrayList<>();
92-
clazzes.add(ServiceClientClassComposer.instance().generate(service, messageTypes));
95+
clazzes.add(
96+
ServiceClientClassComposer.instance().generate(service, messageTypes, resourceNames));
9397
clazzes.add(ServiceSettingsClassComposer.instance().generate(service, messageTypes));
9498
return clazzes;
9599
}

src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import com.google.api.generator.gapic.model.Method;
6363
import com.google.api.generator.gapic.model.Method.Stream;
6464
import com.google.api.generator.gapic.model.MethodArgument;
65+
import com.google.api.generator.gapic.model.ResourceName;
6566
import com.google.api.generator.gapic.model.Service;
6667
import com.google.api.generator.gapic.utils.JavaStyle;
6768
import com.google.common.annotations.VisibleForTesting;
@@ -79,12 +80,13 @@
7980
import java.util.List;
8081
import java.util.Map;
8182
import java.util.Objects;
83+
import java.util.Optional;
8284
import java.util.concurrent.TimeUnit;
8385
import java.util.function.Function;
8486
import java.util.stream.Collectors;
8587
import javax.annotation.Generated;
8688

87-
public class ServiceClientClassComposer implements ClassComposer {
89+
public class ServiceClientClassComposer {
8890
private static final ServiceClientClassComposer INSTANCE = new ServiceClientClassComposer();
8991
private static final String PAGED_RESPONSE_TYPE_NAME_PATTERN = "%sPagedResponse";
9092
private static final String CALLABLE_NAME_PATTERN = "%sCallable";
@@ -108,8 +110,8 @@ public static ServiceClientClassComposer instance() {
108110
return INSTANCE;
109111
}
110112

111-
@Override
112-
public GapicClass generate(Service service, Map<String, Message> messageTypes) {
113+
public GapicClass generate(
114+
Service service, Map<String, Message> messageTypes, Map<String, ResourceName> resourceNames) {
113115
Map<String, TypeNode> types = createTypes(service, messageTypes);
114116
String className = ClassNames.getServiceClientClassName(service);
115117
GapicClass.Kind kind = Kind.MAIN;
@@ -129,7 +131,8 @@ public GapicClass generate(Service service, Map<String, Message> messageTypes) {
129131
.setName(className)
130132
.setImplementsTypes(createClassImplements(types))
131133
.setStatements(createFieldDeclarations(service, types, hasLroClient))
132-
.setMethods(createClassMethods(service, messageTypes, types, hasLroClient))
134+
.setMethods(
135+
createClassMethods(service, messageTypes, types, resourceNames, hasLroClient))
133136
.setNestedClasses(createNestedPagingClasses(service, messageTypes, types))
134137
.build();
135138
return GapicClass.create(kind, classDef);
@@ -152,12 +155,13 @@ private static List<MethodDefinition> createClassMethods(
152155
Service service,
153156
Map<String, Message> messageTypes,
154157
Map<String, TypeNode> types,
158+
Map<String, ResourceName> resourceNames,
155159
boolean hasLroClient) {
156160
List<MethodDefinition> methods = new ArrayList<>();
157161
methods.addAll(createStaticCreatorMethods(service, types));
158162
methods.addAll(createConstructorMethods(service, types, hasLroClient));
159163
methods.addAll(createGetterMethods(service, types, hasLroClient));
160-
methods.addAll(createServiceMethods(service, messageTypes, types));
164+
methods.addAll(createServiceMethods(service, messageTypes, types, resourceNames));
161165
methods.addAll(createBackgroundResourceMethods(service, types));
162166
return methods;
163167
}
@@ -473,11 +477,16 @@ private static List<MethodDefinition> createGetterMethods(
473477
}
474478

475479
private static List<MethodDefinition> createServiceMethods(
476-
Service service, Map<String, Message> messageTypes, Map<String, TypeNode> types) {
480+
Service service,
481+
Map<String, Message> messageTypes,
482+
Map<String, TypeNode> types,
483+
Map<String, ResourceName> resourceNames) {
477484
List<MethodDefinition> javaMethods = new ArrayList<>();
478485
for (Method method : service.methods()) {
479486
if (method.stream().equals(Stream.NONE)) {
480-
javaMethods.addAll(createMethodVariants(method, messageTypes, types));
487+
javaMethods.addAll(
488+
createMethodVariants(
489+
method, getClientClassName(service), messageTypes, types, resourceNames));
481490
javaMethods.add(createMethodDefaultMethod(method, types));
482491
}
483492
if (method.hasLro()) {
@@ -492,7 +501,11 @@ private static List<MethodDefinition> createServiceMethods(
492501
}
493502

494503
private static List<MethodDefinition> createMethodVariants(
495-
Method method, Map<String, Message> messageTypes, Map<String, TypeNode> types) {
504+
Method method,
505+
String clientName,
506+
Map<String, Message> messageTypes,
507+
Map<String, TypeNode> types,
508+
Map<String, ResourceName> resourceNames) {
496509
List<MethodDefinition> javaMethods = new ArrayList<>();
497510
String methodName = JavaStyle.toLowerCamelCase(method.name());
498511
TypeNode methodInputType = method.inputType();
@@ -554,10 +567,20 @@ private static List<MethodDefinition> createMethodVariants(
554567
.setReturnType(methodOutputType)
555568
.build();
556569

570+
Optional<String> methodSampleCode = Optional.empty();
571+
if (!method.isPaged() && !method.hasLro()) {
572+
// TODO(summerji): Remove the condition check once finished the implementation on paged
573+
// sample code and lro sample code.
574+
methodSampleCode =
575+
Optional.of(
576+
ServiceClientSampleCodeComposer.composeRpcMethodHeaderSampleCode(
577+
method, types.get(clientName), signature, resourceNames));
578+
}
557579
MethodDefinition.Builder methodVariantBuilder =
558580
MethodDefinition.builder()
559581
.setHeaderCommentStatements(
560-
ServiceClientCommentComposer.createRpcMethodHeaderComment(method, signature))
582+
ServiceClientCommentComposer.createRpcMethodHeaderComment(
583+
method, signature, methodSampleCode))
561584
.setScope(ScopeNode.PUBLIC)
562585
.setIsFinal(true)
563586
.setName(String.format(method.hasLro() ? "%sAsync" : "%s", methodName))

src/main/java/com/google/api/generator/gapic/composer/ServiceClientCommentComposer.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.Arrays;
2727
import java.util.Collections;
2828
import java.util.List;
29+
import java.util.Optional;
2930
import java.util.stream.Collectors;
3031
import java.util.stream.Stream;
3132

@@ -162,16 +163,18 @@ static CommentStatement createCreateMethodStubArgComment(
162163
}
163164

164165
static List<CommentStatement> createRpcMethodHeaderComment(
165-
Method method, List<MethodArgument> methodArguments) {
166+
Method method, List<MethodArgument> methodArguments, Optional<String> sampleCode) {
166167
JavaDocComment.Builder methodJavadocBuilder = JavaDocComment.builder();
167168

168169
if (method.hasDescription()) {
169170
methodJavadocBuilder =
170171
processProtobufComment(method.description(), methodJavadocBuilder, null);
171172
}
172173

173-
// methodJavadocBuilder.addParagraph(METHOD_DESCRIPTION_SAMPLE_CODE_SUMMARY_STRING);
174-
// TODO(summerji): Add sample code here and uncomment the above.
174+
if (sampleCode.isPresent()) {
175+
methodJavadocBuilder.addParagraph(METHOD_DESCRIPTION_SAMPLE_CODE_SUMMARY_STRING);
176+
methodJavadocBuilder.addSampleCode(sampleCode.get());
177+
}
175178

176179
if (methodArguments.isEmpty()) {
177180
methodJavadocBuilder.addParam(
@@ -196,7 +199,8 @@ static List<CommentStatement> createRpcMethodHeaderComment(
196199
}
197200

198201
static List<CommentStatement> createRpcMethodHeaderComment(Method method) {
199-
return createRpcMethodHeaderComment(method, Collections.emptyList());
202+
// TODO(summerji): Refactor this method when implement default method sample code.
203+
return createRpcMethodHeaderComment(method, Collections.emptyList(), Optional.empty());
200204
}
201205

202206
static CommentStatement createMethodNoArgComment(String serviceName) {

src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,29 @@
2020
import com.google.api.generator.engine.ast.Expr;
2121
import com.google.api.generator.engine.ast.ExprStatement;
2222
import com.google.api.generator.engine.ast.MethodInvocationExpr;
23+
import com.google.api.generator.engine.ast.TryCatchStatement;
2324
import com.google.api.generator.engine.ast.TypeNode;
2425
import com.google.api.generator.engine.ast.VaporReference;
2526
import com.google.api.generator.engine.ast.Variable;
2627
import com.google.api.generator.engine.ast.VariableExpr;
2728
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;
2832
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;
2936
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;
3041

3142
public class ServiceClientSampleCodeComposer {
32-
// TODO(summerji): Add unit tests for ServiceClientSampleCodeComposer.
3343

3444
public static String composeClassHeaderCredentialsSampleCode(
45+
// TODO(summerji): Add unit tests for composeClassHeaderCredentialsSampleCode.
3546
TypeNode clientType, TypeNode settingsType) {
3647
// Initialize clientSettings with builder() method.
3748
// e.g. EchoSettings echoSettings =
@@ -105,6 +116,7 @@ public static String composeClassHeaderCredentialsSampleCode(
105116
}
106117

107118
public static String composeClassHeaderEndpointSampleCode(
119+
// TODO(summerji): Add unit tests for composeClassHeaderEndpointSampleCode.
108120
TypeNode clientType, TypeNode settingsType) {
109121
// Initialize client settings with builder() method.
110122
// e.g. EchoSettings echoSettings = EchoSettings.newBuilder().setEndpoint("myEndpoint").build();
@@ -169,4 +181,141 @@ public static String composeClassHeaderEndpointSampleCode(
169181
ExprStatement.withExpr(initSettingsVarExpr),
170182
ExprStatement.withExpr(initClientVarExpr)));
171183
}
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+
}
172321
}

src/test/java/com/google/api/generator/gapic/composer/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ TESTS = UPDATE_GOLDENS_TESTS + [
2222
"DefaultValueComposerTest",
2323
"ResourceNameTokenizerTest",
2424
"RetrySettingsComposerTest",
25+
"ServiceClientSampleCodeComposerTest",
2526
]
2627

2728
TEST_DEPS = [
@@ -38,6 +39,7 @@ TEST_DEPS = [
3839
"//src/main/java/com/google/api/generator/gapic/protoparser",
3940
"//src/test/java/com/google/api/generator/gapic/testdata:showcase_java_proto",
4041
"//src/test/java/com/google/api/generator/gapic/testdata:testgapic_java_proto",
42+
"@com_google_api_api_common//jar",
4143
"@com_google_api_gax_java//gax",
4244
"@com_google_googleapis//google/logging/v2:logging_java_proto",
4345
"@com_google_googleapis//google/pubsub/v1:pubsub_java_proto",

0 commit comments

Comments
 (0)