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

[ggj][codegen][comments] fix: preserve newlines and parse itemized lists in protobuf comments #443

Merged
merged 31 commits into from
Oct 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
90c4f38
fix: support non-name fields with res-refs in resname def parsing
miraleung Oct 27, 2020
a74be70
fix: add workaround for missing default_host and oauth_scopes annotation
miraleung Oct 27, 2020
aef9843
Merge branch 'master' of github.com:googleapis/gapic-generator-java i…
miraleung Oct 29, 2020
fdb1ffb
fix: clarify LRO parsing error messages
miraleung Oct 27, 2020
642c606
feat: support deeply-nested types in AST and proto message parsing
miraleung Oct 28, 2020
3e26d87
fix: prevent resname tokens from matching subcomponents
miraleung Oct 28, 2020
837da38
fix: use TypeParser for proto message parsing
miraleung Oct 28, 2020
a5fc332
fix: use generic types in field instantiation in ServiceClientTest
miraleung Oct 28, 2020
b71b786
fix: prevent descension into map types in nested message parsing
miraleung Oct 29, 2020
602e1df
fix: merge master
miraleung Oct 29, 2020
07dddb8
fix: use both map generics in ServiceClientTest codegen
miraleung Oct 29, 2020
5e95e8f
fix: dir structure of generated files
miraleung Oct 29, 2020
c37c2d0
test: add asset API gradle pkg rules
miraleung Oct 29, 2020
8a7196f
fix: remove unused dep
miraleung Oct 29, 2020
f7f8099
test: add logging integration target and goldens, consolidate rules
miraleung Oct 29, 2020
9e0ad39
fix: merge master
miraleung Oct 29, 2020
9df3a5b
fix: fix asset_java_gapic build
miraleung Oct 30, 2020
96f8676
fix: fix test src packaging, update integration goldens
miraleung Oct 30, 2020
a91a085
fix: pass all tokens to instansiate in resname 1-pattern case
miraleung Oct 30, 2020
19e0a98
fix: update goldens
miraleung Oct 30, 2020
2dfd4b1
fix: update goldens
miraleung Oct 30, 2020
5dae221
build: add all integration tests to pre-commit hook
miraleung Oct 30, 2020
6917a2b
build: run pre-commit when goldens have changed
miraleung Oct 30, 2020
1aaf0a5
build: add integration golden tests to CircleCI
miraleung Oct 30, 2020
0ba9f53
fix: preserve newlines and parse itemized lists in protobuf comments
miraleung Oct 30, 2020
2b1b8d1
fix: remove extraneous escaper
miraleung Oct 30, 2020
c279667
Merge branch 'master' into alpha/g19
miraleung Oct 30, 2020
ceadd4e
Merge branch 'alpha/g19' of github.com:googleapis/gapic-generator-jav…
miraleung Oct 30, 2020
00af38c
fix: update goldens
miraleung Oct 31, 2020
2fdc4fe
Merge branch 'master' into alpha/g19
miraleung Oct 31, 2020
63484fa
fix: update integration goldens for ServiceClient comment names (#444)
miraleung Oct 31, 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
15 changes: 15 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,21 @@ then
fi
fi

# Check integration tests.
if [ $NUM_JAVA_FILES_CHANGED -gt 0 ] \
|| [ $NUM_INTEGRATION_GOLDEN_FILES_CHANGED -gt 0 ] \
|| [ $NUM_INTEGRATION_BAZEL_FILES_CHANGED -gt 0 ]
then
echo_status "Checking integration tests..."
bazel --batch test --disk_cache="$BAZEL_CACHE_DIR" //test/integration/...
TEST_STATUS=$?
if [ $TEST_STATUS != 0 ]
then
echo_error "Tests failed." "Please fix them and try again."
exit 1
fi
fi

# Check and fix Bazel format.
if [ $NUM_BAZEL_FILES_CHANGED -gt 0 ]
then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
import com.google.api.generator.gapic.model.Service;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Generated;

public class ClientLibraryPackageInfoComposer {
Expand Down Expand Up @@ -73,16 +76,34 @@ private static CommentStatement createPackageInfoJavadoc(GapicContext context) {
javaDocCommentBuilder.addParagraph(
String.format("%s %s %s", DIVIDER, javaClientName, DIVIDER));

// TODO(miraleung): Paragraphs
// TODO(miraleung): Replace this with a comment converter when we upport CommonMark.
if (service.hasDescription()) {
String[] descriptionParagraphs = service.description().split("\\r?\\n");
String[] descriptionParagraphs = service.description().split("\\n\\n");
for (int i = 0; i < descriptionParagraphs.length; i++) {
if (i == 0) {
boolean startsWithItemizedList = descriptionParagraphs[i].startsWith(" * ");
// Split by listed items, then join newlines.
List<String> listItems =
Stream.of(descriptionParagraphs[i].split("\\n \\*"))
.map(s -> s.replace("\n", ""))
.collect(Collectors.toList());
if (startsWithItemizedList) {
// Remove the first asterisk.
listItems.set(0, listItems.get(0).substring(2));
}

if (!startsWithItemizedList) {
if (i == 0) {
javaDocCommentBuilder =
javaDocCommentBuilder.addParagraph(
String.format(SERVICE_DESCRIPTION_HEADER_PATTERN, listItems.get(0)));
} else {
javaDocCommentBuilder = javaDocCommentBuilder.addParagraph(listItems.get(0));
}
}
if (listItems.size() > 1 || startsWithItemizedList) {
javaDocCommentBuilder =
javaDocCommentBuilder.addParagraph(
String.format(SERVICE_DESCRIPTION_HEADER_PATTERN, descriptionParagraphs[i]));
} else {
javaDocCommentBuilder = javaDocCommentBuilder.addParagraph(descriptionParagraphs[i]);
javaDocCommentBuilder.addUnorderedList(
listItems.subList(startsWithItemizedList ? 0 : 1, listItems.size()));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@
import com.google.api.generator.gapic.model.MethodArgument;
import com.google.api.generator.gapic.model.Service;
import com.google.api.generator.gapic.utils.JavaStyle;
import com.google.common.base.Strings;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

class ServiceClientCommentComposer {
// Tokens.
Expand Down Expand Up @@ -102,8 +105,11 @@ class ServiceClientCommentComposer {
static List<CommentStatement> createClassHeaderComments(Service service) {
JavaDocComment.Builder classHeaderJavadocBuilder = JavaDocComment.builder();
if (service.hasDescription()) {
classHeaderJavadocBuilder.addComment(
String.format(SERVICE_DESCRIPTION_SUMMARY_PATTERN, service.description()));
classHeaderJavadocBuilder =
processProtobufComment(
service.description(),
classHeaderJavadocBuilder,
SERVICE_DESCRIPTION_SUMMARY_PATTERN);
}

// Service introduction.
Expand Down Expand Up @@ -146,7 +152,8 @@ static List<CommentStatement> createRpcMethodHeaderComment(
JavaDocComment.Builder methodJavadocBuilder = JavaDocComment.builder();

if (method.hasDescription()) {
methodJavadocBuilder.addComment(method.description());
methodJavadocBuilder =
processProtobufComment(method.description(), methodJavadocBuilder, null);
}

methodJavadocBuilder.addParagraph(METHOD_DESCRIPTION_SAMPLE_CODE_SUMMARY_STRING);
Expand All @@ -157,8 +164,11 @@ static List<CommentStatement> createRpcMethodHeaderComment(
"request", "The request object containing all of the parameters for the API call.");
} else {
for (MethodArgument argument : methodArguments) {
// TODO(miraleung): Remove the newline replacement when we support CommonMark.
String description =
argument.field().hasDescription() ? argument.field().description() : EMPTY_STRING;
argument.field().hasDescription()
? argument.field().description().replace("\n", "")
: EMPTY_STRING;
methodJavadocBuilder.addParam(argument.name(), description);
}
}
Expand Down Expand Up @@ -190,7 +200,8 @@ static List<CommentStatement> createRpcCallableMethodHeaderComment(Method method
JavaDocComment.Builder methodJavadocBuilder = JavaDocComment.builder();

if (method.hasDescription()) {
methodJavadocBuilder.addComment(method.description());
methodJavadocBuilder =
processProtobufComment(method.description(), methodJavadocBuilder, null);
}

methodJavadocBuilder.addParagraph(METHOD_DESCRIPTION_SAMPLE_CODE_SUMMARY_STRING);
Expand All @@ -204,4 +215,42 @@ static List<CommentStatement> createRpcCallableMethodHeaderComment(Method method
private static CommentStatement toSimpleComment(String comment) {
return CommentStatement.withComment(JavaDocComment.withComment(comment));
}

// TODO(miraleung): Replace this with a comment converter when we upport CommonMark.
private static JavaDocComment.Builder processProtobufComment(
String rawComment, JavaDocComment.Builder originalCommentBuilder, String firstPattern) {
JavaDocComment.Builder commentBuilder = originalCommentBuilder;
String[] descriptionParagraphs = rawComment.split("\\n\\n");
for (int i = 0; i < descriptionParagraphs.length; i++) {
boolean startsWithItemizedList = descriptionParagraphs[i].startsWith(" * ");
// Split by listed items, then join newlines.
List<String> listItems =
Stream.of(descriptionParagraphs[i].split("\\n \\*"))
.map(s -> s.replace("\n", ""))
.collect(Collectors.toList());
if (startsWithItemizedList) {
// Remove the first asterisk.
listItems.set(0, listItems.get(0).substring(2));
}
if (!startsWithItemizedList) {
if (i == 0) {
if (!Strings.isNullOrEmpty(firstPattern)) {
commentBuilder =
commentBuilder.addParagraph(String.format(firstPattern, listItems.get(0)));
} else {
commentBuilder = commentBuilder.addParagraph(listItems.get(0));
}
} else {
commentBuilder = commentBuilder.addParagraph(listItems.get(0));
}
}
if (listItems.size() > 1 || startsWithItemizedList) {
commentBuilder =
commentBuilder.addUnorderedList(
listItems.subList(startsWithItemizedList ? 0 : 1, listItems.size()));
}
}

return commentBuilder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

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

import com.google.common.escape.Escaper;
import com.google.common.escape.Escapers;
import com.google.protobuf.DescriptorProtos.SourceCodeInfo.Location;
import javax.annotation.Nonnull;

Expand All @@ -24,9 +22,6 @@
* additional documentation on descriptor.proto.
*/
public class SourceCodeInfoLocation {
// Not a singleton because of nested-class instantiation mechanics.
private final NewlineEscaper ESCAPER = new NewlineEscaper();

@Nonnull private final Location location;

private SourceCodeInfoLocation(Location location) {
Expand All @@ -50,15 +45,6 @@ public String getLeadingDetachedComments(int index) {
}

private String processProtobufComment(String s) {
return ESCAPER.escape(s).trim();
}

private class NewlineEscaper extends Escaper {
private final Escaper charEscaper = Escapers.builder().addEscape('\n', "").build();

@Override
public String escape(String sourceString) {
return charEscaper.escape(sourceString);
}
return s.trim();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void setUp() throws Exception {
public void getServiceInfo() {
SourceCodeInfoLocation location = parser.getLocation(protoFile.findServiceByName("FooService"));
assertEquals(
"This is a service description. It takes up multiple lines, like so.",
"This is a service description.\n It takes up multiple lines, like so.",
location.getLeadingComments());

location = parser.getLocation(protoFile.findServiceByName("BarService"));
Expand All @@ -60,7 +60,7 @@ public void getMethodInfo() {
ServiceDescriptor service = protoFile.findServiceByName("FooService");
SourceCodeInfoLocation location = parser.getLocation(service.findMethodByName("FooMethod"));
assertEquals(
"FooMethod does something. This comment also takes up multiple lines.",
"FooMethod does something.\n This comment also takes up multiple lines.",
location.getLeadingComments());

service = protoFile.findServiceByName("BarService");
Expand All @@ -73,13 +73,13 @@ public void getOuterMessageInfo() {
Descriptor message = protoFile.findMessageTypeByName("FooMessage");
SourceCodeInfoLocation location = parser.getLocation(message);
assertEquals(
"This is a message descxription. Lorum ipsum dolor sit amet consectetur adipiscing elit.",
"This is a message descxription.\n Lorum ipsum dolor sit amet consectetur adipiscing elit.",
location.getLeadingComments());

// Fields.
location = parser.getLocation(message.findFieldByName("field_one"));
assertEquals(
"This is a field description for field_one. And here is the second line of that"
"This is a field description for field_one.\n And here is the second line of that"
+ " description.",
location.getLeadingComments());
assertEquals("A field trailing comment.", location.getTrailingComments());
Expand Down
Loading