1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 #include <cstddef>
9 #include <string>
10 #include <utility>
11 #include <vector>
12
13 #include "google/protobuf/testing/file.h"
14 #include "google/protobuf/testing/file.h"
15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
17 #include "absl/log/absl_check.h"
18 #include "absl/strings/str_cat.h"
19 #include "absl/strings/str_split.h"
20 #include "google/protobuf/compiler/command_line_interface.h"
21 #include "google/protobuf/compiler/java/generator.h"
22 #include "google/protobuf/test_util2.h"
23
24 namespace google {
25 namespace protobuf {
26 namespace compiler {
27 namespace java {
28 namespace {
29
30 using ::testing::ElementsAre;
31
32 // Generates Java code for the specified Java proto, returning the compiler's
33 // exit status.
CompileJavaProto(std::string proto_file_name)34 int CompileJavaProto(std::string proto_file_name) {
35 JavaGenerator java_generator;
36
37 CommandLineInterface cli;
38 cli.RegisterGenerator("--java_out", &java_generator, /*help_text=*/"");
39
40 std::string proto_path = absl::StrCat(
41 "--proto_path=",
42 TestUtil::GetTestDataPath("google/protobuf/compiler/java"));
43 std::string java_out = absl::StrCat("--java_out=", ::testing::TempDir());
44
45 const char* argv[] = {
46 "protoc",
47 proto_path.c_str(),
48 java_out.c_str(),
49 proto_file_name.c_str(),
50 };
51
52 return cli.Run(4, argv);
53 }
54
TEST(MessageSerializationTest,CollapseAdjacentExtensionRanges)55 TEST(MessageSerializationTest, CollapseAdjacentExtensionRanges) {
56 ABSL_CHECK_EQ(CompileJavaProto("message_serialization_unittest.proto"), 0);
57
58 std::string java_source;
59 ABSL_CHECK_OK(File::GetContents(
60 // Open-source codebase does not support file::JoinPath, so we manually
61 // concatenate instead.
62 absl::StrCat(::testing::TempDir(),
63 "/TestMessageWithManyExtensionRanges.java"),
64 &java_source, true));
65
66 // Open-source codebase does not support constexpr absl::string_view.
67 static constexpr const char kWriteUntilCall[] = "extensionWriter.writeUntil(";
68
69 std::vector<std::string> range_ends;
70
71 // Open-source codebase does not have absl::StrSplit overload taking a single
72 // char delimiter.
73 //
74 // NOLINTNEXTLINE(abseil-faster-strsplit-delimiter)
75 for (const auto& line : absl::StrSplit(java_source, "\n")) {
76 // Extract end position from writeUntil call. (Open-source codebase does not
77 // support RE2.)
78 std::size_t write_until_pos = line.find(kWriteUntilCall);
79 if (write_until_pos == std::string::npos) {
80 continue;
81 }
82 write_until_pos += (sizeof(kWriteUntilCall) - 1);
83
84 std::size_t comma_pos = line.find(',', write_until_pos);
85 if (comma_pos == std::string::npos) {
86 continue;
87 }
88
89 range_ends.push_back(
90 std::string(line.substr(write_until_pos, comma_pos - write_until_pos)));
91 }
92
93 EXPECT_THAT(range_ends, ElementsAre("3", "13", "43"));
94 }
95
96 } // namespace
97 } // namespace java
98 } // namespace compiler
99 } // namespace protobuf
100 } // namespace google
101