Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 17cb93b

Browse files
authored
[ggj][codegen][comments] fix: preserve newlines and parse itemized lists in protobuf comments (#443)
* fix: support non-name fields with res-refs in resname def parsing * fix: add workaround for missing default_host and oauth_scopes annotation * fix: clarify LRO parsing error messages * feat: support deeply-nested types in AST and proto message parsing * fix: prevent resname tokens from matching subcomponents * fix: use TypeParser for proto message parsing * fix: use generic types in field instantiation in ServiceClientTest * fix: prevent descension into map types in nested message parsing * fix: merge master * fix: use both map generics in ServiceClientTest codegen * fix: dir structure of generated files * test: add asset API gradle pkg rules * fix: remove unused dep * test: add logging integration target and goldens, consolidate rules * fix: fix asset_java_gapic build * fix: fix test src packaging, update integration goldens * fix: pass all tokens to instansiate in resname 1-pattern case * fix: update goldens * fix: update goldens * build: add all integration tests to pre-commit hook * build: run pre-commit when goldens have changed * build: add integration golden tests to CircleCI * fix: preserve newlines and parse itemized lists in protobuf comments * fix: remove extraneous escaper * fix: update goldens * fix: update integration goldens for ServiceClient comment names (#444)
1 parent fda8eb2 commit 17cb93b

File tree

8 files changed

+392
-180
lines changed

8 files changed

+392
-180
lines changed

.githooks/pre-commit

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,21 @@ then
132132
fi
133133
fi
134134

135+
# Check integration tests.
136+
if [ $NUM_JAVA_FILES_CHANGED -gt 0 ] \
137+
|| [ $NUM_INTEGRATION_GOLDEN_FILES_CHANGED -gt 0 ] \
138+
|| [ $NUM_INTEGRATION_BAZEL_FILES_CHANGED -gt 0 ]
139+
then
140+
echo_status "Checking integration tests..."
141+
bazel --batch test --disk_cache="$BAZEL_CACHE_DIR" //test/integration/...
142+
TEST_STATUS=$?
143+
if [ $TEST_STATUS != 0 ]
144+
then
145+
echo_error "Tests failed." "Please fix them and try again."
146+
exit 1
147+
fi
148+
fi
149+
135150
# Check and fix Bazel format.
136151
if [ $NUM_BAZEL_FILES_CHANGED -gt 0 ]
137152
then

src/main/java/com/google/api/generator/gapic/composer/ClientLibraryPackageInfoComposer.java

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
import com.google.api.generator.gapic.model.Service;
2626
import com.google.common.base.Preconditions;
2727
import com.google.common.base.Strings;
28+
import java.util.List;
29+
import java.util.stream.Collectors;
30+
import java.util.stream.Stream;
2831
import javax.annotation.Generated;
2932

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

76-
// TODO(miraleung): Paragraphs
79+
// TODO(miraleung): Replace this with a comment converter when we upport CommonMark.
7780
if (service.hasDescription()) {
78-
String[] descriptionParagraphs = service.description().split("\\r?\\n");
81+
String[] descriptionParagraphs = service.description().split("\\n\\n");
7982
for (int i = 0; i < descriptionParagraphs.length; i++) {
80-
if (i == 0) {
83+
boolean startsWithItemizedList = descriptionParagraphs[i].startsWith(" * ");
84+
// Split by listed items, then join newlines.
85+
List<String> listItems =
86+
Stream.of(descriptionParagraphs[i].split("\\n \\*"))
87+
.map(s -> s.replace("\n", ""))
88+
.collect(Collectors.toList());
89+
if (startsWithItemizedList) {
90+
// Remove the first asterisk.
91+
listItems.set(0, listItems.get(0).substring(2));
92+
}
93+
94+
if (!startsWithItemizedList) {
95+
if (i == 0) {
96+
javaDocCommentBuilder =
97+
javaDocCommentBuilder.addParagraph(
98+
String.format(SERVICE_DESCRIPTION_HEADER_PATTERN, listItems.get(0)));
99+
} else {
100+
javaDocCommentBuilder = javaDocCommentBuilder.addParagraph(listItems.get(0));
101+
}
102+
}
103+
if (listItems.size() > 1 || startsWithItemizedList) {
81104
javaDocCommentBuilder =
82-
javaDocCommentBuilder.addParagraph(
83-
String.format(SERVICE_DESCRIPTION_HEADER_PATTERN, descriptionParagraphs[i]));
84-
} else {
85-
javaDocCommentBuilder = javaDocCommentBuilder.addParagraph(descriptionParagraphs[i]);
105+
javaDocCommentBuilder.addUnorderedList(
106+
listItems.subList(startsWithItemizedList ? 0 : 1, listItems.size()));
86107
}
87108
}
88109
}

src/main/java/com/google/api/generator/gapic/composer/ServiceClientCommentComposer.java

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@
2121
import com.google.api.generator.gapic.model.MethodArgument;
2222
import com.google.api.generator.gapic.model.Service;
2323
import com.google.api.generator.gapic.utils.JavaStyle;
24+
import com.google.common.base.Strings;
2425
import java.util.Arrays;
2526
import java.util.Collections;
2627
import java.util.List;
28+
import java.util.stream.Collectors;
29+
import java.util.stream.Stream;
2730

2831
class ServiceClientCommentComposer {
2932
// Tokens.
@@ -102,8 +105,11 @@ class ServiceClientCommentComposer {
102105
static List<CommentStatement> createClassHeaderComments(Service service) {
103106
JavaDocComment.Builder classHeaderJavadocBuilder = JavaDocComment.builder();
104107
if (service.hasDescription()) {
105-
classHeaderJavadocBuilder.addComment(
106-
String.format(SERVICE_DESCRIPTION_SUMMARY_PATTERN, service.description()));
108+
classHeaderJavadocBuilder =
109+
processProtobufComment(
110+
service.description(),
111+
classHeaderJavadocBuilder,
112+
SERVICE_DESCRIPTION_SUMMARY_PATTERN);
107113
}
108114

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

148154
if (method.hasDescription()) {
149-
methodJavadocBuilder.addComment(method.description());
155+
methodJavadocBuilder =
156+
processProtobufComment(method.description(), methodJavadocBuilder, null);
150157
}
151158

152159
methodJavadocBuilder.addParagraph(METHOD_DESCRIPTION_SAMPLE_CODE_SUMMARY_STRING);
@@ -157,8 +164,11 @@ static List<CommentStatement> createRpcMethodHeaderComment(
157164
"request", "The request object containing all of the parameters for the API call.");
158165
} else {
159166
for (MethodArgument argument : methodArguments) {
167+
// TODO(miraleung): Remove the newline replacement when we support CommonMark.
160168
String description =
161-
argument.field().hasDescription() ? argument.field().description() : EMPTY_STRING;
169+
argument.field().hasDescription()
170+
? argument.field().description().replace("\n", "")
171+
: EMPTY_STRING;
162172
methodJavadocBuilder.addParam(argument.name(), description);
163173
}
164174
}
@@ -190,7 +200,8 @@ static List<CommentStatement> createRpcCallableMethodHeaderComment(Method method
190200
JavaDocComment.Builder methodJavadocBuilder = JavaDocComment.builder();
191201

192202
if (method.hasDescription()) {
193-
methodJavadocBuilder.addComment(method.description());
203+
methodJavadocBuilder =
204+
processProtobufComment(method.description(), methodJavadocBuilder, null);
194205
}
195206

196207
methodJavadocBuilder.addParagraph(METHOD_DESCRIPTION_SAMPLE_CODE_SUMMARY_STRING);
@@ -204,4 +215,42 @@ static List<CommentStatement> createRpcCallableMethodHeaderComment(Method method
204215
private static CommentStatement toSimpleComment(String comment) {
205216
return CommentStatement.withComment(JavaDocComment.withComment(comment));
206217
}
218+
219+
// TODO(miraleung): Replace this with a comment converter when we upport CommonMark.
220+
private static JavaDocComment.Builder processProtobufComment(
221+
String rawComment, JavaDocComment.Builder originalCommentBuilder, String firstPattern) {
222+
JavaDocComment.Builder commentBuilder = originalCommentBuilder;
223+
String[] descriptionParagraphs = rawComment.split("\\n\\n");
224+
for (int i = 0; i < descriptionParagraphs.length; i++) {
225+
boolean startsWithItemizedList = descriptionParagraphs[i].startsWith(" * ");
226+
// Split by listed items, then join newlines.
227+
List<String> listItems =
228+
Stream.of(descriptionParagraphs[i].split("\\n \\*"))
229+
.map(s -> s.replace("\n", ""))
230+
.collect(Collectors.toList());
231+
if (startsWithItemizedList) {
232+
// Remove the first asterisk.
233+
listItems.set(0, listItems.get(0).substring(2));
234+
}
235+
if (!startsWithItemizedList) {
236+
if (i == 0) {
237+
if (!Strings.isNullOrEmpty(firstPattern)) {
238+
commentBuilder =
239+
commentBuilder.addParagraph(String.format(firstPattern, listItems.get(0)));
240+
} else {
241+
commentBuilder = commentBuilder.addParagraph(listItems.get(0));
242+
}
243+
} else {
244+
commentBuilder = commentBuilder.addParagraph(listItems.get(0));
245+
}
246+
}
247+
if (listItems.size() > 1 || startsWithItemizedList) {
248+
commentBuilder =
249+
commentBuilder.addUnorderedList(
250+
listItems.subList(startsWithItemizedList ? 0 : 1, listItems.size()));
251+
}
252+
}
253+
254+
return commentBuilder;
255+
}
207256
}

src/main/java/com/google/api/generator/gapic/model/SourceCodeInfoLocation.java

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414

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

17-
import com.google.common.escape.Escaper;
18-
import com.google.common.escape.Escapers;
1917
import com.google.protobuf.DescriptorProtos.SourceCodeInfo.Location;
2018
import javax.annotation.Nonnull;
2119

@@ -24,9 +22,6 @@
2422
* additional documentation on descriptor.proto.
2523
*/
2624
public class SourceCodeInfoLocation {
27-
// Not a singleton because of nested-class instantiation mechanics.
28-
private final NewlineEscaper ESCAPER = new NewlineEscaper();
29-
3025
@Nonnull private final Location location;
3126

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

5247
private String processProtobufComment(String s) {
53-
return ESCAPER.escape(s).trim();
54-
}
55-
56-
private class NewlineEscaper extends Escaper {
57-
private final Escaper charEscaper = Escapers.builder().addEscape('\n', "").build();
58-
59-
@Override
60-
public String escape(String sourceString) {
61-
return charEscaper.escape(sourceString);
62-
}
48+
return s.trim();
6349
}
6450
}

src/test/java/com/google/api/generator/gapic/protoparser/SourceCodeInfoParserTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public void setUp() throws Exception {
4848
public void getServiceInfo() {
4949
SourceCodeInfoLocation location = parser.getLocation(protoFile.findServiceByName("FooService"));
5050
assertEquals(
51-
"This is a service description. It takes up multiple lines, like so.",
51+
"This is a service description.\n It takes up multiple lines, like so.",
5252
location.getLeadingComments());
5353

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

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

7979
// Fields.
8080
location = parser.getLocation(message.findFieldByName("field_one"));
8181
assertEquals(
82-
"This is a field description for field_one. And here is the second line of that"
82+
"This is a field description for field_one.\n And here is the second line of that"
8383
+ " description.",
8484
location.getLeadingComments());
8585
assertEquals("A field trailing comment.", location.getTrailingComments());

0 commit comments

Comments
 (0)