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

[composer][samplecode]Implement Setting Class Header Comment Sample Code #487

Merged
merged 42 commits into from
Nov 18, 2020
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
2cb0d9f
draft version
summer-ji-eng Nov 10, 2020
2bf804e
Add unit test for long line
summer-ji-eng Nov 10, 2020
b0c6b47
Implement formatter for code snippet
summer-ji-eng Nov 10, 2020
94bd9ed
Add license and comment
summer-ji-eng Nov 10, 2020
209ec9d
Merge branch 'master' into sample_code_formatter
summer-ji-eng Nov 10, 2020
7176a85
Use string as input parameters
summer-ji-eng Nov 10, 2020
62da37b
remove unused dep
summer-ji-eng Nov 10, 2020
c9213eb
Merge branch 'master' into sample_code_formatter
summer-ji-eng Nov 11, 2020
07d9d21
draft version
summer-ji-eng Nov 10, 2020
55c7604
Add unit test for long line
summer-ji-eng Nov 10, 2020
9f1b49d
Implement formatter for code snippet
summer-ji-eng Nov 10, 2020
3126e5f
Add license and comment
summer-ji-eng Nov 10, 2020
308e6cf
Use string as input parameters
summer-ji-eng Nov 10, 2020
e2f99ab
remove unused dep
summer-ji-eng Nov 10, 2020
e2d2a40
move utils to composer/samplecode
summer-ji-eng Nov 11, 2020
875794f
Merge branch 'sample_code_formatter' of github.com:googleapis/gapic-g…
summer-ji-eng Nov 11, 2020
40977cf
remove utils files
summer-ji-eng Nov 11, 2020
ad842eb
revert BUILD in test
summer-ji-eng Nov 11, 2020
4426dd2
Merge branch 'master' into sample_code_formatter
summer-ji-eng Nov 12, 2020
2cfa86f
Merge branch 'master' into sample_code_formatter
summer-ji-eng Nov 12, 2020
222c910
Add comment and rephrase static string
summer-ji-eng Nov 13, 2020
7ca32d8
simplify the wrapper
summer-ji-eng Nov 13, 2020
4f91c12
Merge branch 'master' into sample_code_formatter
summer-ji-eng Nov 13, 2020
ef1a81d
Merge branch 'master' into sample_code_formatter
summer-ji-eng Nov 13, 2020
67a66e5
compose sample code for settings and stub settings
summer-ji-eng Nov 11, 2020
dadd3b8
Pick first pure unary method
summer-ji-eng Nov 11, 2020
219fca1
resolve merge master
summer-ji-eng Nov 13, 2020
efcd9d8
Add license for new file
summer-ji-eng Nov 13, 2020
dd1c881
pick first unary rpc for setting class
summer-ji-eng Nov 13, 2020
cbeabad
Add comment for method pick
summer-ji-eng Nov 13, 2020
5b602b5
Merge branch 'master' into setting_comment_sample_code_1
summer-ji-eng Nov 14, 2020
38bd06c
Update code mark in sample code
summer-ji-eng Nov 14, 2020
be274d6
move out from samplecode
summer-ji-eng Nov 16, 2020
1798c01
Merge branch 'master' into setting_comment_sample_code_1
summer-ji-eng Nov 16, 2020
95019b0
Add comments in composing sample code
summer-ji-eng Nov 17, 2020
801939a
Merge branch 'setting_comment_sample_code_1' of github.com:googleapis…
summer-ji-eng Nov 17, 2020
210f606
Merge branch 'master' into setting_comment_sample_code_1
summer-ji-eng Nov 17, 2020
06cb0f8
replace reduce by filter
summer-ji-eng Nov 17, 2020
2c111d1
simplify the orElse
summer-ji-eng Nov 17, 2020
39749d1
Merge branch 'master' into setting_comment_sample_code_1
summer-ji-eng Nov 17, 2020
933db28
Merge branch 'master' into setting_comment_sample_code_1
summer-ji-eng Nov 18, 2020
39457ef
Merge branch 'master' into setting_comment_sample_code_1
summer-ji-eng Nov 18, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ java_library(
deps = [
"//:service_config_java_proto",
"//src/main/java/com/google/api/generator/engine/ast",
"//src/main/java/com/google/api/generator/engine/writer",
"//src/main/java/com/google/api/generator/gapic:status_java_proto",
"//src/main/java/com/google/api/generator/gapic/model",
"//src/main/java/com/google/api/generator/gapic/composer/samplecode",
"//src/main/java/com/google/api/generator/gapic/utils",
"@com_google_api_api_common//jar",
"@com_google_api_gax_java//gax",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import com.google.api.generator.gapic.model.GapicClass.Kind;
import com.google.api.generator.gapic.model.Message;
import com.google.api.generator.gapic.model.Method;
import com.google.api.generator.gapic.model.Method.Stream;
import com.google.api.generator.gapic.model.Service;
import com.google.api.generator.gapic.utils.JavaStyle;
import com.google.common.base.Preconditions;
Expand Down Expand Up @@ -101,7 +102,7 @@ public GapicClass generate(Service service, Map<String, Message> ignore) {
ClassDefinition classDef =
ClassDefinition.builder()
.setPackageString(pakkage)
.setHeaderCommentStatements(createClassHeaderComments(service))
.setHeaderCommentStatements(createClassHeaderComments(service, types.get(className)))
.setAnnotations(createClassAnnotations())
.setScope(ScopeNode.PUBLIC)
.setName(className)
Expand All @@ -119,11 +120,20 @@ public GapicClass generate(Service service, Map<String, Message> ignore) {
return GapicClass.create(kind, classDef);
}

private static List<CommentStatement> createClassHeaderComments(Service service) {
private static List<CommentStatement> createClassHeaderComments(
Service service, TypeNode classType) {
// Pick the first pure unary rpc method, if no such method exists, then pick the first in the
// list.
summer-ji-eng marked this conversation as resolved.
Show resolved Hide resolved
Optional<Method> methodOpt =
service.methods().isEmpty() ? Optional.empty() : Optional.of(service.methods().get(0));
service.methods().isEmpty()
? Optional.empty()
: Optional.of(
service.methods().stream()
.filter(m -> m.stream() == Stream.NONE && !m.hasLro() && !m.isPaged())
.findFirst()
.orElse(service.methods().stream().findFirst().get()));
summer-ji-eng marked this conversation as resolved.
Show resolved Hide resolved
return SettingsCommentComposer.createClassHeaderComments(
getClientClassName(service.name()), service.defaultHost(), methodOpt);
getClientClassName(service.name()), service.defaultHost(), methodOpt, classType);
}

private static List<AnnotationNode> createClassAnnotations() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
import com.google.api.generator.gapic.model.GapicServiceConfig;
import com.google.api.generator.gapic.model.Message;
import com.google.api.generator.gapic.model.Method;
import com.google.api.generator.gapic.model.Method.Stream;
import com.google.api.generator.gapic.model.Service;
import com.google.api.generator.gapic.utils.JavaStyle;
import com.google.common.base.Preconditions;
Expand Down Expand Up @@ -163,7 +164,7 @@ public GapicClass generate(
ClassDefinition classDef =
ClassDefinition.builder()
.setPackageString(pakkage)
.setHeaderCommentStatements(createClassHeaderComments(service))
.setHeaderCommentStatements(createClassHeaderComments(service, types.get(className)))
.setAnnotations(createClassAnnotations())
.setScope(ScopeNode.PUBLIC)
.setName(className)
Expand All @@ -187,11 +188,20 @@ private static List<AnnotationNode> createClassAnnotations() {
.build());
}

private static List<CommentStatement> createClassHeaderComments(Service service) {
private static List<CommentStatement> createClassHeaderComments(
Service service, TypeNode classType) {
// Pick the first pure unary rpc method, if no such method exists, then pick the first in the
// list.
Optional<Method> methodOpt =
service.methods().isEmpty() ? Optional.empty() : Optional.of(service.methods().get(0));
service.methods().isEmpty()
? Optional.empty()
: Optional.of(
service.methods().stream()
.filter(m -> m.stream() == Stream.NONE && !m.hasLro() && !m.isPaged())
.findFirst()
.orElse(service.methods().stream().findFirst().get()));
return SettingsCommentComposer.createClassHeaderComments(
String.format(STUB_PATTERN, service.name()), service.defaultHost(), methodOpt);
String.format(STUB_PATTERN, service.name()), service.defaultHost(), methodOpt, classType);
}

private static TypeNode createExtendsType(Service service, Map<String, TypeNode> types) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.google.api.generator.engine.ast.CommentStatement;
import com.google.api.generator.engine.ast.JavaDocComment;
import com.google.api.generator.engine.ast.LineComment;
import com.google.api.generator.engine.ast.TypeNode;
import com.google.api.generator.gapic.model.Method;
import com.google.api.generator.gapic.utils.JavaStyle;
import com.google.common.base.Preconditions;
Expand All @@ -28,6 +29,8 @@
class SettingsCommentComposer {
private static final String COLON = ":";

private static final String CLIENT_CLASS_NAME_PATTERN = "%sClient";
private static final String STUB_PATTERN = "%sStub";
private static final String BUILDER_CLASS_DOC_PATTERN = "Builder for %s.";
private static final String CALL_SETTINGS_METHOD_DOC_PATTERN =
"Returns the object with the settings used for calls to %s.";
Expand Down Expand Up @@ -102,7 +105,10 @@ static CommentStatement createCallSettingsBuilderGetterComment(String javaMethod
}

static List<CommentStatement> createClassHeaderComments(
String configuredClassName, String defaultHost, Optional<Method> methodOpt) {
String configuredClassName,
String defaultHost,
Optional<Method> methodOpt,
TypeNode classType) {
// Split default address and port.
int colonIndex = defaultHost.indexOf(COLON);
Preconditions.checkState(
Expand All @@ -127,12 +133,16 @@ static List<CommentStatement> createClassHeaderComments(
.addParagraph(CLASS_HEADER_BUILDER_DESCRIPTION);

if (methodOpt.isPresent()) {
String sampleCode =
SettingsSampleCodeComposer.composeSettingClassHeaderSampleCode(
methodOpt.get(), classType);
javaDocCommentBuilder =
javaDocCommentBuilder.addParagraph(
String.format(
CLASS_HEADER_SAMPLE_CODE_PATTERN,
JavaStyle.toLowerCamelCase(methodOpt.get().name())));
// TODO(summerji): Add sample code here.
javaDocCommentBuilder
.addParagraph(
String.format(
CLASS_HEADER_SAMPLE_CODE_PATTERN,
JavaStyle.toLowerCamelCase(methodOpt.get().name())))
.addSampleCode(sampleCode);
}

return Arrays.asList(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.api.generator.gapic.composer;

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.MethodInvocationExpr;
import com.google.api.generator.engine.ast.PrimitiveValue;
import com.google.api.generator.engine.ast.Statement;
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.engine.writer.JavaWriterVisitor;
import com.google.api.generator.gapic.composer.samplecode.SampleCodeJavaFormatter;
import com.google.api.generator.gapic.model.Method;
import com.google.api.generator.gapic.utils.JavaStyle;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public final class SettingsSampleCodeComposer {
summer-ji-eng marked this conversation as resolved.
Show resolved Hide resolved
// TODO(summerji): Add unit tests

private static final String BUILDER_NAME_PATTERN = "%sBuilder";
private static final String STUB = "Stub";
private static final String EMPTY_STRING = "";

public static String composeSettingClassHeaderSampleCode(Method method, TypeNode classType) {
// Initialize services settingsBuilder with newBuilder()
// e.g. FoobarSettings.Builder foobarSettingsBuilder = FoobarSettings.newBuilder();
String className = classType.reference().name();
summer-ji-eng marked this conversation as resolved.
Show resolved Hide resolved
TypeNode builderType =
TypeNode.withReference(
VaporReference.builder()
.setEnclosingClassNames(classType.reference().name())
.setName("Builder")
.setPakkage(classType.reference().pakkage())
.build());
Variable builderVar =
Variable.builder()
.setName(getClassSettingsBuilderName(className))
.setType(builderType)
.build();
VariableExpr localSettingsVarExpr = VariableExpr.withVariable(builderVar);
Expr settingsBuilderExpr =
MethodInvocationExpr.builder()
.setStaticReferenceType(classType)
.setMethodName("newBuilder")
.setReturnType(builderType)
.build();
Expr initLocalSettingsExpr =
AssignmentExpr.builder()
.setVariableExpr(localSettingsVarExpr.toBuilder().setIsDecl(true).build())
.setValueExpr(settingsBuilderExpr)
.build();

// Builder with set value method
// e.g
// foobarSettingBuilder.fooSetting().setRetrySettings(echoSettingsBuilder.echoSettings().getRetrySettings().toBuilder().setTotalTimeout(Duration.ofSeconds(30)).build());
summer-ji-eng marked this conversation as resolved.
Show resolved Hide resolved
MethodInvocationExpr retrySettingsMethodExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(localSettingsVarExpr)
.setMethodName(JavaStyle.toLowerCamelCase(String.format("%sSettings", method.name())))
.setReturnType(method.outputType())
.build();
MethodInvocationExpr timeoutArExpr =
MethodInvocationExpr.builder()
.setStaticReferenceType(
TypeNode.withReference(ConcreteReference.withClazz(Duration.class)))
.setMethodName("ofSeconds")
.setArguments(
ValueExpr.withValue(
PrimitiveValue.builder().setType(TypeNode.INT).setValue("30").build()))
.build();
MethodInvocationExpr timeoutBuilderMethodExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(
MethodInvocationExpr.builder()
.setExprReferenceExpr(
MethodInvocationExpr.builder()
.setExprReferenceExpr(retrySettingsMethodExpr)
.setMethodName("getRetrySettings")
.build())
.setMethodName("toBuilder")
.build())
.setMethodName("setTotalTimeout")
.setArguments(Arrays.asList(timeoutArExpr))
.build();
MethodInvocationExpr retrySettingsArgExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(timeoutBuilderMethodExpr)
.setMethodName("build")
.build();
MethodInvocationExpr settingBuilderMethodExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(retrySettingsMethodExpr)
.setMethodName("setRetrySettings")
.setArguments(Arrays.asList(retrySettingsArgExpr))
.build();

// Initialize clientSetting with builder() method.
// e.g: Foobar<Stub>Settings foobarSettings = foobarSettingsBuilder.build();
VariableExpr settingsVarExpr =
VariableExpr.withVariable(
Variable.builder()
.setType(classType)
.setName(getServiceSettingsName(className))
.build());
AssignmentExpr settingBuildAssignmentExpr =
AssignmentExpr.builder()
.setVariableExpr(settingsVarExpr.toBuilder().setIsDecl(true).build())
.setValueExpr(
MethodInvocationExpr.builder()
.setExprReferenceExpr(localSettingsVarExpr)
.setMethodName("build")
.setReturnType(classType)
.build())
.build();

List<Statement> statements =
Arrays.asList(initLocalSettingsExpr, settingBuilderMethodExpr, settingBuildAssignmentExpr)
.stream()
.map(e -> ExprStatement.withExpr(e))
.collect(Collectors.toList());
return SampleCodeJavaFormatter.format(writeStatements(statements));
}

private static String getServiceSettingsName(String className) {
return JavaStyle.toLowerCamelCase(className).replace(STUB, EMPTY_STRING);
}

private static String getClassSettingsBuilderName(String className) {
return JavaStyle.toLowerCamelCase(
String.format(BUILDER_NAME_PATTERN, JavaStyle.toLowerCamelCase(className)))
.replace(STUB, EMPTY_STRING);
}

// TODO(summerji): Refactor to use writeSampleCode method after PR#499 merged.
private static String writeStatements(List<Statement> statements) {
summer-ji-eng marked this conversation as resolved.
Show resolved Hide resolved
JavaWriterVisitor visitor = new JavaWriterVisitor();
for (Statement statement : statements) {
statement.accept(visitor);
}
return visitor.write();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ java_library(
":samplecode_files",
],
deps = [
"//src/main/java/com/google/api/generator/engine/ast",
"//src/main/java/com/google/api/generator/engine/writer",
"//src/main/java/com/google/api/generator/gapic/model",
"//src/main/java/com/google/api/generator/gapic/utils",
"@google_java_format_all_deps//jar",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ TEST_DEPS = [
"//src/main/java/com/google/api/generator/gapic/composer",
"//src/test/java/com/google/api/generator/test/framework:asserts",
"//src/test/java/com/google/api/generator/test/framework:utils",
"//src/main/java/com/google/api/generator/gapic/composer/samplecode",
"//src/main/java/com/google/api/generator/gapic/model",
"//src/main/java/com/google/api/generator/gapic/protoparser",
"//src/test/java/com/google/api/generator/gapic/testdata:showcase_java_proto",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ import javax.annotation.Generated;
* build() is called, the tree of builders is called to create the complete settings object.
*
* <p>For example, to set the total timeout of echo to 30 seconds:
*
* <pre>{@code
* EchoSettings.Builder echoSettingsBuilder = EchoSettings.newBuilder();
* echoSettingsBuilder
* .echoSettings()
* .setRetrySettings(
* echoSettingsBuilder
* .echoSettings()
* .getRetrySettings()
* .toBuilder()
* .setTotalTimeout(Duration.ofSeconds(30))
* .build());
* EchoSettings echoSettings = echoSettingsBuilder.build();
* }</pre>
*/
@Generated("by gapic-generator-java")
public class EchoSettings extends ClientSettings<EchoSettings> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ import org.threeten.bp.Duration;
* build() is called, the tree of builders is called to create the complete settings object.
*
* <p>For example, to set the total timeout of echo to 30 seconds:
*
* <pre>{@code
* EchoStubSettings.Builder echoSettingsBuilder = EchoStubSettings.newBuilder();
* echoSettingsBuilder
* .echoSettings()
* .setRetrySettings(
* echoSettingsBuilder
* .echoSettings()
* .getRetrySettings()
* .toBuilder()
* .setTotalTimeout(Duration.ofSeconds(30))
* .build());
* EchoStubSettings echoSettings = echoSettingsBuilder.build();
* }</pre>
*/
@BetaApi
@Generated("by gapic-generator-java")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,21 @@ import org.threeten.bp.Duration;
* build() is called, the tree of builders is called to create the complete settings object.
*
* <p>For example, to set the total timeout of deleteLog to 30 seconds:
*
* <pre>{@code
* LoggingServiceV2StubSettings.Builder loggingServiceV2SettingsBuilder =
* LoggingServiceV2StubSettings.newBuilder();
* loggingServiceV2SettingsBuilder
* .deleteLogSettings()
* .setRetrySettings(
* loggingServiceV2SettingsBuilder
* .deleteLogSettings()
* .getRetrySettings()
* .toBuilder()
* .setTotalTimeout(Duration.ofSeconds(30))
* .build());
* LoggingServiceV2StubSettings loggingServiceV2Settings = loggingServiceV2SettingsBuilder.build();
* }</pre>
*/
@BetaApi
@Generated("by gapic-generator-java")
Expand Down
Loading