Skip to content

Commit 3dce467

Browse files
committed
feat: ExecutableSampleComposer
1 parent 6af0e18 commit 3dce467

5 files changed

Lines changed: 439 additions & 0 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.api.generator.gapic.composer.samplecode;
16+
17+
import com.google.api.generator.engine.ast.AssignmentExpr;
18+
import com.google.api.generator.engine.ast.Statement;
19+
import java.util.List;
20+
21+
public class ExecutableSample {
22+
private final String samplePackage;
23+
private final String sampleName;
24+
private final List<AssignmentExpr> sampleVariableAssignments;
25+
private final List<Statement> sampleBody;
26+
27+
public ExecutableSample(
28+
String samplePackage,
29+
String sampleName,
30+
List<AssignmentExpr> sampleVariableAssignments,
31+
List<Statement> sampleBody) {
32+
this.samplePackage = samplePackage;
33+
this.sampleName = sampleName;
34+
this.sampleVariableAssignments = sampleVariableAssignments;
35+
this.sampleBody = sampleBody;
36+
}
37+
38+
public String getSamplePackage() {
39+
return samplePackage;
40+
}
41+
42+
public String getSampleName() {
43+
return sampleName;
44+
}
45+
46+
public List<AssignmentExpr> getSampleVariableAssignments() {
47+
return sampleVariableAssignments;
48+
}
49+
50+
public List<Statement> getSampleBody() {
51+
return sampleBody;
52+
}
53+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.api.generator.gapic.composer.samplecode;
16+
17+
import com.google.api.generator.engine.ast.AssignmentExpr;
18+
import com.google.api.generator.engine.ast.ClassDefinition;
19+
import com.google.api.generator.engine.ast.Expr;
20+
import com.google.api.generator.engine.ast.ExprStatement;
21+
import com.google.api.generator.engine.ast.MethodDefinition;
22+
import com.google.api.generator.engine.ast.MethodInvocationExpr;
23+
import com.google.api.generator.engine.ast.ScopeNode;
24+
import com.google.api.generator.engine.ast.Statement;
25+
import com.google.api.generator.engine.ast.TypeNode;
26+
import com.google.api.generator.engine.ast.Variable;
27+
import com.google.api.generator.engine.ast.VariableExpr;
28+
import com.google.api.generator.gapic.utils.JavaStyle;
29+
import com.google.common.base.Preconditions;
30+
import com.google.common.collect.ImmutableList;
31+
import java.util.ArrayList;
32+
import java.util.Arrays;
33+
import java.util.List;
34+
import java.util.stream.Collectors;
35+
36+
public class ExecutableSampleComposer {
37+
public static String createExecutableSample(ExecutableSample executableSample) {
38+
Preconditions.checkNotNull(executableSample);
39+
String sampleMethodName = JavaStyle.toLowerCamelCase(executableSample.getSampleName());
40+
return SampleCodeWriter.write(
41+
composeExecutableSample(
42+
executableSample.getSamplePackage(),
43+
sampleMethodName,
44+
executableSample.getSampleVariableAssignments(),
45+
executableSample.getSampleBody()));
46+
}
47+
48+
private static ClassDefinition composeExecutableSample(
49+
String packageName,
50+
String sampleMethodName,
51+
List<AssignmentExpr> sampleVariableAssignments,
52+
List<Statement> sampleBody) {
53+
String sampleClassName = JavaStyle.toUpperCamelCase(sampleMethodName);
54+
List<VariableExpr> sampleMethodArgs = composeSampleMethodArgs(sampleVariableAssignments);
55+
MethodDefinition mainMethod =
56+
composeMainMethod(
57+
composeMainBody(
58+
sampleVariableAssignments,
59+
composeInvokeMethodStatement(sampleMethodName, sampleMethodArgs)));
60+
MethodDefinition sampleMethod =
61+
composeSampleMethod(sampleMethodName, sampleMethodArgs, sampleBody);
62+
return composeSampleClass(packageName, sampleClassName, mainMethod, sampleMethod);
63+
}
64+
65+
private static List<VariableExpr> composeSampleMethodArgs(
66+
List<AssignmentExpr> sampleVariableAssignments) {
67+
return sampleVariableAssignments.stream()
68+
.map(v -> v.variableExpr().toBuilder().setIsDecl(true).build())
69+
.collect(Collectors.toList());
70+
}
71+
72+
private static Statement composeInvokeMethodStatement(
73+
String sampleMethodName, List<VariableExpr> sampleMethodArgs) {
74+
List<Expr> invokeArgs =
75+
sampleMethodArgs.stream()
76+
.map(arg -> arg.toBuilder().setIsDecl(false).build())
77+
.collect(Collectors.toList());
78+
return ExprStatement.withExpr(
79+
MethodInvocationExpr.builder()
80+
.setMethodName(sampleMethodName)
81+
.setArguments(invokeArgs)
82+
.build());
83+
}
84+
85+
private static List<Statement> composeMainBody(
86+
List<AssignmentExpr> sampleVariableAssignments, Statement invokeMethod) {
87+
List<ExprStatement> setVariables =
88+
sampleVariableAssignments.stream()
89+
.map(var -> ExprStatement.withExpr(var))
90+
.collect(Collectors.toList());
91+
List<Statement> body = new ArrayList<>(setVariables);
92+
body.add(invokeMethod);
93+
return body;
94+
}
95+
96+
private static ClassDefinition composeSampleClass(
97+
String packageName,
98+
String sampleClassName,
99+
MethodDefinition mainMethod,
100+
MethodDefinition sampleMethod) {
101+
return ClassDefinition.builder()
102+
.setScope(ScopeNode.PUBLIC)
103+
.setPackageString(packageName)
104+
.setName(sampleClassName)
105+
.setMethods(ImmutableList.of(mainMethod, sampleMethod))
106+
.build();
107+
}
108+
109+
private static MethodDefinition composeMainMethod(List<Statement> mainBody) {
110+
return MethodDefinition.builder()
111+
.setScope(ScopeNode.PUBLIC)
112+
.setIsStatic(true)
113+
.setReturnType(TypeNode.VOID)
114+
.setName("main")
115+
.setArguments(
116+
VariableExpr.builder()
117+
.setVariable(
118+
Variable.builder().setType(TypeNode.STRING_ARRAY).setName("args").build())
119+
.setIsDecl(true)
120+
.build())
121+
.setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(Exception.class)))
122+
.setBody(mainBody)
123+
.build();
124+
}
125+
126+
private static MethodDefinition composeSampleMethod(
127+
String sampleMethodName,
128+
List<VariableExpr> sampleMethodArgs,
129+
List<Statement> sampleMethodBody) {
130+
return MethodDefinition.builder()
131+
.setScope(ScopeNode.PUBLIC)
132+
.setIsStatic(true)
133+
.setReturnType(TypeNode.VOID)
134+
.setName(sampleMethodName)
135+
.setArguments(sampleMethodArgs)
136+
.setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(Exception.class)))
137+
.setBody(sampleMethodBody)
138+
.build();
139+
}
140+
}

src/main/java/com/google/api/generator/gapic/composer/samplecode/SampleCodeWriter.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package com.google.api.generator.gapic.composer.samplecode;
1616

17+
import com.google.api.generator.engine.ast.ClassDefinition;
1718
import com.google.api.generator.engine.ast.Statement;
1819
import com.google.api.generator.engine.writer.JavaWriterVisitor;
1920
import java.util.Arrays;
@@ -34,4 +35,10 @@ public static String write(List<Statement> statements) {
3435
// Escape character "@" in the markdown code block <pre>{@code...} tags.
3536
return formattedSampleCode.replaceAll("@", "{@literal @}");
3637
}
38+
39+
public static String write(ClassDefinition classDefinition) {
40+
JavaWriterVisitor visitor = new JavaWriterVisitor();
41+
classDefinition.accept(visitor);
42+
return visitor.write();
43+
}
3744
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ TESTS = [
77
"SampleCodeWriterTest",
88
"ServiceClientSampleCodeComposerTest",
99
"SettingsSampleCodeComposerTest",
10+
"ExecutableSampleComposerTest"
1011
]
1112

1213
filegroup(

0 commit comments

Comments
 (0)