Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: patch prototype for snippetgen phase 2 #1190

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a26c58c
feat: patch prototype for snippetgen phase 2
alicejli Dec 21, 2022
b5ac10e
Merge branch 'main' into patchPrototypeSnippetGenPhase2
alicejli Dec 28, 2022
22fafb3
fix: update directory structure for unit tests
alicejli Dec 28, 2022
0ad062d
linter
alicejli Dec 28, 2022
cd76770
Merge branch 'main' into patchPrototypeSnippetGenPhase2
alicejli Dec 28, 2022
e214395
move speech integration test directory
alicejli Dec 28, 2022
bdcb7c6
Merge branch 'main' into patchPrototypeSnippetGenPhase2
alicejli Jan 3, 2023
90a26ed
update golden file directories for tests
alicejli Jan 4, 2023
1647894
Merge branch 'main' into patchPrototypeSnippetGenPhase2
alicejli Jan 5, 2023
0b18102
fix imports for configured snippet
alicejli Jan 5, 2023
70b3939
remove extraneous files and update javadoc comment and request variables
alicejli Jan 6, 2023
75fb853
rebasing
alicejli Jan 9, 2023
3511c29
update comments
alicejli Jan 9, 2023
3439d20
run linter
alicejli Jan 9, 2023
a54e97f
merge to main
alicejli Jan 12, 2023
962e3b6
updates to composer
alicejli Jan 12, 2023
2f9b904
linter
alicejli Jan 12, 2023
41c6829
Merge branch 'main' of https://github.com/googleapis/gapic-generator-…
alicejli Jan 17, 2023
f054fbe
add comment to BUILD file for newly added integration test
alicejli Jan 17, 2023
0ec16fc
change bodyWithComment back to private method
alicejli Jan 19, 2023
7d113b8
Merge branch 'main' into patchPrototypeSnippetGenPhase2
alicejli Jan 26, 2023
1085868
Merge branch 'main' into patchPrototypeSnippetGenPhase2
alicejli Jan 26, 2023
2acf2d7
refactoring
alicejli Jan 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.google.api.generator.engine.ast.ExprStatement;
import com.google.api.generator.engine.ast.Statement;
import com.google.api.generator.engine.writer.JavaWriterVisitor;
import com.google.api.generator.gapic.model.GapicSnippetConfig;
import com.google.api.generator.gapic.model.Sample;
import com.google.common.annotations.VisibleForTesting;
import java.util.Arrays;
Expand All @@ -34,6 +35,10 @@ public static String writeExecutableSample(Sample sample, String packkage) {
return write(SampleComposer.composeExecutableSample(sample, packkage));
}

public static String writeConfiguredSnippet(GapicSnippetConfig snippetConfig) {
return write(ConfiguredSnippetComposer.composeConfiguredSnippetClass(snippetConfig));
}

@VisibleForTesting
public static String write(Statement... statement) {
return write(Arrays.asList(statement));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ private static ClassDefinition createExecutableSample(
fileHeader, packageName, sampleClassName, mainMethod, sampleMethod, regionTag);
}

