• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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