Skip to content

Commit

Permalink
[ggj][codegen] feat: add header comments to ServiceClient (#307)
Browse files Browse the repository at this point in the history
* feat: add protobuf comment parser util

* fix: add basic proto build rules

* feat: add header comments to ServiceClient

* fix: build protoc at test time
  • Loading branch information
miraleung authored Sep 19, 2020
1 parent c63414b commit b4ca070
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ public GapicClass generate(Service service, Map<String, Message> messageTypes) {

ClassDefinition classDef =
ClassDefinition.builder()
.setHeaderCommentStatements(
ServiceClientCommentComposer.createClassHeaderComments(service))
.setPackageString(pakkage)
.setAnnotations(createClassAnnotations(types))
.setImplementsTypes(createClassImplements(types))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,62 @@
import com.google.api.generator.engine.ast.CommentStatement;
import com.google.api.generator.engine.ast.JavaDocComment;
import com.google.api.generator.engine.ast.TypeNode;
import com.google.api.generator.gapic.model.Service;
import com.google.api.generator.gapic.utils.JavaStyle;
import java.util.Arrays;
import java.util.List;

class ServiceClientCommentComposer {
// Tokens.
private static final String COLON = ":";

// Constants.
private static final String SERVICE_DESCRIPTION_INTRO_STRING =
"This class provides the ability to make remote calls to the backing service through method "
+ "calls that map to API methods. Sample code to get started:";
private static final String SERVICE_DESCRIPTION_CLOSE_STRING =
"Note: close() needs to be called on the echoClient object to clean up resources such as "
+ "threads. In the example above, try-with-resources is used, which automatically calls "
+ "close().";
private static final String SERVICE_DESCRIPTION_SURFACE_SUMMARY_STRING =
"The surface of this class includes several types of Java methods for each of the API's "
+ "methods:";
private static final String SERVICE_DESCRIPTION_SURFACE_CODA_STRING =
"See the individual methods for example code.";
private static final String SERVICE_DESCRIPTION_RESOURCE_NAMES_FORMATTING_STRING =
"Many parameters require resource names to be formatted in a particular way. To assist with"
+ " these names, this class includes a format method for each type of name, and"
+ " additionally a parse method to extract the individual identifiers contained within"
+ " names that are returned.";
private static final String SERVICE_DESCRIPTION_CREDENTIALS_SUMMARY_STRING =
"To customize credentials:";
private static final String SERVICE_DESCRIPTION_ENDPOINT_SUMMARY_STRING =
"To customize the endpoint:";

private static final List<String> SERVICE_DESCRIPTION_SURFACE_DESCRIPTION =
Arrays.asList(
"A \"flattened\" method. With this type of method, the fields of the request type have"
+ " been converted into function parameters. It may be the case that not all fields"
+ " are available as parameters, and not every API method will have a flattened"
+ " method entry point.",
"A \"request object\" method. This type of method only takes one parameter, a request"
+ " object, which must be constructed before the call. Not every API method will"
+ " have a request object method.",
"A \"callable\" method. This type of method takes no parameters and returns an immutable "
+ "API callable object, which can be used to initiate calls to the service.");

// Patterns.
private static final String CREATE_METHOD_STUB_ARG_PATTERN =
"Constructs an instance of EchoClient, using the given stub for making calls. This is for"
+ " advanced usage - prefer using create(%s).";

private static final String SERVICE_DESCRIPTION_CUSTOMIZE_SUMMARY_PATTERN =
"This class can be customized by passing in a custom instance of %s to create(). For"
+ " example:";

private static final String SERVICE_DESCRIPTION_SUMMARY_PATTERN = "Service Description: %s";

// Comments.
static final CommentStatement CREATE_METHOD_NO_ARG_COMMENT =
toSimpleComment("Constructs an instance of EchoClient with default settings.");

Expand All @@ -45,6 +93,41 @@ class ServiceClientCommentComposer {
"Returns the OperationsClient that can be used to query the status of a long-running"
+ " operation returned by another API method call.");

static List<CommentStatement> createClassHeaderComments(Service service) {
JavaDocComment.Builder classHeaderJavadocBuilder = JavaDocComment.builder();
if (service.hasDescription()) {
classHeaderJavadocBuilder.addComment(
String.format(SERVICE_DESCRIPTION_SUMMARY_PATTERN, service.description()));
}

// Service introduction.
classHeaderJavadocBuilder.addParagraph(SERVICE_DESCRIPTION_INTRO_STRING);
// TODO(summerji): Add sample code here.

// API surface description.
classHeaderJavadocBuilder.addParagraph(SERVICE_DESCRIPTION_CLOSE_STRING);
classHeaderJavadocBuilder.addParagraph(SERVICE_DESCRIPTION_SURFACE_SUMMARY_STRING);
classHeaderJavadocBuilder.addOrderedList(SERVICE_DESCRIPTION_SURFACE_DESCRIPTION);
classHeaderJavadocBuilder.addParagraph(SERVICE_DESCRIPTION_SURFACE_CODA_STRING);

// Formatting resource names.
classHeaderJavadocBuilder.addParagraph(SERVICE_DESCRIPTION_RESOURCE_NAMES_FORMATTING_STRING);

// Customization examples.
classHeaderJavadocBuilder.addParagraph(
String.format(
SERVICE_DESCRIPTION_CUSTOMIZE_SUMMARY_PATTERN,
String.format("%sSettings", JavaStyle.toUpperCamelCase(service.name()))));
classHeaderJavadocBuilder.addParagraph(SERVICE_DESCRIPTION_CREDENTIALS_SUMMARY_STRING);
// TODO(summerji): Add credentials' customization sample code here.
classHeaderJavadocBuilder.addParagraph(SERVICE_DESCRIPTION_ENDPOINT_SUMMARY_STRING);
// TODO(summerji): Add endpoint customization sample code here.

return Arrays.asList(
CommentComposer.AUTO_GENERATED_CLASS_COMMENT,
CommentStatement.withComment(classHeaderJavadocBuilder.build()));
}

static CommentStatement createCreateMethodStubArgComment(TypeNode settingsType) {
return toSimpleComment(
String.format(CREATE_METHOD_STUB_ARG_PATTERN, settingsType.reference().name()));
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/com/google/api/generator/gapic/model/Service.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
package com.google.api.generator.gapic.model;

import com.google.auto.value.AutoValue;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import java.util.List;
import javax.annotation.Nullable;

@AutoValue
public abstract class Service {
Expand All @@ -32,7 +34,12 @@ public abstract class Service {

public abstract ImmutableList<Method> methods();

// TODO(miraleung): Get comments.
@Nullable
public abstract String description();

public boolean hasDescription() {
return !Strings.isNullOrEmpty(description());
}

public static Builder builder() {
return new AutoValue_Service.Builder().setMethods(ImmutableList.of());
Expand All @@ -52,6 +59,8 @@ public abstract static class Builder {

public abstract Builder setMethods(List<Method> methods);

public abstract Builder setDescription(String description);

public abstract Service build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,55 @@ public void generateServiceClasses() {
+ "import java.util.concurrent.TimeUnit;\n"
+ "import javax.annotation.Generated;\n"
+ "\n"
+ "// AUTO-GENERATED DOCUMENTATION AND CLASS.\n"
+ "/**\n"
+ " * This class provides the ability to make remote calls to the backing service"
+ " through method calls\n"
+ " * that map to API methods. Sample code to get started:\n"
+ " *\n"
+ " * <p>Note: close() needs to be called on the echoClient object to clean up resources"
+ " such as\n"
+ " * threads. In the example above, try-with-resources is used, which automatically"
+ " calls close().\n"
+ " *\n"
+ " * <p>The surface of this class includes several types of Java methods for each of"
+ " the API's\n"
+ " * methods:\n"
+ " *\n"
+ " * <ol>\n"
+ " * <li>A \"flattened\" method. With this type of method, the fields of the request"
+ " type have been\n"
+ " * converted into function parameters. It may be the case that not all fields"
+ " are available as\n"
+ " * parameters, and not every API method will have a flattened method entry"
+ " point.\n"
+ " * <li>A \"request object\" method. This type of method only takes one parameter, a"
+ " request object,\n"
+ " * which must be constructed before the call. Not every API method will have a"
+ " request object\n"
+ " * method.\n"
+ " * <li>A \"callable\" method. This type of method takes no parameters and returns"
+ " an immutable API\n"
+ " * callable object, which can be used to initiate calls to the service.\n"
+ " * </ol>\n"
+ " *\n"
+ " * <p>See the individual methods for example code.\n"
+ " *\n"
+ " * <p>Many parameters require resource names to be formatted in a particular way. To"
+ " assist with\n"
+ " * these names, this class includes a format method for each type of name, and"
+ " additionally a parse\n"
+ " * method to extract the individual identifiers contained within names that are"
+ " returned.\n"
+ " *\n"
+ " * <p>This class can be customized by passing in a custom instance of EchoSettings to"
+ " create(). For\n"
+ " * example:\n"
+ " *\n"
+ " * <p>To customize credentials:\n"
+ " *\n"
+ " * <p>To customize the endpoint:\n"
+ " */\n"
+ "@BetaApi\n"
+ "@Generated(\"by gapic-generator\")\n"
+ "public class EchoClient implements BackgroundResource {\n"
Expand Down

0 comments on commit b4ca070

Please sign in to comment.