diff --git a/src/main/java/com/google/api/generator/engine/ast/JavaDocComment.java b/src/main/java/com/google/api/generator/engine/ast/JavaDocComment.java index 5e0a4665e8..5ab53ca646 100644 --- a/src/main/java/com/google/api/generator/engine/ast/JavaDocComment.java +++ b/src/main/java/com/google/api/generator/engine/ast/JavaDocComment.java @@ -71,6 +71,11 @@ public Builder addParam(String name, String description) { return this; } + public Builder addUnescapedComment(String comment) { + componentsList.add(comment); + return this; + } + public Builder addComment(String comment) { componentsList.add(HtmlEscaper.escaper(comment)); return this; diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposer.java index e7b4b87072..713dd68753 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposer.java @@ -56,6 +56,7 @@ import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.CastExpr; import com.google.api.generator.engine.ast.ClassDefinition; +import com.google.api.generator.engine.ast.CommentStatement; import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.ast.ExprStatement; @@ -163,7 +164,7 @@ public GapicClass generate( ClassDefinition classDef = ClassDefinition.builder() .setPackageString(pakkage) - .setHeaderCommentStatements(CommentComposer.AUTO_GENERATED_CLASS_COMMENT) + .setHeaderCommentStatements(createClassHeaderComments(service)) .setAnnotations(createClassAnnotations()) .setScope(ScopeNode.PUBLIC) .setName(className) @@ -187,6 +188,15 @@ private static List createClassAnnotations() { .build()); } + private static List createClassHeaderComments(Service service) { + Optional methodOpt = + service.methods().isEmpty() ? Optional.empty() : Optional.of(service.methods().get(0)); + return Arrays.asList( + CommentComposer.AUTO_GENERATED_CLASS_COMMENT, + ServiceStubSettingsCommentComposer.createClassHeaderComment( + String.format(STUB_PATTERN, service.name()), service.defaultHost(), methodOpt)); + } + private static TypeNode createExtendsType(Service service, Map types) { TypeNode thisClassType = types.get(getThisClassName(service.name())); return TypeNode.withReference( diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsCommentComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsCommentComposer.java index 659c37d175..b272e90365 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsCommentComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsCommentComposer.java @@ -17,17 +17,42 @@ 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.gapic.model.Method; +import com.google.api.generator.gapic.utils.JavaStyle; +import com.google.common.base.Preconditions; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; class ServiceStubSettingsCommentComposer { + private static final String COLON = ":"; + 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."; private static final String CALL_SETTINGS_BUILDER_METHOD_DOC_PATTERN = "Returns the builder for the settings used for calls to %s."; + // Class header patterns. + private static final String CLASS_HEADER_SUMMARY_PATTERN = + "Settings class to configure an instance of {@link %s}."; + private static final String CLASS_HEADER_DEFAULT_ADDRESS_PORT_PATTERN = + "The default service address (%s) and default port (%d) are used."; + private static final String CLASS_HEADER_SAMPLE_CODE_PATTERN = + "For example, to set the total timeout of %s to 30 seconds:"; + + private static final String CLASS_HEADER_BUILDER_DESCRIPTION = + "The builder of this class is recursive, so contained classes are themselves builders. When" + + " build() is called, the tree of builders is called to create the complete settings" + + " object."; + private static final String CLASS_HEADER_DEFAULTS_DESCRIPTION = + "The default instance has everything set to sensible defaults:"; + private static final String CLASS_HEADER_DEFAULTS_CREDENTIALS_DESCRIPTION = + "Credentials are acquired automatically through Application Default Credentials."; + private static final String CLASS_HEADER_DEFAULTS_RETRIES_DESCRIPTION = + "Retries are configured for idempotent methods but not for non-idempotent methods."; + static final CommentStatement DEFAULT_SCOPES_COMMENT = toSimpleComment("The default scopes of the service."); @@ -76,6 +101,43 @@ static CommentStatement createCallSettingsBuilderGetterComment(String javaMethod return toSimpleComment(String.format(CALL_SETTINGS_BUILDER_METHOD_DOC_PATTERN, javaMethodName)); } + static CommentStatement createClassHeaderComment( + String configuredClassName, String defaultHost, Optional methodOpt) { + // Split default address and port. + int colonIndex = defaultHost.indexOf(COLON); + Preconditions.checkState( + colonIndex > 0 && colonIndex < defaultHost.length() - 1, + String.format( + "No valid address and port found for %s, expected a string formatted like" + + " localhost:8888", + defaultHost)); + String defaultAddress = defaultHost.substring(0, colonIndex); + int defaultPort = Integer.parseInt(defaultHost.substring(colonIndex + 1)); + + JavaDocComment.Builder javaDocCommentBuilder = + JavaDocComment.builder() + .addUnescapedComment(String.format(CLASS_HEADER_SUMMARY_PATTERN, configuredClassName)) + .addParagraph(CLASS_HEADER_DEFAULTS_DESCRIPTION) + .addUnorderedList( + Arrays.asList( + String.format( + CLASS_HEADER_DEFAULT_ADDRESS_PORT_PATTERN, defaultAddress, defaultPort), + CLASS_HEADER_DEFAULTS_CREDENTIALS_DESCRIPTION, + CLASS_HEADER_DEFAULTS_RETRIES_DESCRIPTION)) + .addParagraph(CLASS_HEADER_BUILDER_DESCRIPTION); + + if (methodOpt.isPresent()) { + javaDocCommentBuilder = + javaDocCommentBuilder.addParagraph( + String.format( + CLASS_HEADER_SAMPLE_CODE_PATTERN, + JavaStyle.toLowerCamelCase(methodOpt.get().name()))); + // TODO(summerji): Add sample code here. + } + + return CommentStatement.withComment(javaDocCommentBuilder.build()); + } + private static CommentStatement toSimpleComment(String comment) { return CommentStatement.withComment(JavaDocComment.withComment(comment)); } diff --git a/src/test/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposerTest.java index 1415ba3fd7..2003af7eb2 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposerTest.java @@ -229,6 +229,26 @@ private static List parseServices( + "import org.threeten.bp.Duration;\n" + "\n" + "// AUTO-GENERATED DOCUMENTATION AND CLASS.\n" + + "/**\n" + + " * Settings class to configure an instance of {@link EchoStub}.\n" + + " *\n" + + " *

The default instance has everything set to sensible defaults:\n" + + " *\n" + + " *

    \n" + + " *
  • The default service address (localhost) and default port (7469) are used.\n" + + " *
  • Credentials are acquired automatically through Application Default" + + " Credentials.\n" + + " *
  • Retries are configured for idempotent methods but not for non-idempotent" + + " methods.\n" + + " *
\n" + + " *\n" + + " *

The builder of this class is recursive, so contained classes are themselves" + + " builders. When\n" + + " * build() is called, the tree of builders is called to create the complete settings" + + " object.\n" + + " *\n" + + " *

For example, to set the total timeout of echo to 30 seconds:\n" + + " */\n" + "@BetaApi\n" + "@Generated(\"by gapic-generator-java\")\n" + "public class EchoStubSettings extends StubSettings {\n" @@ -769,6 +789,27 @@ private static List parseServices( + "import org.threeten.bp.Duration;\n" + "\n" + "// AUTO-GENERATED DOCUMENTATION AND CLASS.\n" + + "/**\n" + + " * Settings class to configure an instance of {@link LoggingServiceV2Stub}.\n" + + " *\n" + + " *

The default instance has everything set to sensible defaults:\n" + + " *\n" + + " *

    \n" + + " *
  • The default service address (logging.googleapis.com) and default port (443)" + + " are used.\n" + + " *
  • Credentials are acquired automatically through Application Default" + + " Credentials.\n" + + " *
  • Retries are configured for idempotent methods but not for non-idempotent" + + " methods.\n" + + " *
\n" + + " *\n" + + " *

The builder of this class is recursive, so contained classes are themselves" + + " builders. When\n" + + " * build() is called, the tree of builders is called to create the complete settings" + + " object.\n" + + " *\n" + + " *

For example, to set the total timeout of deleteLog to 30 seconds:\n" + + " */\n" + "@BetaApi\n" + "@Generated(\"by gapic-generator-java\")\n" + "public class LoggingServiceV2StubSettings extends" @@ -1488,6 +1529,27 @@ private static List parseServices( + "import org.threeten.bp.Duration;\n" + "\n" + "// AUTO-GENERATED DOCUMENTATION AND CLASS.\n" + + "/**\n" + + " * Settings class to configure an instance of {@link PublisherStub}.\n" + + " *\n" + + " *

The default instance has everything set to sensible defaults:\n" + + " *\n" + + " *

    \n" + + " *
  • The default service address (pubsub.googleapis.com) and default port (443)" + + " are used.\n" + + " *
  • Credentials are acquired automatically through Application Default" + + " Credentials.\n" + + " *
  • Retries are configured for idempotent methods but not for non-idempotent" + + " methods.\n" + + " *
\n" + + " *\n" + + " *

The builder of this class is recursive, so contained classes are themselves" + + " builders. When\n" + + " * build() is called, the tree of builders is called to create the complete settings" + + " object.\n" + + " *\n" + + " *

For example, to set the total timeout of createTopic to 30 seconds:\n" + + " */\n" + "@BetaApi\n" + "@Generated(\"by gapic-generator-java\")\n" + "public class PublisherStubSettings extends StubSettings {\n"