Skip to content

Commit daaf68a

Browse files
committed
feat(generator): wire transport stub delegation to resumable upload stubs
1 parent bbc408e commit daaf68a

9 files changed

Lines changed: 1033 additions & 13 deletions

File tree

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@
2929
import com.google.api.generator.gapic.composer.grpcrest.HttpJsonServiceClientTestClassComposer;
3030
import com.google.api.generator.gapic.composer.resourcename.ResourceNameHelperClassComposer;
3131
import com.google.api.generator.gapic.composer.rest.HttpJsonServiceCallableFactoryClassComposer;
32+
import com.google.api.generator.gapic.composer.rest.HttpJsonServiceResumableUploadStubClassComposer;
3233
import com.google.api.generator.gapic.composer.rest.HttpJsonServiceStubClassComposer;
3334
import com.google.api.generator.gapic.model.GapicClass;
3435
import com.google.api.generator.gapic.model.GapicContext;
3536
import com.google.api.generator.gapic.model.GapicPackageInfo;
37+
import com.google.api.generator.gapic.model.Method;
3638
import com.google.api.generator.gapic.model.ReflectConfig;
3739
import com.google.api.generator.gapic.model.Sample;
3840
import com.google.api.generator.gapic.model.Service;
@@ -91,6 +93,11 @@ public static List<GapicClass> generateStubClasses(GapicContext context) {
9193
.services()
9294
.forEach(
9395
s -> {
96+
if (s.methods().stream().anyMatch(Method::isResumableUpload)) {
97+
clazzes.add(
98+
HttpJsonServiceResumableUploadStubClassComposer.instance()
99+
.generate(context, s));
100+
}
94101
if (context.transport() == Transport.REST) {
95102
clazzes.add(
96103
com.google.api.generator.gapic.composer.rest.ServiceStubClassComposer.instance()

sdk-platform-java/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java

Lines changed: 154 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.google.api.gax.rpc.OperationCallable;
2626
import com.google.api.gax.rpc.RequestParamsBuilder;
2727
import com.google.api.gax.rpc.RequestParamsExtractor;
28+
import com.google.api.gax.rpc.ResumableUploadCallable;
2829
import com.google.api.gax.rpc.ServerStreamingCallable;
2930
import com.google.api.gax.rpc.UnaryCallable;
3031
import com.google.api.generator.engine.ast.AnnotationNode;
@@ -106,7 +107,7 @@ public abstract class AbstractTransportServiceStubClassComposer implements Class
106107
private static final List<String> AIP_STANDARDS_METHODS =
107108
ImmutableList.of(
108109
"Get", "List", "Create", "Delete", "Update", "Patch", "Insert", "AggregatedList");
109-
private static final Statement EMPTY_LINE_STATEMENT = EmptyLineStatement.create();
110+
protected static final Statement EMPTY_LINE_STATEMENT = EmptyLineStatement.create();
110111

111112
private static final String METHOD_DESCRIPTOR_NAME_PATTERN = "%sMethodDescriptor";
112113
private static final String PAGED_CALLABLE_CLASS_MEMBER_PATTERN = "%sPagedCallable";
@@ -115,6 +116,7 @@ public abstract class AbstractTransportServiceStubClassComposer implements Class
115116
private static final String CALLABLE_FACTORY_MEMBER_NAME = "callableFactory";
116117
protected static final String CALLABLE_CLASS_MEMBER_PATTERN = "%sCallable";
117118
private static final String OPERATION_CALLABLE_CLASS_MEMBER_PATTERN = "%sOperationCallable";
119+
protected static final String RESUMABLE_UPLOAD_STUB_MEMBER_NAME = "resumableUploadStub";
118120

119121
private static final ImmutableList<String> HEURISTIC_ENABLED_PACKAGES =
120122
ImmutableList.of("google.cloud.compute", "google.cloud.sql", "google.cloud.bigquery");
@@ -153,6 +155,7 @@ private static TypeStore createStaticTypes() {
153155
TimeUnit.class,
154156
TypeRegistry.class,
155157
UnaryCallable.class,
158+
ResumableUploadCallable.class,
156159
UnsupportedOperationException.class,
157160
NullMarked.class);
158161
return new TypeStore(concreteClazzes);
@@ -213,6 +216,22 @@ public GapicClass generate(GapicContext context, Service service) {
213216
}
214217
}
215218

219+
if (service.methods().stream().anyMatch(Method::isResumableUpload)) {
220+
TypeNode resumableUploadStubType =
221+
typeStore.get(String.format("HttpJson%sResumableUploadStub", service.name()));
222+
if (isResumableUploadStubNullable()) {
223+
resumableUploadStubType =
224+
TypeNode.withReference(resumableUploadStubType.reference().copyAndSetNullable(true));
225+
}
226+
classMemberVarExprs.put(
227+
RESUMABLE_UPLOAD_STUB_MEMBER_NAME,
228+
VariableExpr.withVariable(
229+
Variable.builder()
230+
.setName(RESUMABLE_UPLOAD_STUB_MEMBER_NAME)
231+
.setType(resumableUploadStubType)
232+
.build()));
233+
}
234+
216235
classMemberVarExprs.put(
217236
CALLABLE_FACTORY_MEMBER_NAME,
218237
VariableExpr.withVariable(
@@ -240,9 +259,7 @@ public GapicClass generate(GapicContext context, Service service) {
240259
callableClassMemberVarExprs,
241260
protoMethodNameToDescriptorVarExprs,
242261
classStatements);
243-
methodDefinitions.addAll(
244-
createStubOverrideMethods(
245-
classMemberVarExprs.get(BACKGROUND_RESOURCES_MEMBER_NAME), service));
262+
methodDefinitions.addAll(createStubOverrideMethods(classMemberVarExprs, service, typeStore));
246263

247264
StubCommentComposer commentComposer =
248265
new StubCommentComposer(getTransportContext().transportNames().get(0));
@@ -425,6 +442,7 @@ protected List<Statement> createMethodDescriptorVariableDecls(
425442
boolean restNumericEnumsEnabled) {
426443
return service.methods().stream()
427444
.filter(x -> x.isSupportedByTransport(getTransportContext().transport()))
445+
.filter(x -> !x.isResumableUpload())
428446
.map(
429447
m ->
430448
createMethodDescriptorVariableDecl(
@@ -454,6 +472,7 @@ protected Map<String, VariableExpr> createProtoMethodNameToDescriptorClassMember
454472
Service service, Class<?> descriptorClass) {
455473
return service.methods().stream()
456474
.filter(x -> x.isSupportedByTransport(getTransportContext().transport()))
475+
.filter(x -> !x.isResumableUpload())
457476
.collect(
458477
Collectors.toMap(
459478
Method::name,
@@ -488,6 +507,9 @@ private Map<String, VariableExpr> createCallableClassMembers(
488507
if (!protoMethod.isSupportedByTransport(getTransportContext().transport())) {
489508
continue;
490509
}
510+
if (protoMethod.isResumableUpload()) {
511+
continue;
512+
}
491513
String javaStyleProtoMethodName = JavaStyle.toLowerCamelCase(protoMethod.name());
492514
String callableName = String.format(CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName);
493515
callableClassMembers.put(callableName, getCallableExpr(protoMethod, callableName));
@@ -592,6 +614,10 @@ protected List<MethodDefinition> createClassMethods(
592614
service,
593615
classMemberVarExprs.get(getTransportContext().transportOperationsStubNames().get(0))));
594616
javaMethods.addAll(createCallableGetterMethods(callableClassMemberVarExprs));
617+
if (service.methods().stream().anyMatch(Method::isResumableUpload)) {
618+
javaMethods.addAll(
619+
createResumableUploadCallableGetterMethods(service, typeStore, classMemberVarExprs));
620+
}
595621
return javaMethods;
596622
}
597623

@@ -778,6 +804,7 @@ protected List<MethodDefinition> createConstructorMethods(
778804
Map<String, VariableExpr> javaStyleMethodNameToTransportSettingsVarExprs =
779805
service.methods().stream()
780806
.filter(x -> x.isSupportedByTransport(getTransportContext().transport()))
807+
.filter(x -> !x.isResumableUpload())
781808
.collect(
782809
Collectors.toMap(
783810
m -> JavaStyle.toLowerCamelCase(m.name()),
@@ -803,6 +830,7 @@ protected List<MethodDefinition> createConstructorMethods(
803830
secondCtorExprs.addAll(
804831
service.methods().stream()
805832
.filter(x -> x.isSupportedByTransport(getTransportContext().transport()))
833+
.filter(x -> !x.isResumableUpload())
806834
.map(
807835
m ->
808836
createTransportSettingsInitExpr(
@@ -835,6 +863,9 @@ protected List<MethodDefinition> createConstructorMethods(
835863
if (!method.isSupportedByTransport(getTransportContext().transport())) {
836864
continue;
837865
}
866+
if (method.isResumableUpload()) {
867+
continue;
868+
}
838869
secondCtorExprs.addAll(
839870
createCallableInitExprs(
840871
context,
@@ -853,6 +884,17 @@ protected List<MethodDefinition> createConstructorMethods(
853884
secondCtorExprs.clear();
854885
secondCtorStatements.add(EMPTY_LINE_STATEMENT);
855886

887+
if (service.methods().stream().anyMatch(Method::isResumableUpload)) {
888+
secondCtorStatements.addAll(
889+
createResumableUploadStubInitStatements(
890+
service,
891+
typeStore,
892+
thisExpr,
893+
classMemberVarExprs.get(RESUMABLE_UPLOAD_STUB_MEMBER_NAME),
894+
clientContextVarExpr,
895+
settingsVarExpr));
896+
}
897+
856898
secondCtorStatements.addAll(createLongRunningClient(service, typeStore));
857899

858900
// Instantiate backgroundResources.
@@ -908,6 +950,36 @@ protected List<Expr> createOperationsStubInitExpr(
908950
.build());
909951
}
910952

953+
protected List<Statement> createResumableUploadStubInitStatements(
954+
Service service,
955+
TypeStore typeStore,
956+
Expr thisExpr,
957+
VariableExpr resumableUploadStubVarExpr,
958+
VariableExpr clientContextVarExpr,
959+
VariableExpr settingsVarExpr) {
960+
TypeNode stubType =
961+
typeStore.get(String.format("HttpJson%sResumableUploadStub", service.name()));
962+
Expr createStubExpr =
963+
MethodInvocationExpr.builder()
964+
.setStaticReferenceType(stubType)
965+
.setMethodName("create")
966+
.setArguments(Arrays.asList(clientContextVarExpr, settingsVarExpr))
967+
.setReturnType(stubType)
968+
.build();
969+
return Arrays.asList(
970+
ExprStatement.withExpr(
971+
AssignmentExpr.builder()
972+
.setVariableExpr(
973+
resumableUploadStubVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build())
974+
.setValueExpr(createStubExpr)
975+
.build()),
976+
EMPTY_LINE_STATEMENT);
977+
}
978+
979+
protected boolean isResumableUploadStubNullable() {
980+
return false;
981+
}
982+
911983
protected List<Statement> createLongRunningClient(Service service, TypeStore typeStore) {
912984
return ImmutableList.of();
913985
}
@@ -1094,8 +1166,39 @@ private static List<MethodDefinition> createCallableGetterMethods(
10941166
.collect(Collectors.toList());
10951167
}
10961168

1169+
protected List<MethodDefinition> createResumableUploadCallableGetterMethods(
1170+
Service service, TypeStore typeStore, Map<String, VariableExpr> classMemberVarExprs) {
1171+
VariableExpr resumableUploadStubVarExpr =
1172+
classMemberVarExprs.get(RESUMABLE_UPLOAD_STUB_MEMBER_NAME);
1173+
return service.methods().stream()
1174+
.filter(Method::isResumableUpload)
1175+
.map(
1176+
m -> {
1177+
String javaStyleMethodName = JavaStyle.toLowerCamelCase(m.name());
1178+
String callableMethodName =
1179+
String.format(CALLABLE_CLASS_MEMBER_PATTERN, javaStyleMethodName);
1180+
TypeNode callableType = getCallableType(m);
1181+
Expr returnExpr =
1182+
MethodInvocationExpr.builder()
1183+
.setExprReferenceExpr(resumableUploadStubVarExpr)
1184+
.setMethodName(callableMethodName)
1185+
.setReturnType(callableType)
1186+
.build();
1187+
return MethodDefinition.builder()
1188+
.setIsOverride(true)
1189+
.setScope(ScopeNode.PUBLIC)
1190+
.setReturnType(callableType)
1191+
.setName(callableMethodName)
1192+
.setReturnExpr(returnExpr)
1193+
.build();
1194+
})
1195+
.collect(Collectors.toList());
1196+
}
1197+
10971198
private List<MethodDefinition> createStubOverrideMethods(
1098-
VariableExpr backgroundResourcesVarExpr, Service service) {
1199+
Map<String, VariableExpr> classMemberVarExprs, Service service, TypeStore typeStore) {
1200+
VariableExpr backgroundResourcesVarExpr =
1201+
classMemberVarExprs.get(BACKGROUND_RESOURCES_MEMBER_NAME);
10991202
Function<String, MethodDefinition.Builder> methodMakerStarterFn =
11001203
methodName ->
11011204
MethodDefinition.builder()
@@ -1135,6 +1238,9 @@ private List<MethodDefinition> createStubOverrideMethods(
11351238
// public final void close() {
11361239
// try {
11371240
// backgroundResources.close();
1241+
// if (resumableUploadStub != null) {
1242+
// resumableUploadStub.close();
1243+
// }
11381244
// } catch (RuntimeException e) {
11391245
// throw e;
11401246
// } catch (Exception e) {
@@ -1162,6 +1268,36 @@ private List<MethodDefinition> createStubOverrideMethods(
11621268
if (service.operationPollingMethod() != null) {
11631269
javaMethods.addAll(createLongRunningClientGetters());
11641270
}
1271+
1272+
List<Statement> tryBodyStatements = new ArrayList<>();
1273+
tryBodyStatements.add(
1274+
ExprStatement.withExpr(
1275+
MethodInvocationExpr.builder()
1276+
.setExprReferenceExpr(backgroundResourcesVarExpr)
1277+
.setMethodName("close")
1278+
.build()));
1279+
if (service.methods().stream().anyMatch(Method::isResumableUpload)) {
1280+
VariableExpr resumableUploadStubVarExpr =
1281+
classMemberVarExprs.get(RESUMABLE_UPLOAD_STUB_MEMBER_NAME);
1282+
Statement closeResumableUploadStubStmt =
1283+
ExprStatement.withExpr(
1284+
MethodInvocationExpr.builder()
1285+
.setExprReferenceExpr(resumableUploadStubVarExpr)
1286+
.setMethodName("close")
1287+
.build());
1288+
if (isResumableUploadStubNullable()) {
1289+
tryBodyStatements.add(
1290+
IfStatement.builder()
1291+
.setConditionExpr(
1292+
RelationalOperationExpr.notEqualToWithExprs(
1293+
resumableUploadStubVarExpr, ValueExpr.createNullExpr()))
1294+
.setBody(Arrays.asList(closeResumableUploadStubStmt))
1295+
.build());
1296+
} else {
1297+
tryBodyStatements.add(closeResumableUploadStubStmt);
1298+
}
1299+
}
1300+
11651301
javaMethods.add(
11661302
methodMakerStarterFn
11671303
.apply("close")
@@ -1170,13 +1306,7 @@ private List<MethodDefinition> createStubOverrideMethods(
11701306
.setBody(
11711307
Arrays.asList(
11721308
TryCatchStatement.builder()
1173-
.setTryBody(
1174-
Arrays.asList(
1175-
ExprStatement.withExpr(
1176-
MethodInvocationExpr.builder()
1177-
.setExprReferenceExpr(backgroundResourcesVarExpr)
1178-
.setMethodName("close")
1179-
.build())))
1309+
.setTryBody(tryBodyStatements)
11801310
.addCatch(
11811311
catchRuntimeExceptionVarExpr.toBuilder().setIsDecl(true).build(),
11821312
Arrays.asList(
@@ -1281,10 +1411,22 @@ private TypeStore createDynamicTypes(Service service, String stubPakkage) {
12811411
.collect(Collectors.toList()),
12821412
true,
12831413
getTransportContext().classNames().getServiceClientClassName(service));
1414+
if (service.methods().stream().anyMatch(Method::isResumableUpload)) {
1415+
typeStore.put(stubPakkage, String.format("HttpJson%sResumableUploadStub", service.name()));
1416+
}
12841417
return typeStore;
12851418
}
12861419

12871420
protected static TypeNode getCallableType(Method protoMethod) {
1421+
if (protoMethod.isResumableUpload()) {
1422+
return TypeNode.withReference(
1423+
ConcreteReference.builder()
1424+
.setClazz(ResumableUploadCallable.class)
1425+
.setGenerics(
1426+
Arrays.asList(
1427+
protoMethod.inputType().reference(), protoMethod.outputType().reference()))
1428+
.build());
1429+
}
12881430
TypeNode callableType = FIXED_TYPESTORE.get("UnaryCallable");
12891431
switch (protoMethod.stream()) {
12901432
case CLIENT:

0 commit comments

Comments
 (0)