Add a mechanism for placing comments in Emit() calls that are not reproduced in the output.

PiperOrigin-RevId: 495059212
pull/11273/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent 680881def1
commit 2433d6088f
  1. 14
      src/google/protobuf/io/printer.cc
  2. 14
      src/google/protobuf/io/printer.h
  3. 16
      src/google/protobuf/io/printer_unittest.cc

@ -49,7 +49,6 @@
#include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/logging.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/escaping.h" #include "absl/strings/escaping.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h" #include "absl/strings/str_format.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
@ -156,22 +155,29 @@ Printer::Format Printer::TokenizeFormat(absl::string_view format_string,
} }
// We now split the remaining format string into lines and discard: // We now split the remaining format string into lines and discard:
// 1. All leading spaces to compute that line's indent. // 1. A trailing Printer-discarded comment, if this is a raw string.
//
// 2. All leading spaces to compute that line's indent.
// We do not do this for the first line, so that Emit(" ") works // We do not do this for the first line, so that Emit(" ") works
// correctly. We do this *regardless* of whether we are processing // correctly. We do this *regardless* of whether we are processing
// a raw string, because existing non-raw-string calls to cpp::Formatter // a raw string, because existing non-raw-string calls to cpp::Formatter
// rely on this. There is a test that validates this behavior. // rely on this. There is a test that validates this behavior.
// //
// 2. Set the indent for that line to max(0, line_indent - // 3. Set the indent for that line to max(0, line_indent -
// raw_string_indent), if this is not a raw string. // raw_string_indent), if this is not a raw string.
// //
// 3. Trailing empty lines, if we know this is a raw string, except for // 4. Trailing empty lines, if we know this is a raw string, except for
// a single extra newline at the end. // a single extra newline at the end.
// //
// Each line is itself split into chunks along the variable delimiters, e.g. // Each line is itself split into chunks along the variable delimiters, e.g.
// $...$. // $...$.
bool is_first = true; bool is_first = true;
for (absl::string_view line_text : absl::StrSplit(format_string, '\n')) { for (absl::string_view line_text : absl::StrSplit(format_string, '\n')) {
if (format.is_raw_string) {
size_t comment_index = line_text.find(options_.ignored_comment_start);
line_text = line_text.substr(0, comment_index);
}
size_t line_indent = 0; size_t line_indent = 0;
while (!is_first && absl::ConsumePrefix(&line_text, " ")) { while (!is_first && absl::ConsumePrefix(&line_text, " ")) {
++line_indent; ++line_indent;

@ -224,6 +224,17 @@ class AnnotationProtoCollector : public AnnotationCollector {
// } // }
// }; // };
// //
// # Comments
//
// It may be desirable to place comments in a raw string that are stripped out
// before printing. The prefix for Printer-ignored comments can be configured
// in Options. By default, this is `//~`.
//
// p.Emit(R"cc(
// // Will be printed in the output.
// //~ Won't be.
// )cc");
//
// # Lookup Frames // # Lookup Frames
// //
// If many calls to Emit() use the same set of variables, they can be stored // If many calls to Emit() use the same set of variables, they can be stored
@ -445,6 +456,9 @@ class PROTOBUF_EXPORT Printer {
// to allow the Printer to emit debugging annotations in the source code // to allow the Printer to emit debugging annotations in the source code
// output. // output.
absl::string_view comment_start = "//"; absl::string_view comment_start = "//";
// The token for beginning comments that are discarded by Printer's internal
// formatter.
absl::string_view ignored_comment_start = "//~";
// The number of spaces that a single level of indentation adds by default; // The number of spaces that a single level of indentation adds by default;
// this is the amount that WithIndent() increases indentation by. // this is the amount that WithIndent() increases indentation by.
size_t spaces_per_indent = 2; size_t spaces_per_indent = 2;

@ -41,14 +41,12 @@
#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor.pb.h"
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include "google/protobuf/testing/googletest.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_map.h"
#include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/logging.h"
#include "absl/strings/str_join.h" #include "absl/strings/str_join.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "google/protobuf/io/zero_copy_stream.h" #include "google/protobuf/io/zero_copy_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h" #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
namespace google { namespace google {
@ -56,7 +54,6 @@ namespace protobuf {
namespace io { namespace io {
using ::testing::AllOf; using ::testing::AllOf;
using ::testing::ElementsAre; using ::testing::ElementsAre;
using ::testing::ExplainMatchResult;
using ::testing::Field; using ::testing::Field;
using ::testing::IsEmpty; using ::testing::IsEmpty;
using ::testing::MatchesRegex; using ::testing::MatchesRegex;
@ -565,6 +562,19 @@ TEST_F(PrinterTest, EmitWithSubs) {
"};\n"); "};\n");
} }
TEST_F(PrinterTest, EmitComments) {
{
Printer printer(output());
printer.Emit(R"cc(
// Yes.
//~ No.
)cc");
printer.Emit("//~ Not a raw string.");
}
EXPECT_EQ(written(), "// Yes.\n//~ Not a raw string.");
}
TEST_F(PrinterTest, EmitWithVars) { TEST_F(PrinterTest, EmitWithVars) {
{ {
Printer printer(output()); Printer printer(output());

Loading…
Cancel
Save