xref: /aosp_15_r20/external/pigweed/pw_protobuf/codegen_encoder_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker // Copyright 2020 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker 
15*61c4878aSAndroid Build Coastguard Worker #include "pw_bytes/array.h"
16*61c4878aSAndroid Build Coastguard Worker #include "pw_protobuf/encoder.h"
17*61c4878aSAndroid Build Coastguard Worker #include "pw_protobuf/wire_format.h"
18*61c4878aSAndroid Build Coastguard Worker #include "pw_span/span.h"
19*61c4878aSAndroid Build Coastguard Worker #include "pw_stream/memory_stream.h"
20*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
21*61c4878aSAndroid Build Coastguard Worker 
22*61c4878aSAndroid Build Coastguard Worker // These header files contain the code generated by the pw_protobuf plugin.
23*61c4878aSAndroid Build Coastguard Worker // They are re-generated every time the tests are built and are used by the
24*61c4878aSAndroid Build Coastguard Worker // tests to ensure that the interface remains consistent.
25*61c4878aSAndroid Build Coastguard Worker //
26*61c4878aSAndroid Build Coastguard Worker // The purpose of the tests in this file is primarily to verify that the
27*61c4878aSAndroid Build Coastguard Worker // generated C++ interface is valid rather than the correctness of the
28*61c4878aSAndroid Build Coastguard Worker // low-level encoder.
29*61c4878aSAndroid Build Coastguard Worker #include "pw_protobuf_test_protos/full_test.pwpb.h"
30*61c4878aSAndroid Build Coastguard Worker #include "pw_protobuf_test_protos/importer.pwpb.h"
31*61c4878aSAndroid Build Coastguard Worker #include "pw_protobuf_test_protos/non_pw_package.pwpb.h"
32*61c4878aSAndroid Build Coastguard Worker #include "pw_protobuf_test_protos/proto2.pwpb.h"
33*61c4878aSAndroid Build Coastguard Worker #include "pw_protobuf_test_protos/repeated.pwpb.h"
34*61c4878aSAndroid Build Coastguard Worker 
35*61c4878aSAndroid Build Coastguard Worker #define EXPECT_SEQ_EQ(seq1, seq2) \
36*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::equal(seq1.begin(), seq1.end(), seq2.begin(), seq2.end()))
37*61c4878aSAndroid Build Coastguard Worker 
38*61c4878aSAndroid Build Coastguard Worker namespace pw::protobuf {
39*61c4878aSAndroid Build Coastguard Worker namespace {
40*61c4878aSAndroid Build Coastguard Worker 
41*61c4878aSAndroid Build Coastguard Worker using test::pwpb::Bool;
42*61c4878aSAndroid Build Coastguard Worker using test::pwpb::Enum;
43*61c4878aSAndroid Build Coastguard Worker 
44*61c4878aSAndroid Build Coastguard Worker namespace Bar = test::pwpb::Bar;
45*61c4878aSAndroid Build Coastguard Worker namespace BaseMessage = test::pwpb::BaseMessage;
46*61c4878aSAndroid Build Coastguard Worker namespace ConstrainedRepeatedTest = test::pwpb::ConstrainedRepeatedTest;
47*61c4878aSAndroid Build Coastguard Worker namespace Crate = test::pwpb::Crate;
48*61c4878aSAndroid Build Coastguard Worker namespace DeviceInfo = test::pwpb::DeviceInfo;
49*61c4878aSAndroid Build Coastguard Worker namespace Foo = test::pwpb::Foo;
50*61c4878aSAndroid Build Coastguard Worker namespace IntegerMetadata = test::pwpb::IntegerMetadata;
51*61c4878aSAndroid Build Coastguard Worker namespace KeyValuePair = test::pwpb::KeyValuePair;
52*61c4878aSAndroid Build Coastguard Worker namespace Overlay = test::pwpb::Overlay;
53*61c4878aSAndroid Build Coastguard Worker namespace Period = test::pwpb::Period;
54*61c4878aSAndroid Build Coastguard Worker namespace Pigweed = test::pwpb::Pigweed;
55*61c4878aSAndroid Build Coastguard Worker namespace Proto = test::pwpb::Proto;
56*61c4878aSAndroid Build Coastguard Worker namespace RepeatedTest = test::pwpb::RepeatedTest;
57*61c4878aSAndroid Build Coastguard Worker 
58*61c4878aSAndroid Build Coastguard Worker namespace imported {
59*61c4878aSAndroid Build Coastguard Worker namespace Timestamp = ::pw::protobuf::test::imported::pwpb::Timestamp;
60*61c4878aSAndroid Build Coastguard Worker }  // namespace imported
61*61c4878aSAndroid Build Coastguard Worker 
62*61c4878aSAndroid Build Coastguard Worker template <uint32_t val>
ToByte()63*61c4878aSAndroid Build Coastguard Worker constexpr std::byte ToByte() {
64*61c4878aSAndroid Build Coastguard Worker   static_assert(val <= 0xff);
65*61c4878aSAndroid Build Coastguard Worker   return static_cast<std::byte>(val);
66*61c4878aSAndroid Build Coastguard Worker }
67*61c4878aSAndroid Build Coastguard Worker 
TEST(Codegen,Codegen)68*61c4878aSAndroid Build Coastguard Worker TEST(Codegen, Codegen) {
69*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[Pigweed::kMaxEncodedSizeBytes +
70*61c4878aSAndroid Build Coastguard Worker                           DeviceInfo::kMaxEncodedSizeBytes];
71*61c4878aSAndroid Build Coastguard Worker   std::byte temp_buffer[Pigweed::kScratchBufferSizeBytes +
72*61c4878aSAndroid Build Coastguard Worker                         DeviceInfo::kMaxEncodedSizeBytes];
73*61c4878aSAndroid Build Coastguard Worker   stream::MemoryWriter writer(encode_buffer);
74*61c4878aSAndroid Build Coastguard Worker 
75*61c4878aSAndroid Build Coastguard Worker   Pigweed::StreamEncoder pigweed(writer, temp_buffer);
76*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), pigweed.WriteMagicNumber(73));
77*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), pigweed.WriteZiggy(-111));
78*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), pigweed.WriteErrorMessage("not a typewriter"));
79*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), pigweed.WriteBin(Pigweed::Protobuf::Binary::ZERO));
80*61c4878aSAndroid Build Coastguard Worker 
81*61c4878aSAndroid Build Coastguard Worker   {
82*61c4878aSAndroid Build Coastguard Worker     Pigweed::Pigweed::StreamEncoder pigweed_pigweed =
83*61c4878aSAndroid Build Coastguard Worker         pigweed.GetPigweedEncoder();
84*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), pigweed_pigweed.WriteStatus(Bool::FILE_NOT_FOUND));
85*61c4878aSAndroid Build Coastguard Worker 
86*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(pigweed_pigweed.status(), OkStatus());
87*61c4878aSAndroid Build Coastguard Worker   }
88*61c4878aSAndroid Build Coastguard Worker 
89*61c4878aSAndroid Build Coastguard Worker   {
90*61c4878aSAndroid Build Coastguard Worker     Proto::StreamEncoder proto = pigweed.GetProtoEncoder();
91*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), proto.WriteBin(Proto::Binary::OFF));
92*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(),
93*61c4878aSAndroid Build Coastguard Worker               proto.WritePigweedPigweedBin(Pigweed::Pigweed::Binary::ZERO));
94*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(),
95*61c4878aSAndroid Build Coastguard Worker               proto.WritePigweedProtobufBin(Pigweed::Protobuf::Binary::ZERO));
96*61c4878aSAndroid Build Coastguard Worker 
97*61c4878aSAndroid Build Coastguard Worker     {
98*61c4878aSAndroid Build Coastguard Worker       Pigweed::Protobuf::Compiler::StreamEncoder meta = proto.GetMetaEncoder();
99*61c4878aSAndroid Build Coastguard Worker       ASSERT_EQ(OkStatus(), meta.WriteFileName("/etc/passwd"));
100*61c4878aSAndroid Build Coastguard Worker       ASSERT_EQ(OkStatus(),
101*61c4878aSAndroid Build Coastguard Worker                 meta.WriteStatus(Pigweed::Protobuf::Compiler::Status::FUBAR));
102*61c4878aSAndroid Build Coastguard Worker     }
103*61c4878aSAndroid Build Coastguard Worker 
104*61c4878aSAndroid Build Coastguard Worker     {
105*61c4878aSAndroid Build Coastguard Worker       Pigweed::StreamEncoder nested_pigweed = proto.GetPigweedEncoder();
106*61c4878aSAndroid Build Coastguard Worker       ASSERT_EQ(OkStatus(),
107*61c4878aSAndroid Build Coastguard Worker                 nested_pigweed.WriteErrorMessage("here we go again"));
108*61c4878aSAndroid Build Coastguard Worker       ASSERT_EQ(OkStatus(), nested_pigweed.WriteMagicNumber(616));
109*61c4878aSAndroid Build Coastguard Worker 
110*61c4878aSAndroid Build Coastguard Worker       {
111*61c4878aSAndroid Build Coastguard Worker         DeviceInfo::StreamEncoder device_info =
112*61c4878aSAndroid Build Coastguard Worker             nested_pigweed.GetDeviceInfoEncoder();
113*61c4878aSAndroid Build Coastguard Worker 
114*61c4878aSAndroid Build Coastguard Worker         {
115*61c4878aSAndroid Build Coastguard Worker           KeyValuePair::StreamEncoder attributes =
116*61c4878aSAndroid Build Coastguard Worker               device_info.GetAttributesEncoder();
117*61c4878aSAndroid Build Coastguard Worker           ASSERT_EQ(OkStatus(), attributes.WriteKey("version"));
118*61c4878aSAndroid Build Coastguard Worker           ASSERT_EQ(OkStatus(), attributes.WriteValue("5.3.1"));
119*61c4878aSAndroid Build Coastguard Worker         }
120*61c4878aSAndroid Build Coastguard Worker 
121*61c4878aSAndroid Build Coastguard Worker         {
122*61c4878aSAndroid Build Coastguard Worker           KeyValuePair::StreamEncoder attributes =
123*61c4878aSAndroid Build Coastguard Worker               device_info.GetAttributesEncoder();
124*61c4878aSAndroid Build Coastguard Worker           ASSERT_EQ(OkStatus(), attributes.WriteKey("chip"));
125*61c4878aSAndroid Build Coastguard Worker           ASSERT_EQ(OkStatus(), attributes.WriteValue("left-soc"));
126*61c4878aSAndroid Build Coastguard Worker         }
127*61c4878aSAndroid Build Coastguard Worker 
128*61c4878aSAndroid Build Coastguard Worker         ASSERT_EQ(OkStatus(),
129*61c4878aSAndroid Build Coastguard Worker                   device_info.WriteStatus(DeviceInfo::DeviceStatus::PANIC));
130*61c4878aSAndroid Build Coastguard Worker       }
131*61c4878aSAndroid Build Coastguard Worker     }
132*61c4878aSAndroid Build Coastguard Worker   }
133*61c4878aSAndroid Build Coastguard Worker 
134*61c4878aSAndroid Build Coastguard Worker   for (unsigned i = 0; i < 5; ++i) {
135*61c4878aSAndroid Build Coastguard Worker     Proto::ID::StreamEncoder id = pigweed.GetIdEncoder();
136*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), id.WriteId(5 * i * i + 3 * i + 49));
137*61c4878aSAndroid Build Coastguard Worker   }
138*61c4878aSAndroid Build Coastguard Worker 
139*61c4878aSAndroid Build Coastguard Worker   // clang-format off
140*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {
141*61c4878aSAndroid Build Coastguard Worker     // pigweed.magic_number
142*61c4878aSAndroid Build Coastguard Worker     0x08, 0x49,
143*61c4878aSAndroid Build Coastguard Worker     // pigweed.ziggy
144*61c4878aSAndroid Build Coastguard Worker     0x10, 0xdd, 0x01,
145*61c4878aSAndroid Build Coastguard Worker     // pigweed.error_message
146*61c4878aSAndroid Build Coastguard Worker     0x2a, 0x10, 'n', 'o', 't', ' ', 'a', ' ',
147*61c4878aSAndroid Build Coastguard Worker     't', 'y', 'p', 'e', 'w', 'r', 'i', 't', 'e', 'r',
148*61c4878aSAndroid Build Coastguard Worker     // pigweed.bin
149*61c4878aSAndroid Build Coastguard Worker     0x40, 0x01,
150*61c4878aSAndroid Build Coastguard Worker     // pigweed.pigweed
151*61c4878aSAndroid Build Coastguard Worker     0x3a, 0x02,
152*61c4878aSAndroid Build Coastguard Worker     // pigweed.pigweed.status
153*61c4878aSAndroid Build Coastguard Worker     0x08, 0x02,
154*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto
155*61c4878aSAndroid Build Coastguard Worker     0x4a, 0x56,
156*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.bin
157*61c4878aSAndroid Build Coastguard Worker     0x10, 0x00,
158*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.pigweed_pigweed_bin
159*61c4878aSAndroid Build Coastguard Worker     0x18, 0x00,
160*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.pigweed_protobuf_bin
161*61c4878aSAndroid Build Coastguard Worker     0x20, 0x01,
162*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.meta
163*61c4878aSAndroid Build Coastguard Worker     0x2a, 0x0f,
164*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.meta.file_name
165*61c4878aSAndroid Build Coastguard Worker     0x0a, 0x0b, '/', 'e', 't', 'c', '/', 'p', 'a', 's', 's', 'w', 'd',
166*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.meta.status
167*61c4878aSAndroid Build Coastguard Worker     0x10, 0x02,
168*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.nested_pigweed
169*61c4878aSAndroid Build Coastguard Worker     0x0a, 0x3d,
170*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.nested_pigweed.error_message
171*61c4878aSAndroid Build Coastguard Worker     0x2a, 0x10, 'h', 'e', 'r', 'e', ' ', 'w', 'e', ' ',
172*61c4878aSAndroid Build Coastguard Worker     'g', 'o', ' ', 'a', 'g', 'a', 'i', 'n',
173*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.nested_pigweed.magic_number
174*61c4878aSAndroid Build Coastguard Worker     0x08, 0xe8, 0x04,
175*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.nested_pigweed.device_info
176*61c4878aSAndroid Build Coastguard Worker     0x32, 0x26,
177*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.nested_pigweed.device_info.attributes[0]
178*61c4878aSAndroid Build Coastguard Worker     0x22, 0x10,
179*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.nested_pigweed.device_info.attributes[0].key
180*61c4878aSAndroid Build Coastguard Worker     0x0a, 0x07, 'v', 'e', 'r', 's', 'i', 'o', 'n',
181*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.nested_pigweed.device_info.attributes[0].value
182*61c4878aSAndroid Build Coastguard Worker     0x12, 0x05, '5', '.', '3', '.', '1',
183*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.nested_pigweed.device_info.attributes[1]
184*61c4878aSAndroid Build Coastguard Worker     0x22, 0x10,
185*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.nested_pigweed.device_info.attributes[1].key
186*61c4878aSAndroid Build Coastguard Worker     0x0a, 0x04, 'c', 'h', 'i', 'p',
187*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.nested_pigweed.device_info.attributes[1].value
188*61c4878aSAndroid Build Coastguard Worker     0x12, 0x08, 'l', 'e', 'f', 't', '-', 's', 'o', 'c',
189*61c4878aSAndroid Build Coastguard Worker     // pigweed.proto.nested_pigweed.device_info.status
190*61c4878aSAndroid Build Coastguard Worker     0x18, 0x03,
191*61c4878aSAndroid Build Coastguard Worker     // pigweed.id[0]
192*61c4878aSAndroid Build Coastguard Worker     0x52, 0x02,
193*61c4878aSAndroid Build Coastguard Worker     // pigweed.id[0].id
194*61c4878aSAndroid Build Coastguard Worker     0x08, 0x31,
195*61c4878aSAndroid Build Coastguard Worker     // pigweed.id[1]
196*61c4878aSAndroid Build Coastguard Worker     0x52, 0x02,
197*61c4878aSAndroid Build Coastguard Worker     // pigweed.id[1].id
198*61c4878aSAndroid Build Coastguard Worker     0x08, 0x39,
199*61c4878aSAndroid Build Coastguard Worker     // pigweed.id[2]
200*61c4878aSAndroid Build Coastguard Worker     0x52, 0x02,
201*61c4878aSAndroid Build Coastguard Worker     // pigweed.id[2].id
202*61c4878aSAndroid Build Coastguard Worker     0x08, 0x4b,
203*61c4878aSAndroid Build Coastguard Worker     // pigweed.id[3]
204*61c4878aSAndroid Build Coastguard Worker     0x52, 0x02,
205*61c4878aSAndroid Build Coastguard Worker     // pigweed.id[3].id
206*61c4878aSAndroid Build Coastguard Worker     0x08, 0x67,
207*61c4878aSAndroid Build Coastguard Worker     // pigweed.id[4]
208*61c4878aSAndroid Build Coastguard Worker     0x52, 0x03,
209*61c4878aSAndroid Build Coastguard Worker     // pigweed.id[4].id
210*61c4878aSAndroid Build Coastguard Worker     0x08, 0x8d, 0x01
211*61c4878aSAndroid Build Coastguard Worker   };
212*61c4878aSAndroid Build Coastguard Worker   // clang-format on
213*61c4878aSAndroid Build Coastguard Worker 
214*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result = writer.WrittenData();
215*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(pigweed.status(), OkStatus());
216*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
217*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
218*61c4878aSAndroid Build Coastguard Worker             0);
219*61c4878aSAndroid Build Coastguard Worker }
220*61c4878aSAndroid Build Coastguard Worker 
TEST(Codegen,RecursiveSubmessage)221*61c4878aSAndroid Build Coastguard Worker TEST(Codegen, RecursiveSubmessage) {
222*61c4878aSAndroid Build Coastguard Worker   // 12 here represents the longest name. Note that all field structure is taken
223*61c4878aSAndroid Build Coastguard Worker   // care of, we just have to multiply by how many crates we're encoding, ie. 4.
224*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[(Crate::kMaxEncodedSizeBytes + 12) * 4];
225*61c4878aSAndroid Build Coastguard Worker 
226*61c4878aSAndroid Build Coastguard Worker   Crate::MemoryEncoder biggest_crate(encode_buffer);
227*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), biggest_crate.WriteName("Huge crate"));
228*61c4878aSAndroid Build Coastguard Worker 
229*61c4878aSAndroid Build Coastguard Worker   {
230*61c4878aSAndroid Build Coastguard Worker     Crate::StreamEncoder medium_crate = biggest_crate.GetSmallerCratesEncoder();
231*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), medium_crate.WriteName("Medium crate"));
232*61c4878aSAndroid Build Coastguard Worker     {
233*61c4878aSAndroid Build Coastguard Worker       Crate::StreamEncoder small_crate = medium_crate.GetSmallerCratesEncoder();
234*61c4878aSAndroid Build Coastguard Worker       ASSERT_EQ(OkStatus(), small_crate.WriteName("Small crate"));
235*61c4878aSAndroid Build Coastguard Worker     }
236*61c4878aSAndroid Build Coastguard Worker     {
237*61c4878aSAndroid Build Coastguard Worker       Crate::StreamEncoder tiny_crate = medium_crate.GetSmallerCratesEncoder();
238*61c4878aSAndroid Build Coastguard Worker       ASSERT_EQ(OkStatus(), tiny_crate.WriteName("Tiny crate"));
239*61c4878aSAndroid Build Coastguard Worker     }
240*61c4878aSAndroid Build Coastguard Worker   }
241*61c4878aSAndroid Build Coastguard Worker 
242*61c4878aSAndroid Build Coastguard Worker   // clang-format off
243*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {
244*61c4878aSAndroid Build Coastguard Worker     // crate.name
245*61c4878aSAndroid Build Coastguard Worker     0x0a, 0x0a, 'H', 'u', 'g', 'e', ' ', 'c', 'r', 'a', 't', 'e',
246*61c4878aSAndroid Build Coastguard Worker     // crate.smaller_crate[0]
247*61c4878aSAndroid Build Coastguard Worker     0x12, 0x2b,
248*61c4878aSAndroid Build Coastguard Worker     // crate.smaller_crate[0].name
249*61c4878aSAndroid Build Coastguard Worker     0x0a, 0x0c, 'M', 'e', 'd', 'i', 'u', 'm', ' ', 'c', 'r', 'a', 't', 'e',
250*61c4878aSAndroid Build Coastguard Worker     // crate.smaller_crate[0].smaller_crate[0]
251*61c4878aSAndroid Build Coastguard Worker     0x12, 0x0d,
252*61c4878aSAndroid Build Coastguard Worker     // crate.smaller_crate[0].smaller_crate[0].name
253*61c4878aSAndroid Build Coastguard Worker     0x0a, 0x0b, 'S', 'm', 'a', 'l', 'l', ' ', 'c', 'r', 'a', 't', 'e',
254*61c4878aSAndroid Build Coastguard Worker     // crate.smaller_crate[0].smaller_crate[1]
255*61c4878aSAndroid Build Coastguard Worker     0x12, 0x0c,
256*61c4878aSAndroid Build Coastguard Worker     // crate.smaller_crate[0].smaller_crate[1].name
257*61c4878aSAndroid Build Coastguard Worker     0x0a, 0x0a, 'T', 'i', 'n', 'y', ' ', 'c', 'r', 'a', 't', 'e',
258*61c4878aSAndroid Build Coastguard Worker   };
259*61c4878aSAndroid Build Coastguard Worker   // clang-format on
260*61c4878aSAndroid Build Coastguard Worker 
261*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result(biggest_crate);
262*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(biggest_crate.status(), OkStatus());
263*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
264*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
265*61c4878aSAndroid Build Coastguard Worker             0);
266*61c4878aSAndroid Build Coastguard Worker }
267*61c4878aSAndroid Build Coastguard Worker 
TEST(CodegenRepeated,ConstrainedFull)268*61c4878aSAndroid Build Coastguard Worker TEST(CodegenRepeated, ConstrainedFull) {
269*61c4878aSAndroid Build Coastguard Worker   // Write and expect non-packed since that's the worst-case size.
270*61c4878aSAndroid Build Coastguard Worker 
271*61c4878aSAndroid Build Coastguard Worker   // clang-format off
272*61c4878aSAndroid Build Coastguard Worker   constexpr auto expected_proto = bytes::Array<
273*61c4878aSAndroid Build Coastguard Worker     // uint32s[], v={0xdeadbeef, 0x2b84f00d}
274*61c4878aSAndroid Build Coastguard Worker     ToByte<FieldKey(1, WireType::kFixed32)>(), 0xef, 0xbe, 0xad, 0xde,
275*61c4878aSAndroid Build Coastguard Worker     ToByte<FieldKey(1, WireType::kFixed32)>(), 0x0d, 0xf0, 0x84, 0x2b
276*61c4878aSAndroid Build Coastguard Worker   >();
277*61c4878aSAndroid Build Coastguard Worker   // clang-format on
278*61c4878aSAndroid Build Coastguard Worker 
279*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[ConstrainedRepeatedTest::kMaxEncodedSizeBytes];
280*61c4878aSAndroid Build Coastguard Worker 
281*61c4878aSAndroid Build Coastguard Worker   // In this test, we expect to exactly utilize the encoding buffer.
282*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(ConstrainedRepeatedTest::kMaxEncodedSizeBytes,
283*61c4878aSAndroid Build Coastguard Worker             expected_proto.size());
284*61c4878aSAndroid Build Coastguard Worker 
285*61c4878aSAndroid Build Coastguard Worker   stream::MemoryWriter writer(encode_buffer);
286*61c4878aSAndroid Build Coastguard Worker   ConstrainedRepeatedTest::StreamEncoder encoder(writer, ByteSpan());
287*61c4878aSAndroid Build Coastguard Worker 
288*61c4878aSAndroid Build Coastguard Worker   PW_TEST_ASSERT_OK(encoder.WriteFixed32s(0xdeadbeef));
289*61c4878aSAndroid Build Coastguard Worker   PW_TEST_ASSERT_OK(encoder.WriteFixed32s(0x2b84f00d));
290*61c4878aSAndroid Build Coastguard Worker 
291*61c4878aSAndroid Build Coastguard Worker   PW_TEST_ASSERT_OK(encoder.status());
292*61c4878aSAndroid Build Coastguard Worker   EXPECT_SEQ_EQ(writer.WrittenData(), expected_proto);
293*61c4878aSAndroid Build Coastguard Worker }
294*61c4878aSAndroid Build Coastguard Worker 
TEST(CodegenRepeated,NonPackedScalar)295*61c4878aSAndroid Build Coastguard Worker TEST(CodegenRepeated, NonPackedScalar) {
296*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[RepeatedTest::kMaxEncodedSizeBytes];
297*61c4878aSAndroid Build Coastguard Worker 
298*61c4878aSAndroid Build Coastguard Worker   stream::MemoryWriter writer(encode_buffer);
299*61c4878aSAndroid Build Coastguard Worker   RepeatedTest::StreamEncoder repeated_test(writer, ByteSpan());
300*61c4878aSAndroid Build Coastguard Worker   for (uint32_t i = 0; i < 4; ++i) {
301*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), repeated_test.WriteUint32s(i * 16));
302*61c4878aSAndroid Build Coastguard Worker   }
303*61c4878aSAndroid Build Coastguard Worker 
304*61c4878aSAndroid Build Coastguard Worker   for (uint32_t i = 0; i < 4; ++i) {
305*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), repeated_test.WriteFixed32s(i * 16));
306*61c4878aSAndroid Build Coastguard Worker   }
307*61c4878aSAndroid Build Coastguard Worker 
308*61c4878aSAndroid Build Coastguard Worker   // clang-format off
309*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {
310*61c4878aSAndroid Build Coastguard Worker     // uint32s[], v={0, 16, 32, 48}
311*61c4878aSAndroid Build Coastguard Worker     0x08, 0x00,
312*61c4878aSAndroid Build Coastguard Worker     0x08, 0x10,
313*61c4878aSAndroid Build Coastguard Worker     0x08, 0x20,
314*61c4878aSAndroid Build Coastguard Worker     0x08, 0x30,
315*61c4878aSAndroid Build Coastguard Worker     // fixed32s[]. v={0, 16, 32, 48}
316*61c4878aSAndroid Build Coastguard Worker     0x35, 0x00, 0x00, 0x00, 0x00,
317*61c4878aSAndroid Build Coastguard Worker     0x35, 0x10, 0x00, 0x00, 0x00,
318*61c4878aSAndroid Build Coastguard Worker     0x35, 0x20, 0x00, 0x00, 0x00,
319*61c4878aSAndroid Build Coastguard Worker     0x35, 0x30, 0x00, 0x00, 0x00,
320*61c4878aSAndroid Build Coastguard Worker   };
321*61c4878aSAndroid Build Coastguard Worker   // clang-format on
322*61c4878aSAndroid Build Coastguard Worker 
323*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result = writer.WrittenData();
324*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(repeated_test.status(), OkStatus());
325*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
326*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
327*61c4878aSAndroid Build Coastguard Worker             0);
328*61c4878aSAndroid Build Coastguard Worker }
329*61c4878aSAndroid Build Coastguard Worker 
TEST(CodegenRepeated,PackedScalar)330*61c4878aSAndroid Build Coastguard Worker TEST(CodegenRepeated, PackedScalar) {
331*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[RepeatedTest::kMaxEncodedSizeBytes];
332*61c4878aSAndroid Build Coastguard Worker 
333*61c4878aSAndroid Build Coastguard Worker   stream::MemoryWriter writer(encode_buffer);
334*61c4878aSAndroid Build Coastguard Worker   RepeatedTest::StreamEncoder repeated_test(writer, ByteSpan());
335*61c4878aSAndroid Build Coastguard Worker   constexpr uint32_t values[] = {0, 16, 32, 48};
336*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), repeated_test.WriteUint32s(values));
337*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), repeated_test.WriteFixed32s(values));
338*61c4878aSAndroid Build Coastguard Worker 
339*61c4878aSAndroid Build Coastguard Worker   // clang-format off
340*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {
341*61c4878aSAndroid Build Coastguard Worker     // uint32s[], v={0, 16, 32, 48}
342*61c4878aSAndroid Build Coastguard Worker     0x0a, 0x04,
343*61c4878aSAndroid Build Coastguard Worker     0x00,
344*61c4878aSAndroid Build Coastguard Worker     0x10,
345*61c4878aSAndroid Build Coastguard Worker     0x20,
346*61c4878aSAndroid Build Coastguard Worker     0x30,
347*61c4878aSAndroid Build Coastguard Worker     // fixed32s[]. v={0, 16, 32, 48}
348*61c4878aSAndroid Build Coastguard Worker     0x32, 0x10,
349*61c4878aSAndroid Build Coastguard Worker     0x00, 0x00, 0x00, 0x00,
350*61c4878aSAndroid Build Coastguard Worker     0x10, 0x00, 0x00, 0x00,
351*61c4878aSAndroid Build Coastguard Worker     0x20, 0x00, 0x00, 0x00,
352*61c4878aSAndroid Build Coastguard Worker     0x30, 0x00, 0x00, 0x00,
353*61c4878aSAndroid Build Coastguard Worker   };
354*61c4878aSAndroid Build Coastguard Worker   // clang-format on
355*61c4878aSAndroid Build Coastguard Worker 
356*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result = writer.WrittenData();
357*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(repeated_test.status(), OkStatus());
358*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
359*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
360*61c4878aSAndroid Build Coastguard Worker             0);
361*61c4878aSAndroid Build Coastguard Worker }
362*61c4878aSAndroid Build Coastguard Worker 
TEST(CodegenRepeated,PackedBool)363*61c4878aSAndroid Build Coastguard Worker TEST(CodegenRepeated, PackedBool) {
364*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[RepeatedTest::kMaxEncodedSizeBytes];
365*61c4878aSAndroid Build Coastguard Worker 
366*61c4878aSAndroid Build Coastguard Worker   stream::MemoryWriter writer(encode_buffer);
367*61c4878aSAndroid Build Coastguard Worker   RepeatedTest::StreamEncoder repeated_test(writer, ByteSpan());
368*61c4878aSAndroid Build Coastguard Worker   constexpr bool values[] = {true, false, true, true, false};
369*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), repeated_test.WriteBools(span(values)));
370*61c4878aSAndroid Build Coastguard Worker 
371*61c4878aSAndroid Build Coastguard Worker   // clang-format off
372*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {
373*61c4878aSAndroid Build Coastguard Worker     // bools[], v={true, false, true, true, false}
374*61c4878aSAndroid Build Coastguard Worker     0x3a, 0x05, 0x01, 0x00, 0x01, 0x01, 0x00,
375*61c4878aSAndroid Build Coastguard Worker   };
376*61c4878aSAndroid Build Coastguard Worker   // clang-format on
377*61c4878aSAndroid Build Coastguard Worker 
378*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result = writer.WrittenData();
379*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(repeated_test.status(), OkStatus());
380*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
381*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
382*61c4878aSAndroid Build Coastguard Worker             0);
383*61c4878aSAndroid Build Coastguard Worker }
384*61c4878aSAndroid Build Coastguard Worker 
TEST(CodegenRepeated,PackedScalarVector)385*61c4878aSAndroid Build Coastguard Worker TEST(CodegenRepeated, PackedScalarVector) {
386*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[RepeatedTest::kMaxEncodedSizeBytes];
387*61c4878aSAndroid Build Coastguard Worker 
388*61c4878aSAndroid Build Coastguard Worker   stream::MemoryWriter writer(encode_buffer);
389*61c4878aSAndroid Build Coastguard Worker   RepeatedTest::StreamEncoder repeated_test(writer, ByteSpan());
390*61c4878aSAndroid Build Coastguard Worker   const pw::Vector<uint32_t, 4> values = {0, 16, 32, 48};
391*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), repeated_test.WriteUint32s(values));
392*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), repeated_test.WriteFixed32s(values));
393*61c4878aSAndroid Build Coastguard Worker 
394*61c4878aSAndroid Build Coastguard Worker   // clang-format off
395*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {
396*61c4878aSAndroid Build Coastguard Worker     // uint32s[], v={0, 16, 32, 48}
397*61c4878aSAndroid Build Coastguard Worker     0x0a, 0x04,
398*61c4878aSAndroid Build Coastguard Worker     0x00,
399*61c4878aSAndroid Build Coastguard Worker     0x10,
400*61c4878aSAndroid Build Coastguard Worker     0x20,
401*61c4878aSAndroid Build Coastguard Worker     0x30,
402*61c4878aSAndroid Build Coastguard Worker     // fixed32s[]. v={0, 16, 32, 48}
403*61c4878aSAndroid Build Coastguard Worker     0x32, 0x10,
404*61c4878aSAndroid Build Coastguard Worker     0x00, 0x00, 0x00, 0x00,
405*61c4878aSAndroid Build Coastguard Worker     0x10, 0x00, 0x00, 0x00,
406*61c4878aSAndroid Build Coastguard Worker     0x20, 0x00, 0x00, 0x00,
407*61c4878aSAndroid Build Coastguard Worker     0x30, 0x00, 0x00, 0x00,
408*61c4878aSAndroid Build Coastguard Worker   };
409*61c4878aSAndroid Build Coastguard Worker   // clang-format on
410*61c4878aSAndroid Build Coastguard Worker 
411*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result = writer.WrittenData();
412*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(repeated_test.status(), OkStatus());
413*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
414*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
415*61c4878aSAndroid Build Coastguard Worker             0);
416*61c4878aSAndroid Build Coastguard Worker }
417*61c4878aSAndroid Build Coastguard Worker 
TEST(CodegenRepeated,PackedEnum)418*61c4878aSAndroid Build Coastguard Worker TEST(CodegenRepeated, PackedEnum) {
419*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[RepeatedTest::kMaxEncodedSizeBytes];
420*61c4878aSAndroid Build Coastguard Worker 
421*61c4878aSAndroid Build Coastguard Worker   stream::MemoryWriter writer(encode_buffer);
422*61c4878aSAndroid Build Coastguard Worker   RepeatedTest::StreamEncoder repeated_test(writer, ByteSpan());
423*61c4878aSAndroid Build Coastguard Worker   constexpr Enum values[] = {Enum::RED, Enum::GREEN, Enum::AMBER, Enum::RED};
424*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(repeated_test.WriteEnums(span(values)), OkStatus());
425*61c4878aSAndroid Build Coastguard Worker 
426*61c4878aSAndroid Build Coastguard Worker   // clang-format off
427*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {
428*61c4878aSAndroid Build Coastguard Worker     // enums[], v={RED, GREEN, AMBER, RED}
429*61c4878aSAndroid Build Coastguard Worker     0x4a, 0x04, 0x00, 0x02, 0x01, 0x00
430*61c4878aSAndroid Build Coastguard Worker   };
431*61c4878aSAndroid Build Coastguard Worker   // clang-format on
432*61c4878aSAndroid Build Coastguard Worker 
433*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result = writer.WrittenData();
434*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(repeated_test.status(), OkStatus());
435*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
436*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
437*61c4878aSAndroid Build Coastguard Worker             0);
438*61c4878aSAndroid Build Coastguard Worker }
439*61c4878aSAndroid Build Coastguard Worker 
TEST(CodegenRepeated,PackedEnumVector)440*61c4878aSAndroid Build Coastguard Worker TEST(CodegenRepeated, PackedEnumVector) {
441*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[RepeatedTest::kMaxEncodedSizeBytes];
442*61c4878aSAndroid Build Coastguard Worker 
443*61c4878aSAndroid Build Coastguard Worker   stream::MemoryWriter writer(encode_buffer);
444*61c4878aSAndroid Build Coastguard Worker   RepeatedTest::StreamEncoder repeated_test(writer, ByteSpan());
445*61c4878aSAndroid Build Coastguard Worker   const pw::Vector<Enum, 4> values = {
446*61c4878aSAndroid Build Coastguard Worker       Enum::RED, Enum::GREEN, Enum::AMBER, Enum::RED};
447*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(repeated_test.WriteEnums(values), OkStatus());
448*61c4878aSAndroid Build Coastguard Worker 
449*61c4878aSAndroid Build Coastguard Worker   // clang-format off
450*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {
451*61c4878aSAndroid Build Coastguard Worker     // enums[], v={RED, GREEN, AMBER, RED}
452*61c4878aSAndroid Build Coastguard Worker     0x4a, 0x04, 0x00, 0x02, 0x01, 0x00
453*61c4878aSAndroid Build Coastguard Worker   };
454*61c4878aSAndroid Build Coastguard Worker   // clang-format on
455*61c4878aSAndroid Build Coastguard Worker 
456*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result = writer.WrittenData();
457*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(repeated_test.status(), OkStatus());
458*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
459*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
460*61c4878aSAndroid Build Coastguard Worker             0);
461*61c4878aSAndroid Build Coastguard Worker }
462*61c4878aSAndroid Build Coastguard Worker 
TEST(CodegenRepeated,NonScalar)463*61c4878aSAndroid Build Coastguard Worker TEST(CodegenRepeated, NonScalar) {
464*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[RepeatedTest::kMaxEncodedSizeBytes];
465*61c4878aSAndroid Build Coastguard Worker 
466*61c4878aSAndroid Build Coastguard Worker   stream::MemoryWriter writer(encode_buffer);
467*61c4878aSAndroid Build Coastguard Worker   RepeatedTest::StreamEncoder repeated_test(writer, ByteSpan());
468*61c4878aSAndroid Build Coastguard Worker   constexpr const char* strings[] = {"the", "quick", "brown", "fox"};
469*61c4878aSAndroid Build Coastguard Worker   for (const char* s : strings) {
470*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), repeated_test.WriteStrings(s));
471*61c4878aSAndroid Build Coastguard Worker   }
472*61c4878aSAndroid Build Coastguard Worker 
473*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {
474*61c4878aSAndroid Build Coastguard Worker       0x1a, 0x03, 't', 'h', 'e', 0x1a, 0x5, 'q',  'u', 'i', 'c', 'k',
475*61c4878aSAndroid Build Coastguard Worker       0x1a, 0x5,  'b', 'r', 'o', 'w',  'n', 0x1a, 0x3, 'f', 'o', 'x'};
476*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result = writer.WrittenData();
477*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(repeated_test.status(), OkStatus());
478*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
479*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
480*61c4878aSAndroid Build Coastguard Worker             0);
481*61c4878aSAndroid Build Coastguard Worker }
482*61c4878aSAndroid Build Coastguard Worker 
TEST(CodegenRepeated,Message)483*61c4878aSAndroid Build Coastguard Worker TEST(CodegenRepeated, Message) {
484*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[RepeatedTest::kMaxEncodedSizeBytes];
485*61c4878aSAndroid Build Coastguard Worker 
486*61c4878aSAndroid Build Coastguard Worker   RepeatedTest::MemoryEncoder repeated_test(encode_buffer);
487*61c4878aSAndroid Build Coastguard Worker   for (uint32_t i = 0; i < 3; ++i) {
488*61c4878aSAndroid Build Coastguard Worker     auto structs = repeated_test.GetStructsEncoder();
489*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), structs.WriteOne(i * 1));
490*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), structs.WriteTwo(i * 2));
491*61c4878aSAndroid Build Coastguard Worker   }
492*61c4878aSAndroid Build Coastguard Worker 
493*61c4878aSAndroid Build Coastguard Worker   // clang-format off
494*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {
495*61c4878aSAndroid Build Coastguard Worker     0x2a, 0x04, 0x08, 0x00, 0x10, 0x00, 0x2a, 0x04, 0x08,
496*61c4878aSAndroid Build Coastguard Worker     0x01, 0x10, 0x02, 0x2a, 0x04, 0x08, 0x02, 0x10, 0x04};
497*61c4878aSAndroid Build Coastguard Worker   // clang-format on
498*61c4878aSAndroid Build Coastguard Worker 
499*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result(repeated_test);
500*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(repeated_test.status(), OkStatus());
501*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
502*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
503*61c4878aSAndroid Build Coastguard Worker             0);
504*61c4878aSAndroid Build Coastguard Worker }
505*61c4878aSAndroid Build Coastguard Worker 
TEST(Codegen,Proto2)506*61c4878aSAndroid Build Coastguard Worker TEST(Codegen, Proto2) {
507*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[Foo::kMaxEncodedSizeBytes];
508*61c4878aSAndroid Build Coastguard Worker 
509*61c4878aSAndroid Build Coastguard Worker   Foo::MemoryEncoder foo(encode_buffer);
510*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), foo.WriteInteger(3));
511*61c4878aSAndroid Build Coastguard Worker 
512*61c4878aSAndroid Build Coastguard Worker   {
513*61c4878aSAndroid Build Coastguard Worker     constexpr std::byte data[] = {
514*61c4878aSAndroid Build Coastguard Worker         std::byte(0xde), std::byte(0xad), std::byte(0xbe), std::byte(0xef)};
515*61c4878aSAndroid Build Coastguard Worker     Bar::StreamEncoder bar = foo.GetBarEncoder();
516*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), bar.WriteData(data));
517*61c4878aSAndroid Build Coastguard Worker   }
518*61c4878aSAndroid Build Coastguard Worker 
519*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {
520*61c4878aSAndroid Build Coastguard Worker       0x08, 0x03, 0x1a, 0x06, 0x0a, 0x04, 0xde, 0xad, 0xbe, 0xef};
521*61c4878aSAndroid Build Coastguard Worker 
522*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result(foo);
523*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(foo.status(), OkStatus());
524*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
525*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
526*61c4878aSAndroid Build Coastguard Worker             0);
527*61c4878aSAndroid Build Coastguard Worker }
528*61c4878aSAndroid Build Coastguard Worker 
TEST(Codegen,Import)529*61c4878aSAndroid Build Coastguard Worker TEST(Codegen, Import) {
530*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[Period::kMaxEncodedSizeBytes];
531*61c4878aSAndroid Build Coastguard Worker 
532*61c4878aSAndroid Build Coastguard Worker   Period::MemoryEncoder period(encode_buffer);
533*61c4878aSAndroid Build Coastguard Worker   {
534*61c4878aSAndroid Build Coastguard Worker     imported::Timestamp::StreamEncoder start = period.GetStartEncoder();
535*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), start.WriteSeconds(1589501793));
536*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), start.WriteNanoseconds(511613110));
537*61c4878aSAndroid Build Coastguard Worker   }
538*61c4878aSAndroid Build Coastguard Worker 
539*61c4878aSAndroid Build Coastguard Worker   {
540*61c4878aSAndroid Build Coastguard Worker     imported::Timestamp::StreamEncoder end = period.GetEndEncoder();
541*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), end.WriteSeconds(1589501841));
542*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(OkStatus(), end.WriteNanoseconds(490367432));
543*61c4878aSAndroid Build Coastguard Worker   }
544*61c4878aSAndroid Build Coastguard Worker 
545*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(period.status(), OkStatus());
546*61c4878aSAndroid Build Coastguard Worker }
547*61c4878aSAndroid Build Coastguard Worker 
TEST(Codegen,NonPigweedPackage)548*61c4878aSAndroid Build Coastguard Worker TEST(Codegen, NonPigweedPackage) {
549*61c4878aSAndroid Build Coastguard Worker   namespace Packed = ::non::pigweed::package::name::pwpb::Packed;
550*61c4878aSAndroid Build Coastguard Worker 
551*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[Packed::kMaxEncodedSizeBytes];
552*61c4878aSAndroid Build Coastguard Worker   std::array<const int64_t, 2> repeated = {0, 1};
553*61c4878aSAndroid Build Coastguard Worker   stream::MemoryWriter writer(encode_buffer);
554*61c4878aSAndroid Build Coastguard Worker   Packed::StreamEncoder packed(writer, ByteSpan());
555*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), packed.WriteRep(span<const int64_t>(repeated)));
556*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(OkStatus(), packed.WritePacked("packed"));
557*61c4878aSAndroid Build Coastguard Worker 
558*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(packed.status(), OkStatus());
559*61c4878aSAndroid Build Coastguard Worker }
560*61c4878aSAndroid Build Coastguard Worker 
TEST(Codegen,MemoryToStreamConversion)561*61c4878aSAndroid Build Coastguard Worker TEST(Codegen, MemoryToStreamConversion) {
562*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[IntegerMetadata::kMaxEncodedSizeBytes];
563*61c4878aSAndroid Build Coastguard Worker   IntegerMetadata::MemoryEncoder metadata(encode_buffer);
564*61c4878aSAndroid Build Coastguard Worker   IntegerMetadata::StreamEncoder& streamed_metadata = metadata;
565*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(streamed_metadata.WriteBits(3), OkStatus());
566*61c4878aSAndroid Build Coastguard Worker 
567*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {0x08, 0x03};
568*61c4878aSAndroid Build Coastguard Worker 
569*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result(metadata);
570*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(metadata.status(), OkStatus());
571*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
572*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
573*61c4878aSAndroid Build Coastguard Worker             0);
574*61c4878aSAndroid Build Coastguard Worker }
575*61c4878aSAndroid Build Coastguard Worker 
TEST(Codegen,OverlayConversion)576*61c4878aSAndroid Build Coastguard Worker TEST(Codegen, OverlayConversion) {
577*61c4878aSAndroid Build Coastguard Worker   std::byte encode_buffer[BaseMessage::kMaxEncodedSizeBytes +
578*61c4878aSAndroid Build Coastguard Worker                           Overlay::kMaxEncodedSizeBytes];
579*61c4878aSAndroid Build Coastguard Worker   BaseMessage::MemoryEncoder base(encode_buffer);
580*61c4878aSAndroid Build Coastguard Worker   Overlay::StreamEncoder& overlay =
581*61c4878aSAndroid Build Coastguard Worker       StreamEncoderCast<Overlay::StreamEncoder>(base);
582*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(overlay.WriteHeight(15), OkStatus());
583*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(base.WriteLength(7), OkStatus());
584*61c4878aSAndroid Build Coastguard Worker 
585*61c4878aSAndroid Build Coastguard Worker   constexpr uint8_t expected_proto[] = {0x10, 0x0f, 0x08, 0x07};
586*61c4878aSAndroid Build Coastguard Worker 
587*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan result(base);
588*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(base.status(), OkStatus());
589*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), sizeof(expected_proto));
590*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)),
591*61c4878aSAndroid Build Coastguard Worker             0);
592*61c4878aSAndroid Build Coastguard Worker }
593*61c4878aSAndroid Build Coastguard Worker 
TEST(Codegen,EnumToString)594*61c4878aSAndroid Build Coastguard Worker TEST(Codegen, EnumToString) {
595*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(test::pwpb::BoolToString(test::pwpb::Bool::kTrue), "TRUE");
596*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(test::pwpb::BoolToString(test::pwpb::Bool::kFalse), "FALSE");
597*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(test::pwpb::BoolToString(test::pwpb::Bool::kFileNotFound),
598*61c4878aSAndroid Build Coastguard Worker                "FILE_NOT_FOUND");
599*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(test::pwpb::BoolToString(static_cast<test::pwpb::Bool>(12893)),
600*61c4878aSAndroid Build Coastguard Worker                "");
601*61c4878aSAndroid Build Coastguard Worker }
602*61c4878aSAndroid Build Coastguard Worker 
TEST(Codegen,NestedEnumToString)603*61c4878aSAndroid Build Coastguard Worker TEST(Codegen, NestedEnumToString) {
604*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(test::pwpb::Pigweed::Pigweed::BinaryToString(
605*61c4878aSAndroid Build Coastguard Worker                    test::pwpb::Pigweed::Pigweed::Binary::kZero),
606*61c4878aSAndroid Build Coastguard Worker                "ZERO");
607*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(test::pwpb::Pigweed::Pigweed::BinaryToString(
608*61c4878aSAndroid Build Coastguard Worker                    test::pwpb::Pigweed::Pigweed::Binary::kOne),
609*61c4878aSAndroid Build Coastguard Worker                "ONE");
610*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(test::pwpb::Pigweed::Pigweed::BinaryToString(
611*61c4878aSAndroid Build Coastguard Worker                    static_cast<test::pwpb::Pigweed::Pigweed::Binary>(12893)),
612*61c4878aSAndroid Build Coastguard Worker                "");
613*61c4878aSAndroid Build Coastguard Worker }
614*61c4878aSAndroid Build Coastguard Worker 
615*61c4878aSAndroid Build Coastguard Worker }  // namespace
616*61c4878aSAndroid Build Coastguard Worker }  // namespace pw::protobuf
617