Skip to content

Commit e1bb5fb

Browse files
committed
feat(generator): wire transport stub delegation to resumable upload stubs
1 parent 542f6e7 commit e1bb5fb

5 files changed

Lines changed: 697 additions & 11 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: 157 additions & 10 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(
@@ -242,7 +261,7 @@ public GapicClass generate(GapicContext context, Service service) {
242261
classStatements);
243262
methodDefinitions.addAll(
244263
createStubOverrideMethods(
245-
classMemberVarExprs.get(BACKGROUND_RESOURCES_MEMBER_NAME), service));
264+
classMemberVarExprs.get(BACKGROUND_RESOURCES_MEMBER_NAME), service, typeStore));
246265

247266
StubCommentComposer commentComposer =
248267
new StubCommentComposer(getTransportContext().transportNames().get(0));
@@ -425,6 +444,7 @@ protected List<Statement> createMethodDescriptorVariableDecls(
425444
boolean restNumericEnumsEnabled) {
426445
return service.methods().stream()
427446
.filter(x -> x.isSupportedByTransport(getTransportContext().transport()))
447+
.filter(x -> !x.isResumableUpload())
428448
.map(
429449
m ->
430450
createMethodDescriptorVariableDecl(
@@ -454,6 +474,7 @@ protected Map<String, VariableExpr> createProtoMethodNameToDescriptorClassMember
454474
Service service, Class<?> descriptorClass) {
455475
return service.methods().stream()
456476
.filter(x -> x.isSupportedByTransport(getTransportContext().transport()))
477+
.filter(x -> !x.isResumableUpload())
457478
.collect(
458479
Collectors.toMap(
459480
Method::name,
@@ -488,6 +509,9 @@ private Map<String, VariableExpr> createCallableClassMembers(
488509
if (!protoMethod.isSupportedByTransport(getTransportContext().transport())) {
489510
continue;
490511
}
512+
if (protoMethod.isResumableUpload()) {
513+
continue;
514+
}
491515
String javaStyleProtoMethodName = JavaStyle.toLowerCamelCase(protoMethod.name());
492516
String callableName = String.format(CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName);
493517
callableClassMembers.put(callableName, getCallableExpr(protoMethod, callableName));
@@ -592,6 +616,10 @@ protected List<MethodDefinition> createClassMethods(
592616
service,
593617
classMemberVarExprs.get(getTransportContext().transportOperationsStubNames().get(0))));
594618
javaMethods.addAll(createCallableGetterMethods(callableClassMemberVarExprs));
619+
if (service.methods().stream().anyMatch(Method::isResumableUpload)) {
620+
javaMethods.addAll(
621+
createResumableUploadCallableGetterMethods(service, typeStore, classMemberVarExprs));
622+
}
595623
return javaMethods;
596624
}
597625

@@ -778,6 +806,7 @@ protected List<MethodDefinition> createConstructorMethods(
778806
Map<String, VariableExpr> javaStyleMethodNameToTransportSettingsVarExprs =
779807
service.methods().stream()
780808
.filter(x -> x.isSupportedByTransport(getTransportContext().transport()))
809+
.filter(x -> !x.isResumableUpload())
781810
.collect(
782811
Collectors.toMap(
783812
m -> JavaStyle.toLowerCamelCase(m.name()),
@@ -803,6 +832,7 @@ protected List<MethodDefinition> createConstructorMethods(
803832
secondCtorExprs.addAll(
804833
service.methods().stream()
805834
.filter(x -> x.isSupportedByTransport(getTransportContext().transport()))
835+
.filter(x -> !x.isResumableUpload())
806836
.map(
807837
m ->
808838
createTransportSettingsInitExpr(
@@ -835,6 +865,9 @@ protected List<MethodDefinition> createConstructorMethods(
835865
if (!method.isSupportedByTransport(getTransportContext().transport())) {
836866
continue;
837867
}
868+
if (method.isResumableUpload()) {
869+
continue;
870+
}
838871
secondCtorExprs.addAll(
839872
createCallableInitExprs(
840873
context,
@@ -853,6 +886,17 @@ protected List<MethodDefinition> createConstructorMethods(
853886
secondCtorExprs.clear();
854887
secondCtorStatements.add(EMPTY_LINE_STATEMENT);
855888

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

858902
// Instantiate backgroundResources.
@@ -908,6 +952,36 @@ protected List<Expr> createOperationsStubInitExpr(
908952
.build());
909953
}
910954

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

1171+
protected List<MethodDefinition> createResumableUploadCallableGetterMethods(
1172+
Service service, TypeStore typeStore, Map<String, VariableExpr> classMemberVarExprs) {
1173+
VariableExpr resumableUploadStubVarExpr =
1174+
classMemberVarExprs.get(RESUMABLE_UPLOAD_STUB_MEMBER_NAME);
1175+
return service.methods().stream()
1176+
.filter(Method::isResumableUpload)
1177+
.map(
1178+
m -> {
1179+
String javaStyleMethodName = JavaStyle.toLowerCamelCase(m.name());
1180+
String callableMethodName =
1181+
String.format(CALLABLE_CLASS_MEMBER_PATTERN, javaStyleMethodName);
1182+
TypeNode callableType = getCallableType(m);
1183+
Expr returnExpr =
1184+
MethodInvocationExpr.builder()
1185+
.setExprReferenceExpr(resumableUploadStubVarExpr)
1186+
.setMethodName(callableMethodName)
1187+
.setReturnType(callableType)
1188+
.build();
1189+
return MethodDefinition.builder()
1190+
.setIsOverride(true)
1191+
.setScope(ScopeNode.PUBLIC)
1192+
.setReturnType(callableType)
1193+
.setName(callableMethodName)
1194+
.setReturnExpr(returnExpr)
1195+
.build();
1196+
})
1197+
.collect(Collectors.toList());
1198+
}
1199+
10971200
private List<MethodDefinition> createStubOverrideMethods(
1098-
VariableExpr backgroundResourcesVarExpr, Service service) {
1201+
VariableExpr backgroundResourcesVarExpr, Service service, TypeStore typeStore) {
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,41 @@ 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+
VariableExpr.withVariable(
1282+
Variable.builder()
1283+
.setName(RESUMABLE_UPLOAD_STUB_MEMBER_NAME)
1284+
.setType(
1285+
typeStore.get(String.format("HttpJson%sResumableUploadStub", service.name())))
1286+
.build());
1287+
Statement closeResumableUploadStubStmt =
1288+
ExprStatement.withExpr(
1289+
MethodInvocationExpr.builder()
1290+
.setExprReferenceExpr(resumableUploadStubVarExpr)
1291+
.setMethodName("close")
1292+
.build());
1293+
if (isResumableUploadStubNullable()) {
1294+
tryBodyStatements.add(
1295+
IfStatement.builder()
1296+
.setConditionExpr(
1297+
RelationalOperationExpr.notEqualToWithExprs(
1298+
resumableUploadStubVarExpr, ValueExpr.createNullExpr()))
1299+
.setBody(Arrays.asList(closeResumableUploadStubStmt))
1300+
.build());
1301+
} else {
1302+
tryBodyStatements.add(closeResumableUploadStubStmt);
1303+
}
1304+
}
1305+
11651306
javaMethods.add(
11661307
methodMakerStarterFn
11671308
.apply("close")
@@ -1170,13 +1311,7 @@ private List<MethodDefinition> createStubOverrideMethods(
11701311
.setBody(
11711312
Arrays.asList(
11721313
TryCatchStatement.builder()
1173-
.setTryBody(
1174-
Arrays.asList(
1175-
ExprStatement.withExpr(
1176-
MethodInvocationExpr.builder()
1177-
.setExprReferenceExpr(backgroundResourcesVarExpr)
1178-
.setMethodName("close")
1179-
.build())))
1314+
.setTryBody(tryBodyStatements)
11801315
.addCatch(
11811316
catchRuntimeExceptionVarExpr.toBuilder().setIsDecl(true).build(),
11821317
Arrays.asList(
@@ -1281,10 +1416,22 @@ private TypeStore createDynamicTypes(Service service, String stubPakkage) {
12811416
.collect(Collectors.toList()),
12821417
true,
12831418
getTransportContext().classNames().getServiceClientClassName(service));
1419+
if (service.methods().stream().anyMatch(Method::isResumableUpload)) {
1420+
typeStore.put(stubPakkage, String.format("HttpJson%sResumableUploadStub", service.name()));
1421+
}
12841422
return typeStore;
12851423
}
12861424

12871425
protected static TypeNode getCallableType(Method protoMethod) {
1426+
if (protoMethod.isResumableUpload()) {
1427+
return TypeNode.withReference(
1428+
ConcreteReference.builder()
1429+
.setClazz(ResumableUploadCallable.class)
1430+
.setGenerics(
1431+
Arrays.asList(
1432+
protoMethod.inputType().reference(), protoMethod.outputType().reference()))
1433+
.build());
1434+
}
12881435
TypeNode callableType = FIXED_TYPESTORE.get("UnaryCallable");
12891436
switch (protoMethod.stream()) {
12901437
case CLIENT:

0 commit comments

Comments
 (0)