• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34 
35 #include <google/protobuf/compiler/cpp/cpp_string_field.h>
36 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
37 #include <google/protobuf/descriptor.pb.h>
38 #include <google/protobuf/io/printer.h>
39 #include <google/protobuf/stubs/strutil.h>
40 
41 
42 namespace google {
43 namespace protobuf {
44 namespace compiler {
45 namespace cpp {
46 
47 namespace {
48 
SetStringVariables(const FieldDescriptor * descriptor,std::map<std::string,std::string> * variables,const Options & options)49 void SetStringVariables(const FieldDescriptor* descriptor,
50                         std::map<std::string, std::string>* variables,
51                         const Options& options) {
52   SetCommonFieldVariables(descriptor, variables, options);
53   (*variables)["default"] = DefaultValue(options, descriptor);
54   (*variables)["default_length"] =
55       StrCat(descriptor->default_value_string().length());
56   std::string default_variable_string = MakeDefaultName(descriptor);
57   (*variables)["default_variable_name"] = default_variable_string;
58 
59   if (!descriptor->default_value_string().empty()) {
60     (*variables)["lazy_variable"] =
61         QualifiedClassName(descriptor->containing_type(), options) +
62         "::" + default_variable_string;
63   }
64 
65   (*variables)["default_string"] =
66       descriptor->default_value_string().empty()
67           ? "::" + (*variables)["proto_ns"] +
68                 "::internal::GetEmptyStringAlreadyInited()"
69           : (*variables)["lazy_variable"] + ".get()";
70   (*variables)["init_value"] =
71       descriptor->default_value_string().empty()
72           ? "&::" + (*variables)["proto_ns"] +
73                 "::internal::GetEmptyStringAlreadyInited()"
74           : "nullptr";
75   (*variables)["default_value_tag"] =
76       "::" + (*variables)["proto_ns"] + "::internal::ArenaStringPtr::" +
77       (descriptor->default_value_string().empty() ? "Empty" : "NonEmpty") +
78       "Default{}";
79   (*variables)["default_variable_or_tag"] =
80       (*variables)[descriptor->default_value_string().empty()
81                        ? "default_value_tag"
82                        : "lazy_variable"];
83   (*variables)["pointer_type"] =
84       descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
85   (*variables)["null_check"] = (*variables)["DCHK"] + "(value != nullptr);\n";
86   // NOTE: Escaped here to unblock proto1->proto2 migration.
87   // TODO(liujisi): Extend this to apply for other conflicting methods.
88   (*variables)["release_name"] =
89       SafeFunctionName(descriptor->containing_type(), descriptor, "release_");
90   (*variables)["full_name"] = descriptor->full_name();
91 
92   if (options.opensource_runtime) {
93     (*variables)["string_piece"] = "::std::string";
94   } else {
95     (*variables)["string_piece"] = "::StringPiece";
96   }
97 }
98 
99 }  // namespace
100 
101 // ===================================================================
102 
StringFieldGenerator(const FieldDescriptor * descriptor,const Options & options)103 StringFieldGenerator::StringFieldGenerator(const FieldDescriptor* descriptor,
104                                            const Options& options)
105     : FieldGenerator(descriptor, options) {
106   SetStringVariables(descriptor, &variables_, options);
107 }
108 
~StringFieldGenerator()109 StringFieldGenerator::~StringFieldGenerator() {}
110 
GeneratePrivateMembers(io::Printer * printer) const111 void StringFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
112   Formatter format(printer, variables_);
113   format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n");
114 }
115 
GenerateStaticMembers(io::Printer * printer) const116 void StringFieldGenerator::GenerateStaticMembers(io::Printer* printer) const {
117   Formatter format(printer, variables_);
118   if (!descriptor_->default_value_string().empty()) {
119     format(
120         "static const ::$proto_ns$::internal::LazyString"
121         " $default_variable_name$;\n");
122   }
123 }
124 
GenerateAccessorDeclarations(io::Printer * printer) const125 void StringFieldGenerator::GenerateAccessorDeclarations(
126     io::Printer* printer) const {
127   Formatter format(printer, variables_);
128   // If we're using StringFieldGenerator for a field with a ctype, it's
129   // because that ctype isn't actually implemented.  In particular, this is
130   // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
131   // We aren't releasing Cord because it has too many Google-specific
132   // dependencies and we aren't releasing StringPiece because it's hardly
133   // useful outside of Google and because it would get confusing to have
134   // multiple instances of the StringPiece class in different libraries (PCRE
135   // already includes it for their C++ bindings, which came from Google).
136   //
137   // In any case, we make all the accessors private while still actually
138   // using a string to represent the field internally.  This way, we can
139   // guarantee that if we do ever implement the ctype, it won't break any
140   // existing users who might be -- for whatever reason -- already using .proto
141   // files that applied the ctype.  The field can still be accessed via the
142   // reflection interface since the reflection interface is independent of
143   // the string's underlying representation.
144 
145   bool unknown_ctype = descriptor_->options().ctype() !=
146                        EffectiveStringCType(descriptor_, options_);
147 
148   if (unknown_ctype) {
149     format.Outdent();
150     format(
151         " private:\n"
152         "  // Hidden due to unknown ctype option.\n");
153     format.Indent();
154   }
155 
156   format(
157       "$deprecated_attr$const std::string& ${1$$name$$}$() const;\n"
158       "$deprecated_attr$void ${1$set_$name$$}$(const std::string& value);\n"
159       "$deprecated_attr$void ${1$set_$name$$}$(std::string&& value);\n"
160       "$deprecated_attr$void ${1$set_$name$$}$(const char* value);\n",
161       descriptor_);
162   if (!options_.opensource_runtime) {
163     format(
164         "$deprecated_attr$void ${1$set_$name$$}$(::StringPiece value);\n",
165         descriptor_);
166   }
167   format(
168       "$deprecated_attr$void ${1$set_$name$$}$(const $pointer_type$* "
169       "value, size_t size)"
170       ";\n"
171       "$deprecated_attr$std::string* ${1$mutable_$name$$}$();\n"
172       "$deprecated_attr$std::string* ${1$$release_name$$}$();\n"
173       "$deprecated_attr$void ${1$set_allocated_$name$$}$(std::string* "
174       "$name$);\n",
175       descriptor_);
176   format(
177       "private:\n"
178       "const std::string& _internal_$name$() const;\n"
179       "void _internal_set_$name$(const std::string& value);\n"
180       "std::string* _internal_mutable_$name$();\n"
181       "public:\n");
182 
183   if (unknown_ctype) {
184     format.Outdent();
185     format(" public:\n");
186     format.Indent();
187   }
188 }
189 
GenerateInlineAccessorDefinitions(io::Printer * printer) const190 void StringFieldGenerator::GenerateInlineAccessorDefinitions(
191     io::Printer* printer) const {
192   Formatter format(printer, variables_);
193   format(
194       "inline const std::string& $classname$::$name$() const {\n"
195       "$annotate_accessor$"
196       "  // @@protoc_insertion_point(field_get:$full_name$)\n");
197   if (!descriptor_->default_value_string().empty()) {
198     format(
199         "  if ($name$_.IsDefault(nullptr)) return "
200         "$default_variable_name$.get();\n");
201   }
202   format(
203       "  return _internal_$name$();\n"
204       "}\n"
205       "inline void $classname$::set_$name$(const std::string& value) {\n"
206       "$annotate_accessor$"
207       "  _internal_set_$name$(value);\n"
208       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
209       "}\n"
210       "inline std::string* $classname$::mutable_$name$() {\n"
211       "$annotate_accessor$"
212       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
213       "  return _internal_mutable_$name$();\n"
214       "}\n"
215       "inline const std::string& $classname$::_internal_$name$() const {\n"
216       "  return $name$_.Get();\n"
217       "}\n"
218       "inline void $classname$::_internal_set_$name$(const std::string& "
219       "value) {\n"
220       "  $set_hasbit$\n"
221       "  $name$_.Set($default_value_tag$, value, GetArena());\n"
222       "}\n"
223       "inline void $classname$::set_$name$(std::string&& value) {\n"
224       "$annotate_accessor$"
225       "  $set_hasbit$\n"
226       "  $name$_.Set(\n"
227       "    $default_value_tag$, ::std::move(value), GetArena());\n"
228       "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
229       "}\n"
230       "inline void $classname$::set_$name$(const char* value) {\n"
231       "$annotate_accessor$"
232       "  $null_check$"
233       "  $set_hasbit$\n"
234       "  $name$_.Set($default_value_tag$, $string_piece$(value), GetArena());\n"
235       "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
236       "}\n");
237   if (!options_.opensource_runtime) {
238     format(
239         "inline void $classname$::set_$name$(::StringPiece value) {\n"
240         "$annotate_accessor$"
241         "  $set_hasbit$\n"
242         "  $name$_.Set($default_value_tag$, value,GetArena());\n"
243         "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
244         "}\n");
245   }
246   format(
247       "inline "
248       "void $classname$::set_$name$(const $pointer_type$* value,\n"
249       "    size_t size) {\n"
250       "$annotate_accessor$"
251       "  $set_hasbit$\n"
252       "  $name$_.Set($default_value_tag$, $string_piece$(\n"
253       "      reinterpret_cast<const char*>(value), size), GetArena());\n"
254       "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
255       "}\n"
256       "inline std::string* $classname$::_internal_mutable_$name$() {\n"
257       "  $set_hasbit$\n"
258       "  return $name$_.Mutable($default_variable_or_tag$, GetArena());\n"
259       "}\n"
260       "inline std::string* $classname$::$release_name$() {\n"
261       "$annotate_accessor$"
262       "  // @@protoc_insertion_point(field_release:$full_name$)\n");
263 
264   if (HasHasbit(descriptor_)) {
265     format(
266         "  if (!_internal_has_$name$()) {\n"
267         "    return nullptr;\n"
268         "  }\n"
269         "  $clear_hasbit$\n"
270         "  return $name$_.ReleaseNonDefault($init_value$, GetArena());\n");
271   } else {
272     format("  return $name$_.Release($init_value$, GetArena());\n");
273   }
274 
275   format(
276       "}\n"
277       "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
278       "$annotate_accessor$"
279       "  if ($name$ != nullptr) {\n"
280       "    $set_hasbit$\n"
281       "  } else {\n"
282       "    $clear_hasbit$\n"
283       "  }\n"
284       "  $name$_.SetAllocated($init_value$, $name$,\n"
285       "      GetArena());\n"
286       "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
287       "}\n");
288 }
289 
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const290 void StringFieldGenerator::GenerateNonInlineAccessorDefinitions(
291     io::Printer* printer) const {
292   Formatter format(printer, variables_);
293   if (!descriptor_->default_value_string().empty()) {
294     format(
295         "const ::$proto_ns$::internal::LazyString "
296         "$classname$::$default_variable_name$"
297         "{{{$default$, $default_length$}}, {nullptr}};\n");
298   }
299 }
300 
GenerateClearingCode(io::Printer * printer) const301 void StringFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
302   Formatter format(printer, variables_);
303   if (descriptor_->default_value_string().empty()) {
304     format("$name$_.ClearToEmpty();\n");
305   } else {
306     format("$name$_.ClearToDefault($lazy_variable$, GetArena());\n");
307   }
308 }
309 
GenerateMessageClearingCode(io::Printer * printer) const310 void StringFieldGenerator::GenerateMessageClearingCode(
311     io::Printer* printer) const {
312   Formatter format(printer, variables_);
313   // Two-dimension specialization here: supporting arenas, field presence, or
314   // not, and default value is the empty string or not. Complexity here ensures
315   // the minimal number of branches / amount of extraneous code at runtime
316   // (given that the below methods are inlined one-liners)!
317 
318   // If we have a hasbit, then the Clear() method of the protocol buffer
319   // will have checked that this field is set.  If so, we can avoid redundant
320   // checks against the default variable.
321   const bool must_be_present = HasHasbit(descriptor_);
322 
323   if (descriptor_->default_value_string().empty()) {
324     if (must_be_present) {
325       format("$name$_.ClearNonDefaultToEmpty();\n");
326     } else {
327       format("$name$_.ClearToEmpty();\n");
328     }
329   } else {
330     // Clear to a non-empty default is more involved, as we try to use the
331     // Arena if one is present and may need to reallocate the string.
332     format("$name$_.ClearToDefault($lazy_variable$, GetArena());\n ");
333   }
334 }
335 
GenerateMergingCode(io::Printer * printer) const336 void StringFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
337   Formatter format(printer, variables_);
338   // TODO(gpike): improve this
339   format("_internal_set_$name$(from._internal_$name$());\n");
340 }
341 
GenerateSwappingCode(io::Printer * printer) const342 void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
343   Formatter format(printer, variables_);
344   format("$name$_.Swap(&other->$name$_, $init_value$, GetArena());\n");
345 }
346 
GenerateConstructorCode(io::Printer * printer) const347 void StringFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
348   Formatter format(printer, variables_);
349   format("$name$_.UnsafeSetDefault($init_value$);\n");
350 }
351 
GenerateCopyConstructorCode(io::Printer * printer) const352 void StringFieldGenerator::GenerateCopyConstructorCode(
353     io::Printer* printer) const {
354   Formatter format(printer, variables_);
355   GenerateConstructorCode(printer);
356 
357   if (HasHasbit(descriptor_)) {
358     format("if (from._internal_has_$name$()) {\n");
359   } else {
360     format("if (!from._internal_$name$().empty()) {\n");
361   }
362 
363   format.Indent();
364 
365   // TODO(gpike): improve this
366   format(
367       "$name$_.Set($default_value_tag$, from._internal_$name$(), \n"
368       "  GetArena());\n");
369 
370   format.Outdent();
371   format("}\n");
372 }
373 
GenerateDestructorCode(io::Printer * printer) const374 void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
375   Formatter format(printer, variables_);
376   format("$name$_.DestroyNoArena($init_value$);\n");
377 }
378 
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const379 void StringFieldGenerator::GenerateSerializeWithCachedSizesToArray(
380     io::Printer* printer) const {
381   Formatter format(printer, variables_);
382   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
383     GenerateUtf8CheckCodeForString(
384         descriptor_, options_, false,
385         "this->_internal_$name$().data(), "
386         "static_cast<int>(this->_internal_$name$().length()),\n",
387         format);
388   }
389   format(
390       "target = stream->Write$declared_type$MaybeAliased(\n"
391       "    $number$, this->_internal_$name$(), target);\n");
392 }
393 
GenerateByteSize(io::Printer * printer) const394 void StringFieldGenerator::GenerateByteSize(io::Printer* printer) const {
395   Formatter format(printer, variables_);
396   format(
397       "total_size += $tag_size$ +\n"
398       "  ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
399       "    this->_internal_$name$());\n");
400 }
401 
402 // ===================================================================
403 
StringOneofFieldGenerator(const FieldDescriptor * descriptor,const Options & options)404 StringOneofFieldGenerator::StringOneofFieldGenerator(
405     const FieldDescriptor* descriptor, const Options& options)
406     : StringFieldGenerator(descriptor, options) {
407   SetCommonOneofFieldVariables(descriptor, &variables_);
408   variables_["field_name"] = UnderscoresToCamelCase(descriptor->name(), true);
409   variables_["oneof_index"] =
410       StrCat(descriptor->containing_oneof()->index());
411 }
412 
~StringOneofFieldGenerator()413 StringOneofFieldGenerator::~StringOneofFieldGenerator() {}
414 
GenerateInlineAccessorDefinitions(io::Printer * printer) const415 void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
416     io::Printer* printer) const {
417   Formatter format(printer, variables_);
418   format(
419       "inline const std::string& $classname$::$name$() const {\n"
420       "$annotate_accessor$"
421       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
422       "  return _internal_$name$();\n"
423       "}\n"
424       "inline void $classname$::set_$name$(const std::string& value) {\n"
425       "$annotate_accessor$"
426       "  _internal_set_$name$(value);\n"
427       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
428       "}\n"
429       "inline std::string* $classname$::mutable_$name$() {\n"
430       "$annotate_accessor$"
431       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
432       "  return _internal_mutable_$name$();\n"
433       "}\n"
434       "inline const std::string& $classname$::_internal_$name$() const {\n"
435       "  if (_internal_has_$name$()) {\n"
436       "    return $field_member$.Get();\n"
437       "  }\n"
438       "  return $default_string$;\n"
439       "}\n"
440       "inline void $classname$::_internal_set_$name$(const std::string& "
441       "value) {\n"
442       "  if (!_internal_has_$name$()) {\n"
443       "    clear_$oneof_name$();\n"
444       "    set_has_$name$();\n"
445       "    $field_member$.UnsafeSetDefault($init_value$);\n"
446       "  }\n"
447       "  $field_member$.Set($default_value_tag$, value, GetArena());\n"
448       "}\n"
449       "inline void $classname$::set_$name$(std::string&& value) {\n"
450       "$annotate_accessor$"
451       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
452       "  if (!_internal_has_$name$()) {\n"
453       "    clear_$oneof_name$();\n"
454       "    set_has_$name$();\n"
455       "    $field_member$.UnsafeSetDefault($init_value$);\n"
456       "  }\n"
457       "  $field_member$.Set(\n"
458       "    $default_value_tag$, ::std::move(value), GetArena());\n"
459       "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
460       "}\n"
461       "inline void $classname$::set_$name$(const char* value) {\n"
462       "$annotate_accessor$"
463       "  $null_check$"
464       "  if (!_internal_has_$name$()) {\n"
465       "    clear_$oneof_name$();\n"
466       "    set_has_$name$();\n"
467       "    $field_member$.UnsafeSetDefault($init_value$);\n"
468       "  }\n"
469       "  $field_member$.Set($default_value_tag$,\n"
470       "      $string_piece$(value), GetArena());\n"
471       "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
472       "}\n");
473   if (!options_.opensource_runtime) {
474     format(
475         "inline void $classname$::set_$name$(::StringPiece value) {\n"
476         "$annotate_accessor$"
477         "  if (!_internal_has_$name$()) {\n"
478         "    clear_$oneof_name$();\n"
479         "    set_has_$name$();\n"
480         "    $field_member$.UnsafeSetDefault($init_value$);\n"
481         "  }\n"
482         "  $field_member$.Set($default_value_tag$, value, GetArena());\n"
483         "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
484         "}\n");
485   }
486   format(
487       "inline "
488       "void $classname$::set_$name$(const $pointer_type$* value,\n"
489       "                             size_t size) {\n"
490       "$annotate_accessor$"
491       "  if (!_internal_has_$name$()) {\n"
492       "    clear_$oneof_name$();\n"
493       "    set_has_$name$();\n"
494       "    $field_member$.UnsafeSetDefault($init_value$);\n"
495       "  }\n"
496       "  $field_member$.Set(\n"
497       "      $default_value_tag$, $string_piece$(\n"
498       "      reinterpret_cast<const char*>(value), size),\n"
499       "      GetArena());\n"
500       "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
501       "}\n"
502       "inline std::string* $classname$::_internal_mutable_$name$() {\n"
503       "  if (!_internal_has_$name$()) {\n"
504       "    clear_$oneof_name$();\n"
505       "    set_has_$name$();\n"
506       "    $field_member$.UnsafeSetDefault($init_value$);\n"
507       "  }\n"
508       "  return $field_member$.Mutable(\n"
509       "      $default_variable_or_tag$, GetArena());\n"
510       "}\n"
511       "inline std::string* $classname$::$release_name$() {\n"
512       "$annotate_accessor$"
513       "  // @@protoc_insertion_point(field_release:$full_name$)\n"
514       "  if (_internal_has_$name$()) {\n"
515       "    clear_has_$oneof_name$();\n"
516       "    return $field_member$.ReleaseNonDefault($init_value$, GetArena());\n"
517       "  } else {\n"
518       "    return nullptr;\n"
519       "  }\n"
520       "}\n"
521       "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
522       "$annotate_accessor$"
523       "  if (has_$oneof_name$()) {\n"
524       "    clear_$oneof_name$();\n"
525       "  }\n"
526       "  if ($name$ != nullptr) {\n"
527       "    set_has_$name$();\n"
528       "    $field_member$.UnsafeSetDefault($name$);\n"
529       "    ::$proto_ns$::Arena* arena = GetArena();\n"
530       "    if (arena != nullptr) {\n"
531       "      arena->Own($name$);\n"
532       "    }\n"
533       "  }\n"
534       "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
535       "}\n");
536 }
537 
GenerateClearingCode(io::Printer * printer) const538 void StringOneofFieldGenerator::GenerateClearingCode(
539     io::Printer* printer) const {
540   Formatter format(printer, variables_);
541   format("$field_member$.Destroy($default_value_tag$, GetArena());\n");
542 }
543 
GenerateMessageClearingCode(io::Printer * printer) const544 void StringOneofFieldGenerator::GenerateMessageClearingCode(
545     io::Printer* printer) const {
546   return GenerateClearingCode(printer);
547 }
548 
GenerateSwappingCode(io::Printer * printer) const549 void StringOneofFieldGenerator::GenerateSwappingCode(
550     io::Printer* printer) const {
551   // Don't print any swapping code. Swapping the union will swap this field.
552 }
553 
GenerateConstructorCode(io::Printer * printer) const554 void StringOneofFieldGenerator::GenerateConstructorCode(
555     io::Printer* printer) const {
556   // Nothing required here.
557 }
558 
559 // ===================================================================
560 
RepeatedStringFieldGenerator(const FieldDescriptor * descriptor,const Options & options)561 RepeatedStringFieldGenerator::RepeatedStringFieldGenerator(
562     const FieldDescriptor* descriptor, const Options& options)
563     : FieldGenerator(descriptor, options) {
564   SetStringVariables(descriptor, &variables_, options);
565 }
566 
~RepeatedStringFieldGenerator()567 RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
568 
GeneratePrivateMembers(io::Printer * printer) const569 void RepeatedStringFieldGenerator::GeneratePrivateMembers(
570     io::Printer* printer) const {
571   Formatter format(printer, variables_);
572   format("::$proto_ns$::RepeatedPtrField<std::string> $name$_;\n");
573 }
574 
GenerateAccessorDeclarations(io::Printer * printer) const575 void RepeatedStringFieldGenerator::GenerateAccessorDeclarations(
576     io::Printer* printer) const {
577   Formatter format(printer, variables_);
578   // See comment above about unknown ctypes.
579   bool unknown_ctype = descriptor_->options().ctype() !=
580                        EffectiveStringCType(descriptor_, options_);
581 
582   if (unknown_ctype) {
583     format.Outdent();
584     format(
585         " private:\n"
586         "  // Hidden due to unknown ctype option.\n");
587     format.Indent();
588   }
589 
590   format(
591       "$deprecated_attr$const std::string& ${1$$name$$}$(int index) const;\n"
592       "$deprecated_attr$std::string* ${1$mutable_$name$$}$(int index);\n"
593       "$deprecated_attr$void ${1$set_$name$$}$(int index, const "
594       "std::string& value);\n"
595       "$deprecated_attr$void ${1$set_$name$$}$(int index, std::string&& "
596       "value);\n"
597       "$deprecated_attr$void ${1$set_$name$$}$(int index, const "
598       "char* value);\n",
599       descriptor_);
600   if (!options_.opensource_runtime) {
601     format(
602         "$deprecated_attr$void ${1$set_$name$$}$(int index, "
603         "StringPiece value);\n",
604         descriptor_);
605   }
606   format(
607       "$deprecated_attr$void ${1$set_$name$$}$("
608       "int index, const $pointer_type$* value, size_t size);\n"
609       "$deprecated_attr$std::string* ${1$add_$name$$}$();\n"
610       "$deprecated_attr$void ${1$add_$name$$}$(const std::string& value);\n"
611       "$deprecated_attr$void ${1$add_$name$$}$(std::string&& value);\n"
612       "$deprecated_attr$void ${1$add_$name$$}$(const char* value);\n",
613       descriptor_);
614   if (!options_.opensource_runtime) {
615     format(
616         "$deprecated_attr$void ${1$add_$name$$}$(StringPiece value);\n",
617         descriptor_);
618   }
619   format(
620       "$deprecated_attr$void ${1$add_$name$$}$(const $pointer_type$* "
621       "value, size_t size)"
622       ";\n"
623       "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField<std::string>& "
624       "${1$$name$$}$() "
625       "const;\n"
626       "$deprecated_attr$::$proto_ns$::RepeatedPtrField<std::string>* "
627       "${1$mutable_$name$$}$()"
628       ";\n"
629       "private:\n"
630       "const std::string& ${1$_internal_$name$$}$(int index) const;\n"
631       "std::string* _internal_add_$name$();\n"
632       "public:\n",
633       descriptor_);
634 
635   if (unknown_ctype) {
636     format.Outdent();
637     format(" public:\n");
638     format.Indent();
639   }
640 }
641 
GenerateInlineAccessorDefinitions(io::Printer * printer) const642 void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
643     io::Printer* printer) const {
644   Formatter format(printer, variables_);
645   format(
646       "inline std::string* $classname$::add_$name$() {\n"
647       "$annotate_accessor$"
648       "  // @@protoc_insertion_point(field_add_mutable:$full_name$)\n"
649       "  return _internal_add_$name$();\n"
650       "}\n");
651   if (options_.safe_boundary_check) {
652     format(
653         "inline const std::string& $classname$::_internal_$name$(int index) "
654         "const {\n"
655         "  return $name$_.InternalCheckedGet(\n"
656         "      index, ::$proto_ns$::internal::GetEmptyStringAlreadyInited());\n"
657         "}\n");
658   } else {
659     format(
660         "inline const std::string& $classname$::_internal_$name$(int index) "
661         "const {\n"
662         "  return $name$_.Get(index);\n"
663         "}\n");
664   }
665   format(
666       "inline const std::string& $classname$::$name$(int index) const {\n"
667       "$annotate_accessor$"
668       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
669       "  return _internal_$name$(index);\n"
670       "}\n"
671       "inline std::string* $classname$::mutable_$name$(int index) {\n"
672       "$annotate_accessor$"
673       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
674       "  return $name$_.Mutable(index);\n"
675       "}\n"
676       "inline void $classname$::set_$name$(int index, const std::string& "
677       "value) "
678       "{\n"
679       "$annotate_accessor$"
680       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
681       "  $name$_.Mutable(index)->assign(value);\n"
682       "}\n"
683       "inline void $classname$::set_$name$(int index, std::string&& value) {\n"
684       "$annotate_accessor$"
685       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
686       "  $name$_.Mutable(index)->assign(std::move(value));\n"
687       "}\n"
688       "inline void $classname$::set_$name$(int index, const char* value) {\n"
689       "$annotate_accessor$"
690       "  $null_check$"
691       "  $name$_.Mutable(index)->assign(value);\n"
692       "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
693       "}\n");
694   if (!options_.opensource_runtime) {
695     format(
696         "inline void "
697         "$classname$::set_$name$(int index, StringPiece value) {\n"
698         "$annotate_accessor$"
699         "  $name$_.Mutable(index)->assign(value.data(), value.size());\n"
700         "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
701         "}\n");
702   }
703   format(
704       "inline void "
705       "$classname$::set_$name$"
706       "(int index, const $pointer_type$* value, size_t size) {\n"
707       "$annotate_accessor$"
708       "  $name$_.Mutable(index)->assign(\n"
709       "    reinterpret_cast<const char*>(value), size);\n"
710       "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
711       "}\n"
712       "inline std::string* $classname$::_internal_add_$name$() {\n"
713       "  return $name$_.Add();\n"
714       "}\n"
715       "inline void $classname$::add_$name$(const std::string& value) {\n"
716       "$annotate_accessor$"
717       "  $name$_.Add()->assign(value);\n"
718       "  // @@protoc_insertion_point(field_add:$full_name$)\n"
719       "}\n"
720       "inline void $classname$::add_$name$(std::string&& value) {\n"
721       "$annotate_accessor$"
722       "  $name$_.Add(std::move(value));\n"
723       "  // @@protoc_insertion_point(field_add:$full_name$)\n"
724       "}\n"
725       "inline void $classname$::add_$name$(const char* value) {\n"
726       "$annotate_accessor$"
727       "  $null_check$"
728       "  $name$_.Add()->assign(value);\n"
729       "  // @@protoc_insertion_point(field_add_char:$full_name$)\n"
730       "}\n");
731   if (!options_.opensource_runtime) {
732     format(
733         "inline void $classname$::add_$name$(StringPiece value) {\n"
734         "$annotate_accessor$"
735         "  $name$_.Add()->assign(value.data(), value.size());\n"
736         "  // @@protoc_insertion_point(field_add_string_piece:$full_name$)\n"
737         "}\n");
738   }
739   format(
740       "inline void "
741       "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
742       "$annotate_accessor$"
743       "  $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
744       "  // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
745       "}\n"
746       "inline const ::$proto_ns$::RepeatedPtrField<std::string>&\n"
747       "$classname$::$name$() const {\n"
748       "$annotate_accessor$"
749       "  // @@protoc_insertion_point(field_list:$full_name$)\n"
750       "  return $name$_;\n"
751       "}\n"
752       "inline ::$proto_ns$::RepeatedPtrField<std::string>*\n"
753       "$classname$::mutable_$name$() {\n"
754       "$annotate_accessor$"
755       "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
756       "  return &$name$_;\n"
757       "}\n");
758 }
759 
GenerateClearingCode(io::Printer * printer) const760 void RepeatedStringFieldGenerator::GenerateClearingCode(
761     io::Printer* printer) const {
762   Formatter format(printer, variables_);
763   format("$name$_.Clear();\n");
764 }
765 
GenerateMergingCode(io::Printer * printer) const766 void RepeatedStringFieldGenerator::GenerateMergingCode(
767     io::Printer* printer) const {
768   Formatter format(printer, variables_);
769   format("$name$_.MergeFrom(from.$name$_);\n");
770 }
771 
GenerateSwappingCode(io::Printer * printer) const772 void RepeatedStringFieldGenerator::GenerateSwappingCode(
773     io::Printer* printer) const {
774   Formatter format(printer, variables_);
775   format("$name$_.InternalSwap(&other->$name$_);\n");
776 }
777 
GenerateConstructorCode(io::Printer * printer) const778 void RepeatedStringFieldGenerator::GenerateConstructorCode(
779     io::Printer* printer) const {
780   // Not needed for repeated fields.
781 }
782 
GenerateCopyConstructorCode(io::Printer * printer) const783 void RepeatedStringFieldGenerator::GenerateCopyConstructorCode(
784     io::Printer* printer) const {
785   Formatter format(printer, variables_);
786   format("$name$_.CopyFrom(from.$name$_);");
787 }
788 
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const789 void RepeatedStringFieldGenerator::GenerateSerializeWithCachedSizesToArray(
790     io::Printer* printer) const {
791   Formatter format(printer, variables_);
792   format(
793       "for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n"
794       "  const auto& s = this->_internal_$name$(i);\n");
795   // format("for (const std::string& s : this->$name$()) {\n");
796   format.Indent();
797   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
798     GenerateUtf8CheckCodeForString(descriptor_, options_, false,
799                                    "s.data(), static_cast<int>(s.length()),\n",
800                                    format);
801   }
802   format.Outdent();
803   format(
804       "  target = stream->Write$declared_type$($number$, s, target);\n"
805       "}\n");
806 }
807 
GenerateByteSize(io::Printer * printer) const808 void RepeatedStringFieldGenerator::GenerateByteSize(
809     io::Printer* printer) const {
810   Formatter format(printer, variables_);
811   format(
812       "total_size += $tag_size$ *\n"
813       "    ::$proto_ns$::internal::FromIntSize($name$_.size());\n"
814       "for (int i = 0, n = $name$_.size(); i < n; i++) {\n"
815       "  total_size += "
816       "::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
817       "    $name$_.Get(i));\n"
818       "}\n");
819 }
820 
821 }  // namespace cpp
822 }  // namespace compiler
823 }  // namespace protobuf
824 }  // namespace google
825