Skip to content

Commit a20125d

Browse files
authored
fix(generator): preserve comment introducers across embedded newlines (#16332)
1 parent ac64c89 commit a20125d

2 files changed

Lines changed: 55 additions & 16 deletions

File tree

generator/internal/codegen_utils.cc

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -331,26 +331,55 @@ std::string FormatCommentBlock(std::string const& comment,
331331
if (offset >= line_length) GCP_LOG(FATAL) << "line_length is too small";
332332
auto comment_width = line_length - offset;
333333

334-
std::vector<std::string> lines;
335-
std::size_t start_pos = 0;
336-
while (start_pos != std::string::npos) {
337-
std::size_t boundary = start_pos + comment_width;
338-
std::size_t end_pos = boundary;
339-
if (boundary < comment.length()) {
340-
// Look backward from the boundary for the last word
341-
end_pos = comment.rfind(' ', boundary);
342-
// If there is only one word, find and use its boundary
343-
if (end_pos == std::string::npos || end_pos < start_pos) {
344-
end_pos = comment.find(' ', boundary);
334+
bool const has_trailing_newline = comment.back() == '\n';
335+
std::string_view comment_sv = comment;
336+
if (has_trailing_newline) {
337+
comment_sv.remove_suffix(1);
338+
}
339+
340+
std::vector<std::string_view> lines;
341+
std::vector<std::string_view> paragraphs = absl::StrSplit(comment_sv, '\n');
342+
for (auto const& paragraph : paragraphs) {
343+
if (paragraph.empty()) {
344+
lines.emplace_back();
345+
continue;
346+
}
347+
std::size_t start_pos = 0;
348+
while (start_pos != std::string_view::npos) {
349+
std::size_t boundary = start_pos + comment_width;
350+
std::size_t end_pos = boundary;
351+
if (boundary < paragraph.length()) {
352+
// Look backward from the boundary for the last word
353+
end_pos = paragraph.rfind(' ', boundary);
354+
// If there is only one word, find and use its boundary
355+
if (end_pos == std::string_view::npos || end_pos < start_pos) {
356+
end_pos = paragraph.find(' ', boundary);
357+
}
345358
}
359+
lines.push_back(paragraph.substr(start_pos, end_pos - start_pos));
360+
start_pos = paragraph.find_first_not_of(' ', end_pos);
346361
}
347-
lines.push_back(comment.substr(start_pos, end_pos - start_pos));
348-
start_pos = comment.find_first_not_of(' ', end_pos);
349362
}
350363

351364
std::string indent(indent_level * indent_width, ' ');
352-
std::string joiner = absl::StrCat("\n", indent, comment_introducer);
353-
return absl::StrCat(indent, comment_introducer, absl::StrJoin(lines, joiner));
365+
std::string trimmed_introducer = comment_introducer;
366+
while (!trimmed_introducer.empty() && trimmed_introducer.back() == ' ') {
367+
trimmed_introducer.pop_back();
368+
}
369+
370+
std::string result;
371+
for (std::size_t i = 0; i < lines.size(); ++i) {
372+
if (i > 0) result += "\n";
373+
if (lines[i].empty()) {
374+
result += absl::StrCat(indent, trimmed_introducer);
375+
continue;
376+
}
377+
result += absl::StrCat(indent, comment_introducer, lines[i]);
378+
}
379+
if (has_trailing_newline) {
380+
result += "\n";
381+
}
382+
return result;
354383
}
355384

356385
std::string FormatCommentKeyValueList(

generator/internal/codegen_utils_test.cc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,17 @@ wordthatiswaytoolong)"""},
475475
// internal)](https://cloud.google.com/compute/docs/reference/rest/v1/globalAddresses)
476476
// * [Regional (external and
477477
// internal)](https://cloud.google.com/compute/docs/reference/rest/v1/addresses)
478-
// For more information, see Reserving a static external IP address.)"""}));
478+
// For more information, see Reserving a static external IP address.)"""},
479+
FormatCommentBlockTestParams{"Line 1.\nLine 2 is here.", 1, "// ", 2,
480+
80, R"""(
481+
// Line 1.
482+
// Line 2 is here.)"""},
483+
FormatCommentBlockTestParams{
484+
"Paragraph 1.\n\nParagraph 2 with more text.", 1, "// ", 2, 80,
485+
R"""(
486+
// Paragraph 1.
487+
//
488+
// Paragraph 2 with more text.)"""}));
479489

480490
struct FormatCommentKeyValueListTestParams {
481491
std::vector<std::pair<std::string, std::string>> comment;

0 commit comments

Comments
 (0)