35 #include <google/protobuf/io/printer.h>
39 #include <google/protobuf/stubs/logging.h>
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/descriptor.pb.h>
42 #include <google/protobuf/testing/googletest.h>
43 #include <gtest/gtest.h>
44 #include <google/protobuf/io/zero_copy_stream_impl.h>
56 const int block_size = 100;
65 for (
int block_size = 1; block_size < 512; block_size *= 2) {
71 printer.Print(
"Hello World!");
72 printer.Print(
" This is the same line.\n");
73 printer.Print(
"But this is a new one.\nAnd this is another one.");
81 "Hello World! This is the same line.\n"
82 "But this is a new one.\n"
83 "And this is another one.",
91 for (
int block_size = 1; block_size < 512; block_size *= 2) {
97 printer.WriteRaw(
"Hello World!", 12);
98 printer.PrintRaw(
" This is the same line.\n");
99 printer.PrintRaw(
"But this is a new one.\nAnd this is another one.");
100 printer.WriteRaw(
"\n", 1);
101 printer.PrintRaw(string_obj);
108 "Hello World! This is the same line.\n"
109 "But this is a new one.\n"
110 "And this is another one."
120 for (
int block_size = 1; block_size < 512; block_size *= 2) {
125 std::map<std::string, std::string> vars;
127 vars[
"foo"] =
"World";
128 vars[
"bar"] =
"$foo$";
129 vars[
"abcdefg"] =
"1234";
131 printer.Print(vars,
"Hello $foo$!\nbar = $bar$\n");
132 printer.PrintRaw(
"RawBit\n");
133 printer.Print(vars,
"$abcdefg$\nA literal dollar sign: $$");
135 vars[
"foo"] =
"blah";
136 printer.Print(vars,
"\nNow foo = $foo$.");
148 "A literal dollar sign: $\n"
161 printer.Print(
"Hello $foo$!\n",
"foo",
"World");
162 printer.PrintRaw(
"RawBit\n");
163 printer.Print(
"$foo$ $bar$\n",
"foo",
"one",
"bar",
"two");
178 class MockDescriptorFile {
191 class MockDescriptor {
207 std::vector<int>
path_;
214 AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
217 std::map<std::string, std::string> vars;
220 printer.Print(vars,
"012$foo$4$bar$\n");
221 std::vector<int> path_1;
222 path_1.push_back(33);
223 std::vector<int> path_2;
224 path_2.push_back(11);
225 path_2.push_back(22);
226 MockDescriptor descriptor_1(
"path_1", path_1);
227 MockDescriptor descriptor_2(
"path_2", path_2);
228 printer.Annotate(
"foo",
"foo", &descriptor_1);
229 printer.Annotate(
"bar",
"bar", &descriptor_2);
257 AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
260 printer.Print(
"012$foo$4$bar$\n",
"foo",
"3",
"bar",
"5");
261 std::vector<int> path_1;
262 path_1.push_back(33);
263 std::vector<int> path_2;
264 path_2.push_back(11);
265 path_2.push_back(22);
266 MockDescriptor descriptor_1(
"path_1", path_1);
267 MockDescriptor descriptor_2(
"path_2", path_2);
268 printer.Annotate(
"foo",
"foo", &descriptor_1);
269 printer.Annotate(
"bar",
"bar", &descriptor_2);
297 AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
300 printer.Print(
"012$foo$4$bar$\n",
"foo",
"3",
"bar",
"5");
301 std::vector<int>
path;
321 AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
324 printer.Print(
"012$foo$4$baz$$bam$$bar$\n",
"foo",
"3",
"bar",
"5",
"baz",
326 std::vector<int>
path;
342 TEST(
Printer, AnnotateDespiteUnrelatedMultipleUses) {
346 AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
349 printer.Print(
"012$foo$4$foo$$bar$\n",
"foo",
"3",
"bar",
"5");
350 std::vector<int>
path;
370 AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
373 printer.Print(
"0\n");
375 printer.Print(
"$foo$",
"foo",
"4");
376 std::vector<int>
path;
380 printer.Print(
",\n");
381 printer.Print(
"$bar$",
"bar",
"9");
383 MockDescriptor descriptor_two(
"path",
path);
384 printer.Annotate(
"bar", &descriptor_two);
385 printer.Print(
"\n${$$D$$}$\n",
"{",
"",
"}",
"",
"D",
"d");
387 MockDescriptor descriptor_three(
"path",
path);
388 printer.Annotate(
"{",
"}", &descriptor_three);
419 AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
423 printer.Print(
"$A$$N$$B$C\n",
"A",
"",
"N",
"\nz",
"B",
"");
424 std::vector<int>
path;
445 for (
int block_size = 1; block_size < 512; block_size *= 2) {
450 std::map<std::string, std::string> vars;
452 vars[
"newline"] =
"\n";
454 printer.Print(
"This is not indented.\n");
456 printer.Print(
"This is indented\nAnd so is this\n");
458 printer.Print(
"But this is not.");
461 " And this is still the same line.\n"
462 "But this is indented.\n");
463 printer.PrintRaw(
"RawBit has indent at start\n");
464 printer.PrintRaw(
"but not after a raw newline\n");
466 "Note that a newline in a variable will break "
467 "indenting, as we see$newline$here.\n");
469 printer.Print(
"And this");
472 printer.Print(
" is double-indented\nBack to normal.");
480 "This is not indented.\n"
481 " This is indented\n"
483 "But this is not. And this is still the same line.\n"
484 " But this is indented.\n"
485 " RawBit has indent at start\n"
486 "but not after a raw newline\n"
487 "Note that a newline in a variable will break indenting, as we see\n"
489 " And this is double-indented\n"
496 #ifdef PROTOBUF_HAS_DEATH_TEST
503 EXPECT_DEBUG_DEATH(printer.Print(
"$nosuchvar$"),
"Undefined variable");
504 EXPECT_DEBUG_DEATH(printer.Print(
"$unclosed"),
"Unclosed variable name");
505 EXPECT_DEBUG_DEATH(printer.Outdent(),
"without matching Indent");
512 AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
515 printer.Print(
"012$foo$4$foo$\n",
"foo",
"3");
516 std::vector<int>
path;
519 EXPECT_DEBUG_DEATH(printer.Annotate(
"foo",
"foo", &
descriptor),
"multiple");
527 AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
530 printer.Print(
"012$foo$4$bar$\n",
"foo",
"3",
"bar",
"5");
531 std::vector<int>
path;
534 EXPECT_DEBUG_DEATH(printer.Annotate(
"bar",
"foo", &
descriptor),
"negative");
542 AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
545 printer.Print(
"012$foo$4$foo$\n",
"foo",
"3");
546 std::vector<int>
path;
549 EXPECT_DEBUG_DEATH(printer.Annotate(
"bar",
"bar", &
descriptor),
553 #endif // PROTOBUF_HAS_DEATH_TEST
562 printer.Print(
"0123456789abcdef");
572 printer.Print(
"blah");
586 printer.Print(
"0123456789abcdef");
594 printer.Print(
"blah");
602 std::vector<std::string>
args{
"arg1",
"arg2"};
603 std::map<std::string, std::string> vars{
604 {
"foo",
"bar"}, {
"baz",
"bla"}, {
"empty",
""}};
612 printer.FormatInternal(
args, vars,
"$1$ $2$");
622 printer.FormatInternal({}, vars,
"$foo$$ baz$$ empty$");
632 printer.FormatInternal({}, vars,
"$empty $$foo $$baz$");
642 printer.FormatInternal(
args, vars,
"$empty $$1$ $foo $$2$ $baz$");
655 printer.FormatInternal(
args, vars,
"$empty $\n\n$1$ $foo $$2$\n$baz$");
658 EXPECT_EQ(
"\n\n arg1 bar arg2\n bla", s);
666 AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
672 std::vector<std::string>
args{annotation.SerializeAsString(),
"arg1",
674 printer.FormatInternal(
args, vars,
"$empty $\n\n${1$$2$$}$ $3$\n$baz$");
686 #ifdef PROTOBUF_HAS_DEATH_TEST
693 EXPECT_DEATH(printer.FormatInternal(
args, vars,
"$empty $$1$"),
"Unused");
700 EXPECT_DEATH(printer.FormatInternal(
args, vars,
"$2$ $1$"),
"order");
707 EXPECT_DEATH(printer.FormatInternal(
args, vars,
"$0$"),
"failed");
714 EXPECT_DEATH(printer.FormatInternal(
args, vars,
"$1$ $2$ $3$"),
"bounds");
721 EXPECT_DEATH(printer.FormatInternal(
args, vars,
"$huh$ $1$$2$"),
"Unknown");
728 EXPECT_DEATH(printer.FormatInternal({}, vars,
"$ $"),
"Empty");
730 #endif // PROTOBUF_HAS_DEATH_TEST