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 // Author: kenton@google.com (Kenton Varda)
9 // Based on original Protocol Buffers design by
10 // Sanjay Ghemawat, Jeff Dean, and others.
11
12 #include <memory>
13 #include <string>
14 #include <tuple>
15
16 #include "absl/container/flat_hash_map.h"
17 #include "absl/log/absl_check.h"
18 #include "absl/memory/memory.h"
19 #include "absl/strings/escaping.h"
20 #include "absl/strings/str_cat.h"
21 #include "absl/strings/string_view.h"
22 #include "absl/strings/substitute.h"
23 #include "google/protobuf/compiler/cpp/field.h"
24 #include "google/protobuf/compiler/cpp/field_generators/generators.h"
25 #include "google/protobuf/compiler/cpp/helpers.h"
26 #include "google/protobuf/compiler/cpp/options.h"
27 #include "google/protobuf/descriptor.h"
28
29 namespace google {
30 namespace protobuf {
31 namespace compiler {
32 namespace cpp {
33 namespace {
SetCordVariables(const FieldDescriptor * descriptor,absl::flat_hash_map<absl::string_view,std::string> * variables,const Options & options)34 void SetCordVariables(
35 const FieldDescriptor* descriptor,
36 absl::flat_hash_map<absl::string_view, std::string>* variables,
37 const Options& options) {
38 (*variables)["default"] = absl::StrCat(
39 "\"", absl::CEscape(descriptor->default_value_string()), "\"");
40 (*variables)["default_length"] =
41 absl::StrCat(descriptor->default_value_string().length());
42 (*variables)["full_name"] = descriptor->full_name();
43 // For one of Cords
44 (*variables)["default_variable_name"] = MakeDefaultName(descriptor);
45 (*variables)["default_variable_field"] = MakeDefaultFieldName(descriptor);
46 (*variables)["default_variable"] =
47 descriptor->default_value_string().empty()
48 ? absl::StrCat("::", ProtobufNamespace(options),
49 "::internal::GetEmptyCordAlreadyInited()")
50 : absl::StrCat(
51 QualifiedClassName(descriptor->containing_type(), options),
52 "::", MakeDefaultFieldName(descriptor));
53 }
54
55 class CordFieldGenerator : public FieldGeneratorBase {
56 public:
57 CordFieldGenerator(const FieldDescriptor* descriptor, const Options& options,
58 MessageSCCAnalyzer* scc);
59 ~CordFieldGenerator() override = default;
60
61 void GeneratePrivateMembers(io::Printer* printer) const override;
62 void GenerateAccessorDeclarations(io::Printer* printer) const override;
63 void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
64 void GenerateClearingCode(io::Printer* printer) const override;
65 void GenerateMergingCode(io::Printer* printer) const override;
66 void GenerateSwappingCode(io::Printer* printer) const override;
67 void GenerateConstructorCode(io::Printer* printer) const override;
68 void GenerateArenaDestructorCode(io::Printer* printer) const override;
69 void GenerateSerializeWithCachedSizesToArray(
70 io::Printer* printer) const override;
71 void GenerateByteSize(io::Printer* printer) const override;
72 void GenerateAggregateInitializer(io::Printer* printer) const override;
73 void GenerateConstexprAggregateInitializer(
74 io::Printer* printer) const override;
NeedsArenaDestructor() const75 ArenaDtorNeeds NeedsArenaDestructor() const override {
76 return ArenaDtorNeeds::kRequired;
77 }
78
GenerateMemberConstexprConstructor(io::Printer * p) const79 void GenerateMemberConstexprConstructor(io::Printer* p) const override {
80 if (field_->default_value_string().empty()) {
81 p->Emit("$name$_{}");
82 } else {
83 p->Emit({{"Split", ShouldSplit(field_, options_) ? "Split::" : ""}},
84 "$name$_{::absl::strings_internal::MakeStringConstant("
85 "$classname$::Impl_::$Split$_default_$name$_func_{})}");
86 }
87 }
88
GenerateMemberConstructor(io::Printer * p) const89 void GenerateMemberConstructor(io::Printer* p) const override {
90 auto vars = p->WithVars(variables_);
91 if (field_->default_value_string().empty()) {
92 p->Emit("$name$_{}");
93 } else {
94 p->Emit("$name$_{::absl::string_view($default$, $default_length$)}");
95 }
96 }
97
GenerateMemberCopyConstructor(io::Printer * p) const98 void GenerateMemberCopyConstructor(io::Printer* p) const override {
99 auto vars = p->WithVars(variables_);
100 p->Emit("$name$_{from.$name$_}");
101 }
102
GenerateOneofCopyConstruct(io::Printer * p) const103 void GenerateOneofCopyConstruct(io::Printer* p) const override {
104 auto vars = p->WithVars(variables_);
105 p->Emit(R"cc(
106 $field$ = ::$proto_ns$::Arena::Create<absl::Cord>(arena, *from.$field$);
107 )cc");
108 }
109 };
110
111 class CordOneofFieldGenerator : public CordFieldGenerator {
112 public:
113 CordOneofFieldGenerator(const FieldDescriptor* descriptor,
114 const Options& options, MessageSCCAnalyzer* scc);
115 ~CordOneofFieldGenerator() override = default;
116
117 void GeneratePrivateMembers(io::Printer* printer) const override;
118 void GenerateStaticMembers(io::Printer* printer) const override;
119 void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
120 void GenerateNonInlineAccessorDefinitions(
121 io::Printer* printer) const override;
122 bool RequiresArena(GeneratorFunction func) const override;
123 void GenerateClearingCode(io::Printer* printer) const override;
124 void GenerateSwappingCode(io::Printer* printer) const override;
125 void GenerateMergingCode(io::Printer* printer) const override;
GenerateConstructorCode(io::Printer * printer) const126 void GenerateConstructorCode(io::Printer* printer) const override {}
127 void GenerateArenaDestructorCode(io::Printer* printer) const override;
128 // Overrides CordFieldGenerator behavior.
NeedsArenaDestructor() const129 ArenaDtorNeeds NeedsArenaDestructor() const override {
130 return ArenaDtorNeeds::kNone;
131 }
132 };
133
134
CordFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc)135 CordFieldGenerator::CordFieldGenerator(const FieldDescriptor* descriptor,
136 const Options& options,
137 MessageSCCAnalyzer* scc)
138 : FieldGeneratorBase(descriptor, options, scc) {
139 SetCordVariables(descriptor, &variables_, options);
140 }
141
GeneratePrivateMembers(io::Printer * printer) const142 void CordFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
143 Formatter format(printer, variables_);
144 format("::absl::Cord $name$_;\n");
145 if (!field_->default_value_string().empty()) {
146 format(
147 "struct _default_$name$_func_ {\n"
148 " constexpr absl::string_view operator()() const {\n"
149 " return absl::string_view($default$, $default_length$);\n"
150 " }\n"
151 "};\n");
152 }
153 }
154
GenerateAccessorDeclarations(io::Printer * printer) const155 void CordFieldGenerator::GenerateAccessorDeclarations(
156 io::Printer* printer) const {
157 Formatter format(printer, variables_);
158 format("$deprecated_attr$const ::absl::Cord& ${1$$name$$}$() const;\n",
159 field_);
160 format(
161 "$deprecated_attr$void ${1$set_$name$$}$(const ::absl::Cord& value);\n"
162 "$deprecated_attr$void ${1$set_$name$$}$(::absl::string_view value);\n",
163 std::make_tuple(field_, GeneratedCodeInfo::Annotation::SET));
164 format(
165 "private:\n"
166 "const ::absl::Cord& ${1$_internal_$name$$}$() const;\n"
167 "void ${1$_internal_set_$name$$}$(const ::absl::Cord& value);\n"
168 "::absl::Cord* ${1$_internal_mutable_$name$$}$();\n"
169 "public:\n",
170 field_);
171 }
172
GenerateInlineAccessorDefinitions(io::Printer * printer) const173 void CordFieldGenerator::GenerateInlineAccessorDefinitions(
174 io::Printer* printer) const {
175 auto v = printer->WithVars(variables_);
176 printer->Emit(R"cc(
177 inline const ::absl::Cord& $classname$::_internal_$name_internal$() const {
178 return $field$;
179 }
180 )cc");
181 printer->Emit(R"cc(
182 inline const ::absl::Cord& $classname$::$name$() const
183 ABSL_ATTRIBUTE_LIFETIME_BOUND {
184 $WeakDescriptorSelfPin$;
185 $annotate_get$;
186 // @@protoc_insertion_point(field_get:$full_name$)
187 return _internal_$name_internal$();
188 }
189 )cc");
190 printer->Emit(R"cc(
191 inline void $classname$::_internal_set_$name_internal$(
192 const ::absl::Cord& value) {
193 $set_hasbit$;
194 $field$ = value;
195 }
196 )cc");
197 printer->Emit(R"cc(
198 inline void $classname$::set_$name$(const ::absl::Cord& value) {
199 $WeakDescriptorSelfPin$;
200 $PrepareSplitMessageForWrite$;
201 _internal_set_$name_internal$(value);
202 $annotate_set$;
203 // @@protoc_insertion_point(field_set:$full_name$)
204 }
205 )cc");
206 printer->Emit(R"cc(
207 inline void $classname$::set_$name$(::absl::string_view value) {
208 $WeakDescriptorSelfPin$;
209 $PrepareSplitMessageForWrite$;
210 $set_hasbit$;
211 $field$ = value;
212 $annotate_set$;
213 // @@protoc_insertion_point(field_set_string_piece:$full_name$)
214 }
215 )cc");
216 printer->Emit(R"cc(
217 inline ::absl::Cord* $classname$::_internal_mutable_$name_internal$() {
218 $set_hasbit$;
219 return &$field$;
220 }
221 )cc");
222 }
223
GenerateClearingCode(io::Printer * printer) const224 void CordFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
225 Formatter format(printer, variables_);
226 if (field_->default_value_string().empty()) {
227 format("$field$.Clear();\n");
228 } else {
229 format("$field$ = ::absl::string_view($default$, $default_length$);\n");
230 }
231 }
232
GenerateMergingCode(io::Printer * printer) const233 void CordFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
234 Formatter format(printer, variables_);
235 format("_this->_internal_set_$name$(from._internal_$name$());\n");
236 }
237
GenerateSwappingCode(io::Printer * printer) const238 void CordFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
239 Formatter format(printer, variables_);
240 format("$field$.swap(other->$field$);\n");
241 }
242
GenerateConstructorCode(io::Printer * printer) const243 void CordFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
244 ABSL_CHECK(!should_split());
245 Formatter format(printer, variables_);
246 if (!field_->default_value_string().empty()) {
247 format("$field$ = ::absl::string_view($default$, $default_length$);\n");
248 }
249 }
250
251
GenerateArenaDestructorCode(io::Printer * printer) const252 void CordFieldGenerator::GenerateArenaDestructorCode(
253 io::Printer* printer) const {
254 Formatter format(printer, variables_);
255 // _this is the object being destructed (we are inside a static method here).
256 format("_this->$field$. ::absl::Cord::~Cord ();\n");
257 }
258
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const259 void CordFieldGenerator::GenerateSerializeWithCachedSizesToArray(
260 io::Printer* printer) const {
261 Formatter format(printer, variables_);
262 if (field_->type() == FieldDescriptor::TYPE_STRING) {
263 GenerateUtf8CheckCodeForCord(
264 field_, options_, false,
265 absl::Substitute("this_._internal_$0(), ", printer->LookupVar("name")),
266 format);
267 }
268 format(
269 "target = stream->Write$declared_type$($number$, "
270 "this_._internal_$name$(), "
271 "target);\n");
272 }
273
GenerateByteSize(io::Printer * printer) const274 void CordFieldGenerator::GenerateByteSize(io::Printer* printer) const {
275 Formatter format(printer, variables_);
276 format(
277 "total_size += $tag_size$ +\n"
278 " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
279 " this_._internal_$name$());\n");
280 }
281
GenerateConstexprAggregateInitializer(io::Printer * p) const282 void CordFieldGenerator::GenerateConstexprAggregateInitializer(
283 io::Printer* p) const {
284 if (field_->default_value_string().empty()) {
285 p->Emit(R"cc(
286 /*decltype($field$)*/ {},
287 )cc");
288 } else {
289 p->Emit(
290 {{"Split", should_split() ? "Split::" : ""}},
291 R"cc(
292 /*decltype($field$)*/ {::absl::strings_internal::MakeStringConstant(
293 $classname$::Impl_::$Split$_default_$name$_func_{})},
294 )cc");
295 }
296 }
297
GenerateAggregateInitializer(io::Printer * p) const298 void CordFieldGenerator::GenerateAggregateInitializer(io::Printer* p) const {
299 if (should_split()) {
300 p->Emit(R"cc(
301 decltype(Impl_::Split::$name$_){},
302 )cc");
303 } else {
304 p->Emit(R"cc(
305 decltype($field$){},
306 )cc");
307 }
308 }
309
310 // ===================================================================
311
CordOneofFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc)312 CordOneofFieldGenerator::CordOneofFieldGenerator(
313 const FieldDescriptor* descriptor, const Options& options,
314 MessageSCCAnalyzer* scc)
315 : CordFieldGenerator(descriptor, options, scc) {}
316
GeneratePrivateMembers(io::Printer * printer) const317 void CordOneofFieldGenerator::GeneratePrivateMembers(
318 io::Printer* printer) const {
319 Formatter format(printer, variables_);
320 format("::absl::Cord *$name$_;\n");
321 }
322
GenerateStaticMembers(io::Printer * printer) const323 void CordOneofFieldGenerator::GenerateStaticMembers(
324 io::Printer* printer) const {
325 Formatter format(printer, variables_);
326 if (!field_->default_value_string().empty()) {
327 format(
328 "struct _default_$name$_func_ {\n"
329 " constexpr absl::string_view operator()() const {\n"
330 " return absl::string_view($default$, $default_length$);\n"
331 " }\n"
332 "};"
333 "static const ::absl::Cord $default_variable_name$;\n");
334 }
335 }
336
GenerateInlineAccessorDefinitions(io::Printer * printer) const337 void CordOneofFieldGenerator::GenerateInlineAccessorDefinitions(
338 io::Printer* printer) const {
339 auto v = printer->WithVars(variables_);
340 printer->Emit(R"cc(
341 inline const ::absl::Cord& $classname$::_internal_$name_internal$() const {
342 if ($has_field$) {
343 return *$field$;
344 }
345 return $default_variable$;
346 }
347 )cc");
348 printer->Emit(R"cc(
349 inline const ::absl::Cord& $classname$::$name$() const
350 ABSL_ATTRIBUTE_LIFETIME_BOUND {
351 $WeakDescriptorSelfPin$;
352 $annotate_get$;
353 // @@protoc_insertion_point(field_get:$full_name$)
354 return _internal_$name_internal$();
355 }
356 )cc");
357 printer->Emit(R"cc(
358 inline void $classname$::set_$name$(const ::absl::Cord& value) {
359 $WeakDescriptorSelfPin$;
360 if ($not_has_field$) {
361 clear_$oneof_name$();
362 set_has_$name_internal$();
363 $field$ = new ::absl::Cord;
364 ::$proto_ns$::Arena* arena = GetArena();
365 if (arena != nullptr) {
366 arena->Own($field$);
367 }
368 }
369 *$field$ = value;
370 $annotate_set$;
371 // @@protoc_insertion_point(field_set:$full_name$)
372 }
373 )cc");
374 printer->Emit(R"cc(
375 inline void $classname$::set_$name$(::absl::string_view value) {
376 $WeakDescriptorSelfPin$;
377 if ($not_has_field$) {
378 clear_$oneof_name$();
379 set_has_$name_internal$();
380 $field$ = new ::absl::Cord;
381 ::$proto_ns$::Arena* arena = GetArena();
382 if (arena != nullptr) {
383 arena->Own($field$);
384 }
385 }
386 *$field$ = value;
387 $annotate_set$;
388 // @@protoc_insertion_point(field_set_string_piece:$full_name$)
389 }
390 )cc");
391 printer->Emit(R"cc(
392 inline ::absl::Cord* $classname$::_internal_mutable_$name_internal$() {
393 if ($not_has_field$) {
394 clear_$oneof_name$();
395 set_has_$name_internal$();
396 $field$ = new ::absl::Cord;
397 ::$proto_ns$::Arena* arena = GetArena();
398 if (arena != nullptr) {
399 arena->Own($field$);
400 }
401 }
402 return $field$;
403 }
404 )cc");
405 }
406
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const407 void CordOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
408 io::Printer* printer) const {
409 Formatter format(printer, variables_);
410 if (!field_->default_value_string().empty()) {
411 format(
412 "PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT "
413 "const ::absl::Cord $classname$::$default_variable_field$(\n"
414 " ::absl::strings_internal::MakeStringConstant(\n"
415 " _default_$name$_func_{}));\n");
416 }
417 }
418
RequiresArena(GeneratorFunction func) const419 bool CordOneofFieldGenerator::RequiresArena(GeneratorFunction func) const {
420 switch (func) {
421 case GeneratorFunction::kMergeFrom:
422 return true;
423 }
424 return false;
425 }
426
GenerateClearingCode(io::Printer * printer) const427 void CordOneofFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
428 Formatter format(printer, variables_);
429 format(
430 "if (GetArena() == nullptr) {\n"
431 " delete $field$;\n"
432 "}\n");
433 }
434
GenerateSwappingCode(io::Printer * printer) const435 void CordOneofFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
436 // Don't print any swapping code. Swapping the union will swap this field.
437 }
438
GenerateArenaDestructorCode(io::Printer * printer) const439 void CordOneofFieldGenerator::GenerateArenaDestructorCode(
440 io::Printer* printer) const {
441 // We inherit from CordFieldGenerator, so we need to re-override to the
442 // default behavior here.
443 }
444
GenerateMergingCode(io::Printer * printer) const445 void CordOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
446 printer->Emit(R"cc(
447 if (oneof_needs_init) {
448 _this->$field$ = ::$proto_ns$::Arena::Create<absl::Cord>(arena);
449 }
450 *_this->$field$ = *from.$field$;
451 )cc");
452 }
453
454 // ===================================================================
455 } // namespace
456
MakeSingularCordGenerator(const FieldDescriptor * desc,const Options & options,MessageSCCAnalyzer * scc)457 std::unique_ptr<FieldGeneratorBase> MakeSingularCordGenerator(
458 const FieldDescriptor* desc, const Options& options,
459 MessageSCCAnalyzer* scc) {
460 return absl::make_unique<CordFieldGenerator>(desc, options, scc);
461 }
462
463
MakeOneofCordGenerator(const FieldDescriptor * desc,const Options & options,MessageSCCAnalyzer * scc)464 std::unique_ptr<FieldGeneratorBase> MakeOneofCordGenerator(
465 const FieldDescriptor* desc, const Options& options,
466 MessageSCCAnalyzer* scc) {
467 return absl::make_unique<CordOneofFieldGenerator>(desc, options, scc);
468 }
469
470 } // namespace cpp
471 } // namespace compiler
472 } // namespace protobuf
473 } // namespace google
474