private static List<VariableExpr> composeSampleMethodArgs(
public static List<VariableExpr> composeSampleMethodArgs(
List<AssignmentExpr> sampleVariableAssignments) {
return sampleVariableAssignments.stream()
.map(v -> v.variableExpr().toBuilder().setIsDecl(true).build())
.collect(Collectors.toList());
}

private static Statement composeInvokeMethodStatement(
public static Statement composeInvokeMethodStatement(
String sampleMethodName, List<VariableExpr> sampleMethodArgs) {
List<Expr> invokeArgs =
sampleMethodArgs.stream()
Expand All @@ -101,7 +101,7 @@ private static Statement composeInvokeMethodStatement(
.build());
}

private static List<Statement> composeMainBody(
public static List<Statement> composeMainBody(
List<AssignmentExpr> sampleVariableAssignments, Statement invokeMethod) {
List<ExprStatement> setVariables =
sampleVariableAssignments.stream()
Expand Down Expand Up @@ -129,7 +129,7 @@ private static ClassDefinition composeSampleClass(
.build();
}

private static MethodDefinition composeMainMethod(List<Statement> mainBody) {
public static MethodDefinition composeMainMethod(List<Statement> mainBody) {
return MethodDefinition.builder()
.setScope(ScopeNode.PUBLIC)
.setIsStatic(true)
Expand All @@ -146,7 +146,7 @@ private static MethodDefinition composeMainMethod(List<Statement> mainBody) {
.build();
}

private static MethodDefinition composeSampleMethod(
public static MethodDefinition composeSampleMethod(
String sampleMethodName,
List<VariableExpr> sampleMethodArgs,
List<Statement> sampleMethodBody) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,26 @@
package com.google.api.generator.gapic.composer.samplecode;

import com.google.api.generator.engine.ast.AssignmentExpr;
import com.google.api.generator.engine.ast.ConcreteReference;
import com.google.api.generator.engine.ast.Expr;
import com.google.api.generator.engine.ast.ExprStatement;
import com.google.api.generator.engine.ast.ForStatement;
import com.google.api.generator.engine.ast.MethodInvocationExpr;
import com.google.api.generator.engine.ast.Statement;
import com.google.api.generator.engine.ast.StringObjectValue;
import com.google.api.generator.engine.ast.TypeNode;
import com.google.api.generator.engine.ast.ValueExpr;
import com.google.api.generator.engine.ast.VaporReference;
import com.google.api.generator.engine.ast.Variable;
import com.google.api.generator.engine.ast.VariableExpr;
import com.google.api.generator.gapic.model.GapicSnippetConfig;
import com.google.api.generator.gapic.model.MethodArgument;
import com.google.api.generator.gapic.model.ResourceName;
import com.google.api.generator.gapic.model.Sample;
import com.google.api.generator.gapic.utils.JavaStyle;
import com.google.cloud.tools.snippetgen.configlanguage.v1.Expression;
import com.google.cloud.tools.snippetgen.configlanguage.v1.Type;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -110,4 +123,265 @@ public static List<Sample> handleDuplicateSamples(List<Sample> samples) {
}
return uniqueSamples;
}

// Convert Type to String for use as Return Type in configured sample. Handles Scalar, Enum, and
// Message Types.
// TODO: Handle RepeatedType (P1), MapType (P1), BytesType (P3)
public static String convertTypeToString(Type type) {
if (type.hasMessageType()) {
return type.getMessageType().getMessageFullName();
}
if (type.hasScalarType()) {
return type.getScalarType().name();
}
if (type.hasEnumType()) {
return type.getEnumType().getEnumFullName();
} else {
return "";
}
}

// If the return type is a message Type, need to do additional parsing to get return Type for
// sample method
public static String convertTypeToReturnType(String type) {
String[] splitString = type.split("\\.");
return splitString[splitString.length - 1];
}

// Handle configLanguage.Type conversion
// Handles Scalar, Enum, and Message Types
// TODO: Handle Repeated type (P1), Map type (P1), and Bytes type (P3)

// Convert configLanguage.Type to TypeNode
// https://developers.google.com/protocol-buffers/docs/proto3#scalar
public static TypeNode convertScalarTypeToTypeNode(Type.ScalarType configType) {
switch (configType) {
case TYPE_BOOL:
return TypeNode.BOOLEAN;
case TYPE_FLOAT:
return TypeNode.FLOAT;
case TYPE_INT64:
case TYPE_FIXED64:
case TYPE_SFIXED64:
case TYPE_SINT64:
return TypeNode.LONG;
case TYPE_UINT64:
case TYPE_INT32:
case TYPE_FIXED32:
case TYPE_UINT32:
case TYPE_SFIXED32:
case TYPE_SINT32:
return TypeNode.INT;
default:
return TypeNode.STRING;
}
}

// Convert configLanguage.Type to java.Lang type in string
// https://developers.google.com/protocol-buffers/docs/proto3#scalar
public static String convertScalarTypeToJavaTypeString(Type.ScalarType configType) {
switch (configType) {
case TYPE_BOOL:
return ("Boolean");
case TYPE_FLOAT:
return ("Float");
case TYPE_INT64:
case TYPE_FIXED64:
case TYPE_SFIXED64:
case TYPE_SINT64:
return ("Long");
case TYPE_UINT64:
case TYPE_INT32:
case TYPE_FIXED32:
case TYPE_UINT32:
case TYPE_SFIXED32:
case TYPE_SINT32:
return ("Int");
default:
return ("String");
}
}

// Convert config.Language Expression to String
// Currently handles Boolean, String, NameValue Expressions
// TODO: add handling for ComplexValue (P0), Enum (P0), Number (P0), NameValue with Path (P1),
// ListValue (P1), MapValue (P1), ConditionalValue (P2), NullValue (P2), BytesValue (P3), and
// DefaultValue (P3)
public static String convertExpressionToString(Expression expression) {
if (expression.hasBooleanValue()) {
return String.valueOf(expression.getBooleanValue());
}
if (expression.hasStringValue()) {
return expression.getStringValue();
}
if (expression.hasNameValue()) {
String name = JavaStyle.toLowerCamelCase(expression.getNameValue().getName());
String path =
JavaStyle.toUpperCamelCase(
expression.getNameValue().getPathList().stream().collect(Collectors.joining(".")));
if (path.length() > 0) {
path = ".get" + path + "()";
}
return name + path;
}
if (expression.hasComplexValue()) {
return expression.getComplexValue().getPropertiesMap().toString();
} else {
return null;
}
}

// Convert configLanguage.Statement to Statement
// Handles Standard Output, Return, Declaration, and Declaration Assignment Statements
// TODO: Handle Iteration.Repeated (P1), Iteration.Map (P1), Conditional (P2),
// Iteration.NumberSequence (P2), and Iteration.bytes (P3) Statements
// Currently only works for repeated_iteration
// List<CustomClass.ClassItem> itemsList = createdCustomClass.getItemsList();
// for(items : itemsList){
// System.out.println(item)
// }
public static Statement convertIterationTypeStatementToStatement(
com.google.cloud.tools.snippetgen.configlanguage.v1.Statement statement) {
if (statement.hasIteration() && statement.getIteration().hasRepeatedIteration()) {
String name = statement.getIteration().getRepeatedIteration().getCurrentName();
// String element =
// statement.getIteration().getRepeatedIteration().getRepeatedElements();
TypeNode iterationType =
TypeNode.withReference(
VaporReference.builder()
.setName("ClassItem")
.setPakkage("com.google.cloud.speech.v1.CustomClass")
.build());

Variable variable = Variable.builder().setName(name).setType(iterationType).build();
VariableExpr variableExpr =
VariableExpr.builder().setVariable(variable).setIsDecl(true).build();

VariableExpr objVariableExpr =
VariableExpr.builder()
.setVariable(
Variable.builder().setType(TypeNode.OBJECT).setName("createdCustomClass").build())
.setIsDecl(true)
.build();

MethodInvocationExpr methodExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(objVariableExpr.toBuilder().setIsDecl(false).build())
.setMethodName("getItemsList")
.build();

Statement BodyStatement = ExprStatement.withExpr(systemOutPrint(variableExpr));

return ForStatement.builder()
.setLocalVariableExpr(variableExpr)
.setCollectionExpr(methodExpr)
.setBody(Arrays.asList(BodyStatement))
.build();
}
return null;
}

// Convert configLanguage.Statement of StandardOutput to Statement
// Support StandardOutput
// TODO: Support Return (P0), Declaration (P0), Declaration Assigment (P0)
// TODO: Support Iteration.Repeated (P1), Iteration.Map (P1), Conditional (P2), Iteration.NumberSequence(P2), Iteration.bytes(P3)
public static Statement convertStandardOutputStatementToStatement(
com.google.cloud.tools.snippetgen.configlanguage.v1.Statement statement) {
if (statement.hasStandardOutput()) {
if(statement.getStandardOutput().getValue().hasStringValue()) {
String val = convertExpressionToString(statement.getStandardOutput().getValue());
Expr content = ValueExpr.withValue(StringObjectValue.withValue(val));
return ExprStatement.withExpr(composeSystemOutPrint(content));
}
if(statement.getStandardOutput().getValue().hasNameValue()){
// If path does not exist in NameValue, print out Name
if(statement.getStandardOutput().getValue().getNameValue().getPathList().isEmpty()){
VariableExpr content =
VariableExpr.builder()
.setVariable(
Variable.builder()
.setType(TypeNode.STRING)
.setName(JavaStyle.toLowerCamelCase(statement.getStandardOutput().getValue().getNameValue().getName()))
.build())
.setIsDecl(true)
.build();
return ExprStatement.withExpr(systemOutPrint(content));
}
// If path exists in NameValue, print out Name.get<Path>
TypeNode contentType =
TypeNode.withReference(
ConcreteReference.builder()
.setClazz(Object.class)
.build());
VariableExpr contentVarExpr =
VariableExpr.withVariable(
Variable.builder().setName(JavaStyle.toLowerCamelCase(statement.getStandardOutput().getValue().getNameValue().getName())).setType(contentType).build());
MethodInvocationExpr initialGetMethodInvocationExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(contentVarExpr)
.setMethodName(String.format("get%s", JavaStyle.toUpperCamelCase(statement.getStandardOutput().getValue().getNameValue().getPathList().get(0))))
.setReturnType(TypeNode.VOID)
.build();

// If path is nested, recursively add get() methods
// for(String pathField : statement.getStandardOutput().getValue().getNameValue().getPathList()){
// MethodInvocationExpr nextGetMethodInvocationExpr =
// MethodInvocationExpr.builder()
// .setExprReferenceExpr(initialGetMethodInvocationExpr)
// .setMethodName(String.format("get%s", JavaStyle.toUpperCamelCase(pathField)))
// .setReturnType(TypeNode.VOID)
// .build();
// return ExprStatement.withExpr(systemOutPrint(nextGetMethodInvocationExpr));
// }
return ExprStatement.withExpr(systemOutPrint(initialGetMethodInvocationExpr));
}
}
// Return empty print statement if invalid
return ExprStatement.withExpr(systemOutPrint(""));
}

// Create Statement from standardOutput
public static MethodInvocationExpr systemOutPrint(String content) {
return composeSystemOutPrint(ValueExpr.withValue(StringObjectValue.withValue(content)));
}

private static MethodInvocationExpr systemOutPrint(VariableExpr variableExpr) {
return composeSystemOutPrint(variableExpr.toBuilder().setIsDecl(false).build());
}

public static MethodInvocationExpr systemOutPrint(MethodInvocationExpr nestedVariableExpr) {
return composeSystemOutPrint(nestedVariableExpr.toBuilder().build());
}

public static MethodInvocationExpr composeSystemOutPrint(Expr content) {
VaporReference out =
VaporReference.builder()
.setEnclosingClassNames("System")
.setName("out")
.setPakkage("java.lang")
.build();
return MethodInvocationExpr.builder()
.setStaticReferenceType(TypeNode.withReference(out))
.setMethodName("println")
.setArguments(content)
.build();
}

public static MethodInvocationExpr setNestedValue(String content) {
return composeNestedValue(ValueExpr.withValue(StringObjectValue.withValue(content)));
}

private static MethodInvocationExpr composeNestedValue(Expr content) {
VaporReference out =
VaporReference.builder()
.setEnclosingClassNames("CustomClass")
.setName("out")
.setPakkage("java.lang")
.build();
return MethodInvocationExpr.builder()
.setStaticReferenceType(TypeNode.withReference(out))
.setMethodName("println")
.setArguments(content)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ public GapicMetadata gapicMetadata() {
@Nullable
public abstract GapicServiceConfig serviceConfig();

@Nullable
public abstract List<GapicSnippetConfig> snippetConfigs();

public boolean hasSnippetConfigs() {
return snippetConfigs().size() != 0;
}

@Nullable
public abstract com.google.api.Service serviceYamlProto();

Expand All @@ -67,6 +74,12 @@ public void updateGapicMetadata(GapicMetadata newMetadata) {
gapicMetadata = newMetadata;
}

public void updateSnippetConfigs(List<GapicSnippetConfig> listOfsnippetConfigs) {
for (GapicSnippetConfig snippetConfig : listOfsnippetConfigs) {
snippetConfigs().add(snippetConfig);
}
}

static GapicMetadata defaultGapicMetadata() {
return GapicMetadata.newBuilder()
.setSchema("1.0")
Expand Down Expand Up @@ -107,6 +120,8 @@ public Builder setHelperResourceNames(Set<ResourceName> helperResourceNames) {

public abstract Builder setServiceConfig(GapicServiceConfig serviceConfig);

public abstract Builder setSnippetConfigs(List<GapicSnippetConfig> snippetConfigs);

public abstract Builder setServiceYamlProto(com.google.api.Service serviceYamlProto);

public abstract Builder setGapicMetadataEnabled(boolean gapicMetadataEnabled);
Expand Down
Loading