1 // Copyright 2022 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "proto_bloat.h"
16 #include "pw_bloat/bloat_this_binary.h"
17 #include "pw_protobuf/decoder.h"
18 #include "pw_protobuf/encoder.h"
19 #include "pw_protobuf/stream_decoder.h"
20 #include "pw_protobuf_test_protos/size_report.pwpb.h"
21 #include "pw_result/result.h"
22 #include "pw_status/status.h"
23
24 #ifndef _PW_PROTOBUF_SIZE_REPORT_NO_CODEGEN
25 #define _PW_PROTOBUF_SIZE_REPORT_NO_CODEGEN 0
26 #endif // _PW_PROTOBUF_SIZE_REPORT_NO_CODEGEN
27
28 #ifndef _PW_PROTOBUF_SIZE_REPORT_WIRE_FORMAT
29 #define _PW_PROTOBUF_SIZE_REPORT_WIRE_FORMAT 0
30 #endif // _PW_PROTOBUF_SIZE_REPORT_WIRE_FORMAT
31
32 #ifndef _PW_PROTOBUF_SIZE_REPORT_MESSAGE
33 #define _PW_PROTOBUF_SIZE_REPORT_MESSAGE 0
34 #endif // _PW_PROTOBUF_SIZE_REPORT_MESSAGE
35
36 namespace pw::protobuf_size_report {
37 namespace {
38
39 template <typename T>
ConsumeValue(T val)40 PW_NO_INLINE void ConsumeValue(T val) {
41 [[maybe_unused]] volatile T no_optimize = val;
42 }
43
44 #if _PW_PROTOBUF_SIZE_REPORT_NO_CODEGEN
45
46 std::array<std::byte, pwpb::ItemInfo::kMaxEncodedSizeBytes> encode_buffer;
47 pw::protobuf::MemoryEncoder generic_encoder(encode_buffer);
48
BasicEncode()49 PW_NO_INLINE void BasicEncode() {
50 pw::Status status;
51 status.Update(generic_encoder.WriteInt64(1, 0x5001DBADFEEDBEE5));
52 status.Update(generic_encoder.WriteInt32(2, 128));
53 status.Update(generic_encoder.WriteInt32(3, 2));
54 ConsumeValue(status);
55 }
56
57 std::array<std::byte, pwpb::ItemInfo::kMaxEncodedSizeBytes> decode_buffer;
58 pw::protobuf::Decoder generic_decoder(decode_buffer);
59
BasicDecode()60 PW_NO_INLINE void BasicDecode() {
61 while (generic_decoder.Next().ok()) {
62 switch (generic_decoder.FieldNumber()) {
63 case static_cast<uint32_t>(pwpb::ItemInfo::Fields::kOffset): {
64 uint64_t value;
65 if (generic_decoder.ReadUint64(&value).ok()) {
66 ConsumeValue(value);
67 }
68 break;
69 }
70 case static_cast<uint32_t>(pwpb::ItemInfo::Fields::kSize): {
71 uint32_t value;
72 if (generic_decoder.ReadUint32(&value).ok()) {
73 ConsumeValue(value);
74 }
75 break;
76 }
77 case static_cast<uint32_t>(pwpb::ItemInfo::Fields::kAccessLevel): {
78 uint32_t value;
79
80 if (generic_decoder.ReadUint32(&value).ok()) {
81 ConsumeValue(value);
82 }
83 break;
84 }
85 }
86 }
87 }
88 #endif // _PW_PROTOBUF_SIZE_REPORT_NO_CODEGEN
89
90 #if _PW_PROTOBUF_SIZE_REPORT_WIRE_FORMAT
91
92 std::array<std::byte, pwpb::ItemInfo::kMaxEncodedSizeBytes> encode_buffer;
93 pwpb::ItemInfo::MemoryEncoder encoder(encode_buffer);
94
BasicEncode()95 PW_NO_INLINE void BasicEncode() {
96 pw::Status status;
97 status.Update(encoder.WriteOffset(0x5001DBADFEEDBEE5));
98 status.Update(encoder.WriteSize(128));
99 status.Update(encoder.WriteAccessLevel(pwpb::ItemInfo::Access::WRITE));
100 ConsumeValue(status);
101 }
102
103 std::array<std::byte, pwpb::ItemInfo::kMaxEncodedSizeBytes> decode_buffer;
104 pw::stream::MemoryReader reader(decode_buffer);
105 pwpb::ItemInfo::StreamDecoder decoder(reader);
106
BasicDecode()107 PW_NO_INLINE void BasicDecode() {
108 while (decoder.Next().ok()) {
109 pw::Result<pwpb::ItemInfo::Fields> field = decoder.Field();
110 if (!field.ok()) {
111 ConsumeValue(field.status());
112 return;
113 }
114
115 switch (field.value()) {
116 case pwpb::ItemInfo::Fields::kOffset: {
117 pw::Result<uint64_t> value = decoder.ReadOffset();
118 if (value.ok()) {
119 ConsumeValue(value);
120 }
121 break;
122 }
123 case pwpb::ItemInfo::Fields::kSize: {
124 pw::Result<uint32_t> value = decoder.ReadSize();
125 if (value.ok()) {
126 ConsumeValue(value);
127 }
128 break;
129 }
130 case pwpb::ItemInfo::Fields::kAccessLevel: {
131 pw::Result<pwpb::ItemInfo::Access> value = decoder.ReadAccessLevel();
132 if (value.ok()) {
133 ConsumeValue(value);
134 }
135 break;
136 }
137 }
138 }
139 }
140 #endif // _PW_PROTOBUF_SIZE_REPORT_WIRE_FORMAT
141
142 #if _PW_PROTOBUF_SIZE_REPORT_MESSAGE
143
144 pwpb::ItemInfo::Message message;
145
146 std::array<std::byte, pwpb::ItemInfo::kMaxEncodedSizeBytes> encode_buffer;
147 pwpb::ItemInfo::MemoryEncoder encoder(encode_buffer);
148
BasicEncode()149 PW_NO_INLINE void BasicEncode() {
150 message.offset = 0x5001DBADFEEDBEE5;
151 message.size = 128;
152 message.access_level = pwpb::ItemInfo::Access::WRITE;
153 ConsumeValue(encoder.Write(message));
154 }
155
156 std::array<std::byte, pwpb::ItemInfo::kMaxEncodedSizeBytes> decode_buffer;
157 pw::stream::MemoryReader reader(decode_buffer);
158 pwpb::ItemInfo::StreamDecoder decoder(reader);
159
BasicDecode()160 PW_NO_INLINE void BasicDecode() {
161 if (pw::Status status = decoder.Read(message); status.ok()) {
162 ConsumeValue(status);
163 }
164 }
165 #endif // _PW_PROTOBUF_SIZE_REPORT_MESSAGE
166
167 } // namespace
168 } // namespace pw::protobuf_size_report
169
main()170 int main() {
171 pw::bloat::BloatThisBinary();
172 pw::protobuf_size_report::BloatWithBase();
173 pw::protobuf_size_report::BloatWithEncoder();
174 pw::protobuf_size_report::BloatWithStreamDecoder();
175 pw::protobuf_size_report::BloatWithDecoder();
176 pw::protobuf_size_report::BloatWithTableEncoder();
177 pw::protobuf_size_report::BloatWithTableDecoder();
178 pw::protobuf_size_report::BasicEncode();
179 pw::protobuf_size_report::BasicDecode();
180 return 0;
181 }
182