• 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   (*variables)["default_variable"] =
59       descriptor->default_value_string().empty()
60           ? "&::" + (*variables)["proto_ns"] +
61                 "::internal::GetEmptyStringAlreadyInited()"
62           : "&" + QualifiedClassName(descriptor->containing_type(), options) +
63                 "::" + default_variable_string + ".get()";
64   (*variables)["pointer_type"] =
65       descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
66   (*variables)["null_check"] = (*variables)["DCHK"] + "(value != nullptr);\n";
67   // NOTE: Escaped here to unblock proto1->proto2 migration.
68   // TODO(liujisi): Extend this to apply for other conflicting methods.
69   (*variables)["release_name"] =
70       SafeFunctionName(descriptor->containing_type(), descriptor, "release_");
71   (*variables)["full_name"] = descriptor->full_name();
72 
73   if (options.opensource_runtime) {
74     (*variables)["string_piece"] = "::std::string";
75   } else {
76     (*variables)["string_piece"] = "::StringPiece";
77   }
78 
79   (*variables)["lite"] =
80       HasDescriptorMethods(descriptor->file(), options) ? "" : "Lite";
81 }
82 
83 }  // namespace
84 
85 // ===================================================================
86 
StringFieldGenerator(const FieldDescriptor * descriptor,const Options & options)87 StringFieldGenerator::StringFieldGenerator(const FieldDescriptor* descriptor,
88                                            const Options& options)
89     : FieldGenerator(descriptor, options),
90       lite_(!HasDescriptorMethods(descriptor->file(), options)),
91       inlined_(IsStringInlined(descriptor, options)) {
92   SetStringVariables(descriptor, &variables_, options);
93 }
94 
~StringFieldGenerator()95 StringFieldGenerator::~StringFieldGenerator() {}
96 
GeneratePrivateMembers(io::Printer * printer) const97 void StringFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
98   Formatter format(printer, variables_);
99   if (inlined_) {
100     format("::$proto_ns$::internal::InlinedStringField $name$_;\n");
101   } else {
102     // N.B. that we continue to use |ArenaStringPtr| instead of |string*| for
103     // string fields, even when SupportArenas(descriptor_) == false. Why?  The
104     // simple answer is to avoid unmaintainable complexity. The reflection code
105     // assumes ArenaStringPtrs. These are *almost* in-memory-compatible with
106     // string*, except for the pointer tags and related ownership semantics. We
107     // could modify the runtime code to use string* for the
108     // not-supporting-arenas case, but this would require a way to detect which
109     // type of class was generated (adding overhead and complexity to
110     // GeneratedMessageReflection) and littering the runtime code paths with
111     // conditionals. It's simpler to stick with this but use lightweight
112     // accessors that assume arena == NULL.  There should be very little
113     // overhead anyway because it's just a tagged pointer in-memory.
114     format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n");
115   }
116 }
117 
GenerateStaticMembers(io::Printer * printer) const118 void StringFieldGenerator::GenerateStaticMembers(io::Printer* printer) const {
119   Formatter format(printer, variables_);
120   if (!descriptor_->default_value_string().empty()) {
121     // We make the default instance public, so it can be initialized by
122     // non-friend code.
123     format(
124         "public:\n"
125         "static ::$proto_ns$::internal::ExplicitlyConstructed<std::string>"
126         " $default_variable_name$;\n"
127         "private:\n");
128   }
129 }
130 
GenerateAccessorDeclarations(io::Printer * printer) const131 void StringFieldGenerator::GenerateAccessorDeclarations(
132     io::Printer* printer) const {
133   Formatter format(printer, variables_);
134   // If we're using StringFieldGenerator for a field with a ctype, it's
135   // because that ctype isn't actually implemented.  In particular, this is
136   // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
137   // We aren't releasing Cord because it has too many Google-specific
138   // dependencies and we aren't releasing StringPiece because it's hardly
139   // useful outside of Google and because it would get confusing to have
140   // multiple instances of the StringPiece class in different libraries (PCRE
141   // already includes it for their C++ bindings, which came from Google).
142   //
143   // In any case, we make all the accessors private while still actually
144   // using a string to represent the field internally.  This way, we can
145   // guarantee that if we do ever implement the ctype, it won't break any
146   // existing users who might be -- for whatever reason -- already using .proto
147   // files that applied the ctype.  The field can still be accessed via the
148   // reflection interface since the reflection interface is independent of
149   // the string's underlying representation.
150 
151   bool unknown_ctype = descriptor_->options().ctype() !=
152                        EffectiveStringCType(descriptor_, options_);
153 
154   if (unknown_ctype) {
155     format.Outdent();
156     format(
157         " private:\n"
158         "  // Hidden due to unknown ctype option.\n");
159     format.Indent();
160   }
161 
162   format(
163       "$deprecated_attr$const std::string& ${1$$name$$}$() const;\n"
164       "$deprecated_attr$void ${1$set_$name$$}$(const std::string& value);\n"
165       "$deprecated_attr$void ${1$set_$name$$}$(std::string&& value);\n"
166       "$deprecated_attr$void ${1$set_$name$$}$(const char* value);\n",
167       descriptor_);
168   if (!options_.opensource_runtime) {
169     format(
170         "$deprecated_attr$void ${1$set_$name$$}$(::StringPiece value);\n",
171         descriptor_);
172   }
173   format(
174       "$deprecated_attr$void ${1$set_$name$$}$(const $pointer_type$* "
175       "value, size_t size)"
176       ";\n"
177       "$deprecated_attr$std::string* ${1$mutable_$name$$}$();\n"
178       "$deprecated_attr$std::string* ${1$$release_name$$}$();\n"
179       "$deprecated_attr$void ${1$set_allocated_$name$$}$(std::string* "
180       "$name$);\n",
181       descriptor_);
182   format(
183       "private:\n"
184       "const std::string& _internal_$name$() const;\n"
185       "void _internal_set_$name$(const std::string& value);\n"
186       "std::string* _internal_mutable_$name$();\n"
187       "public:\n");
188 
189   if (unknown_ctype) {
190     format.Outdent();
191     format(" public:\n");
192     format.Indent();
193   }
194 }
195 
GenerateInlineAccessorDefinitions(io::Printer * printer) const196 void StringFieldGenerator::GenerateInlineAccessorDefinitions(
197     io::Printer* printer) const {
198   Formatter format(printer, variables_);
199   format(
200       "inline const std::string& $classname$::$name$() const {\n"
201       "$annotate_accessor$"
202       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
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   if (SupportsArenas(descriptor_)) {
216     format(
217         "inline const std::string& $classname$::_internal_$name$() const {\n"
218         "  return $name$_.Get();\n"
219         "}\n"
220         "inline void $classname$::_internal_set_$name$(const std::string& "
221         "value) {\n"
222         "  $set_hasbit$\n"
223         "  $name$_.Set$lite$($default_variable$, value, GetArena());\n"
224         "}\n"
225         "inline void $classname$::set_$name$(std::string&& value) {\n"
226         "$annotate_accessor$"
227         "  $set_hasbit$\n"
228         "  $name$_.Set$lite$(\n"
229         "    $default_variable$, ::std::move(value), GetArena());\n"
230         "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
231         "}\n"
232         "inline void $classname$::set_$name$(const char* value) {\n"
233         "$annotate_accessor$"
234         "  $null_check$"
235         "  $set_hasbit$\n"
236         "  $name$_.Set$lite$($default_variable$, $string_piece$(value),\n"
237         "              GetArena());\n"
238         "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
239         "}\n");
240     if (!options_.opensource_runtime) {
241       format(
242           "inline void $classname$::set_$name$(::StringPiece value) {\n"
243           "$annotate_accessor$"
244           "  $set_hasbit$\n"
245           "  $name$_.Set$lite$($default_variable$, value,GetArena());\n"
246           "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
247           "}\n");
248     }
249     format(
250         "inline "
251         "void $classname$::set_$name$(const $pointer_type$* value,\n"
252         "    size_t size) {\n"
253         "$annotate_accessor$"
254         "  $set_hasbit$\n"
255         "  $name$_.Set$lite$($default_variable$, $string_piece$(\n"
256         "      reinterpret_cast<const char*>(value), size), GetArena());\n"
257         "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
258         "}\n"
259         "inline std::string* $classname$::_internal_mutable_$name$() {\n"
260         "  $set_hasbit$\n"
261         "  return $name$_.Mutable($default_variable$, GetArena());\n"
262         "}\n"
263         "inline std::string* $classname$::$release_name$() {\n"
264         "$annotate_accessor$"
265         "  // @@protoc_insertion_point(field_release:$full_name$)\n");
266 
267     if (HasHasbit(descriptor_)) {
268       format(
269           "  if (!_internal_has_$name$()) {\n"
270           "    return nullptr;\n"
271           "  }\n"
272           "  $clear_hasbit$\n"
273           "  return $name$_.ReleaseNonDefault("
274           "$default_variable$, GetArena());\n");
275     } else {
276       format(
277           "  return $name$_.Release($default_variable$, GetArena());\n");
278     }
279 
280     format(
281         "}\n"
282         "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
283         "$annotate_accessor$"
284         "  if ($name$ != nullptr) {\n"
285         "    $set_hasbit$\n"
286         "  } else {\n"
287         "    $clear_hasbit$\n"
288         "  }\n"
289         "  $name$_.SetAllocated($default_variable$, $name$,\n"
290         "      GetArena());\n"
291         "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
292         "}\n");
293   } else {
294     // No-arena case.
295     format(
296         "inline const std::string& $classname$::_internal_$name$() const {\n"
297         "  return $name$_.GetNoArena();\n"
298         "}\n"
299         "inline void $classname$::_internal_set_$name$(const std::string& "
300         "value) {\n"
301         "  $set_hasbit$\n"
302         "  $name$_.SetNoArena($default_variable$, value);\n"
303         "}\n"
304         "inline void $classname$::set_$name$(std::string&& value) {\n"
305         "$annotate_accessor$"
306         "  $set_hasbit$\n"
307         "  $name$_.SetNoArena(\n"
308         "    $default_variable$, ::std::move(value));\n"
309         "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
310         "}\n"
311         "inline void $classname$::set_$name$(const char* value) {\n"
312         "$annotate_accessor$"
313         "  $null_check$"
314         "  $set_hasbit$\n"
315         "  $name$_.SetNoArena($default_variable$, $string_piece$(value));\n"
316         "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
317         "}\n");
318     if (!options_.opensource_runtime) {
319       format(
320           "inline void $classname$::set_$name$(::StringPiece value) {\n"
321           "$annotate_accessor$"
322           "  $set_hasbit$\n"
323           "  $name$_.SetNoArena($default_variable$, value);\n"
324           "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
325           "}\n");
326     }
327     format(
328         "inline "
329         "void $classname$::set_$name$(const $pointer_type$* value, "
330         "size_t size) {\n"
331         "$annotate_accessor$"
332         "  $set_hasbit$\n"
333         "  $name$_.SetNoArena($default_variable$,\n"
334         "      $string_piece$(reinterpret_cast<const char*>(value), size));\n"
335         "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
336         "}\n"
337         "inline std::string* $classname$::_internal_mutable_$name$() {\n"
338         "  $set_hasbit$\n"
339         "  return $name$_.MutableNoArena($default_variable$);\n"
340         "}\n"
341         "inline std::string* $classname$::$release_name$() {\n"
342         "$annotate_accessor$"
343         "  // @@protoc_insertion_point(field_release:$full_name$)\n");
344 
345     if (HasHasbit(descriptor_)) {
346       format(
347           "  if (!_internal_has_$name$()) {\n"
348           "    return nullptr;\n"
349           "  }\n"
350           "  $clear_hasbit$\n"
351           "  return $name$_.ReleaseNonDefaultNoArena($default_variable$);\n");
352     } else {
353       format(
354           "  $clear_hasbit$\n"
355           "  return $name$_.ReleaseNoArena($default_variable$);\n");
356     }
357 
358     format(
359         "}\n"
360         "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
361         "$annotate_accessor$"
362         "  if ($name$ != nullptr) {\n"
363         "    $set_hasbit$\n"
364         "  } else {\n"
365         "    $clear_hasbit$\n"
366         "  }\n"
367         "  $name$_.SetAllocatedNoArena($default_variable$, $name$);\n"
368         "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
369         "}\n");
370   }
371 }
372 
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const373 void StringFieldGenerator::GenerateNonInlineAccessorDefinitions(
374     io::Printer* printer) const {
375   Formatter format(printer, variables_);
376   if (!descriptor_->default_value_string().empty()) {
377     // Initialized in GenerateDefaultInstanceAllocator.
378     format(
379         "::$proto_ns$::internal::ExplicitlyConstructed<std::string> "
380         "$classname$::$default_variable_name$;\n");
381   }
382 }
383 
GenerateClearingCode(io::Printer * printer) const384 void StringFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
385   Formatter format(printer, variables_);
386   // Two-dimension specialization here: supporting arenas or not, and default
387   // value is the empty string or not. Complexity here ensures the minimal
388   // number of branches / amount of extraneous code at runtime (given that the
389   // below methods are inlined one-liners)!
390   if (SupportsArenas(descriptor_)) {
391     if (descriptor_->default_value_string().empty()) {
392       format("$name$_.ClearToEmpty($default_variable$, GetArena());\n");
393     } else {
394       format("$name$_.ClearToDefault($default_variable$, GetArena());\n");
395     }
396   } else {
397     if (descriptor_->default_value_string().empty()) {
398       format("$name$_.ClearToEmptyNoArena($default_variable$);\n");
399     } else {
400       format("$name$_.ClearToDefaultNoArena($default_variable$);\n");
401     }
402   }
403 }
404 
GenerateMessageClearingCode(io::Printer * printer) const405 void StringFieldGenerator::GenerateMessageClearingCode(
406     io::Printer* printer) const {
407   Formatter format(printer, variables_);
408   // Two-dimension specialization here: supporting arenas, field presence, or
409   // not, and default value is the empty string or not. Complexity here ensures
410   // the minimal number of branches / amount of extraneous code at runtime
411   // (given that the below methods are inlined one-liners)!
412 
413   // If we have a hasbit, then the Clear() method of the protocol buffer
414   // will have checked that this field is set.  If so, we can avoid redundant
415   // checks against default_variable.
416   const bool must_be_present = HasHasbit(descriptor_);
417 
418   if (inlined_ && must_be_present) {
419     // Calling mutable_$name$() gives us a string reference and sets the has bit
420     // for $name$ (in proto2).  We may get here when the string field is inlined
421     // but the string's contents have not been changed by the user, so we cannot
422     // make an assertion about the contents of the string and could never make
423     // an assertion about the string instance.
424     //
425     // For non-inlined strings, we distinguish from non-default by comparing
426     // instances, rather than contents.
427     format("$DCHK$(!$name$_.IsDefault($default_variable$));\n");
428   }
429 
430   if (SupportsArenas(descriptor_)) {
431     if (descriptor_->default_value_string().empty()) {
432       if (must_be_present) {
433         format("$name$_.ClearNonDefaultToEmpty();\n");
434       } else {
435         format("$name$_.ClearToEmpty($default_variable$, GetArena());\n");
436       }
437     } else {
438       // Clear to a non-empty default is more involved, as we try to use the
439       // Arena if one is present and may need to reallocate the string.
440       format("$name$_.ClearToDefault($default_variable$, GetArena());\n");
441     }
442   } else if (must_be_present) {
443     // When Arenas are disabled and field presence has been checked, we can
444     // safely treat the ArenaStringPtr as a string*.
445     if (descriptor_->default_value_string().empty()) {
446       format("$name$_.ClearNonDefaultToEmptyNoArena();\n");
447     } else {
448       format("$name$_.UnsafeMutablePointer()->assign(*$default_variable$);\n");
449     }
450   } else {
451     if (descriptor_->default_value_string().empty()) {
452       format("$name$_.ClearToEmptyNoArena($default_variable$);\n");
453     } else {
454       format("$name$_.ClearToDefaultNoArena($default_variable$);\n");
455     }
456   }
457 }
458 
GenerateMergingCode(io::Printer * printer) const459 void StringFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
460   Formatter format(printer, variables_);
461   if (SupportsArenas(descriptor_) || descriptor_->real_containing_oneof()) {
462     // TODO(gpike): improve this
463     format("_internal_set_$name$(from._internal_$name$());\n");
464   } else {
465     format(
466         "$set_hasbit$\n"
467         "$name$_.AssignWithDefault($default_variable$, from.$name$_);\n");
468   }
469 }
470 
GenerateSwappingCode(io::Printer * printer) const471 void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
472   Formatter format(printer, variables_);
473   if (inlined_) {
474     format("$name$_.Swap(&other->$name$_);\n");
475   } else {
476     format("$name$_.Swap(&other->$name$_, $default_variable$, GetArena());\n");
477   }
478 }
479 
GenerateConstructorCode(io::Printer * printer) const480 void StringFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
481   Formatter format(printer, variables_);
482   // TODO(ckennelly): Construct non-empty strings as part of the initializer
483   // list.
484   if (inlined_ && descriptor_->default_value_string().empty()) {
485     // Automatic initialization will construct the string.
486     return;
487   }
488 
489   format("$name$_.UnsafeSetDefault($default_variable$);\n");
490 }
491 
GenerateCopyConstructorCode(io::Printer * printer) const492 void StringFieldGenerator::GenerateCopyConstructorCode(
493     io::Printer* printer) const {
494   Formatter format(printer, variables_);
495   GenerateConstructorCode(printer);
496 
497   if (HasHasbit(descriptor_)) {
498     format("if (from._internal_has_$name$()) {\n");
499   } else {
500     format("if (!from._internal_$name$().empty()) {\n");
501   }
502 
503   format.Indent();
504 
505   if (SupportsArenas(descriptor_) || descriptor_->real_containing_oneof()) {
506     // TODO(gpike): improve this
507     format(
508         "$name$_.Set$lite$($default_variable$, from._internal_$name$(),\n"
509         "  GetArena());\n");
510   } else {
511     format("$name$_.AssignWithDefault($default_variable$, from.$name$_);\n");
512   }
513 
514   format.Outdent();
515   format("}\n");
516 }
517 
GenerateDestructorCode(io::Printer * printer) const518 void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
519   Formatter format(printer, variables_);
520   if (inlined_) {
521     // The destructor is automatically invoked.
522     return;
523   }
524 
525   format("$name$_.DestroyNoArena($default_variable$);\n");
526 }
527 
GenerateArenaDestructorCode(io::Printer * printer) const528 bool StringFieldGenerator::GenerateArenaDestructorCode(
529     io::Printer* printer) const {
530   Formatter format(printer, variables_);
531   if (!inlined_) {
532     return false;
533   }
534 
535   format("_this->$name$_.DestroyNoArena($default_variable$);\n");
536   return true;
537 }
538 
GenerateDefaultInstanceAllocator(io::Printer * printer) const539 void StringFieldGenerator::GenerateDefaultInstanceAllocator(
540     io::Printer* printer) const {
541   Formatter format(printer, variables_);
542   if (!descriptor_->default_value_string().empty()) {
543     format(
544         "$ns$::$classname$::$default_variable_name$.DefaultConstruct();\n"
545         "*$ns$::$classname$::$default_variable_name$.get_mutable() = "
546         "std::string($default$, $default_length$);\n"
547         "::$proto_ns$::internal::OnShutdownDestroyString(\n"
548         "    $ns$::$classname$::$default_variable_name$.get_mutable());\n");
549   }
550 }
551 
MergeFromCodedStreamNeedsArena() const552 bool StringFieldGenerator::MergeFromCodedStreamNeedsArena() const {
553   return !lite_ && !inlined_ && !options_.opensource_runtime;
554 }
555 
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const556 void StringFieldGenerator::GenerateSerializeWithCachedSizesToArray(
557     io::Printer* printer) const {
558   Formatter format(printer, variables_);
559   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
560     GenerateUtf8CheckCodeForString(
561         descriptor_, options_, false,
562         "this->_internal_$name$().data(), "
563         "static_cast<int>(this->_internal_$name$().length()),\n",
564         format);
565   }
566   format(
567       "target = stream->Write$declared_type$MaybeAliased(\n"
568       "    $number$, this->_internal_$name$(), target);\n");
569 }
570 
GenerateByteSize(io::Printer * printer) const571 void StringFieldGenerator::GenerateByteSize(io::Printer* printer) const {
572   Formatter format(printer, variables_);
573   format(
574       "total_size += $tag_size$ +\n"
575       "  ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
576       "    this->_internal_$name$());\n");
577 }
578 
CalculateFieldTag() const579 uint32 StringFieldGenerator::CalculateFieldTag() const {
580   return inlined_ ? 1 : 0;
581 }
582 
583 // ===================================================================
584 
StringOneofFieldGenerator(const FieldDescriptor * descriptor,const Options & options)585 StringOneofFieldGenerator::StringOneofFieldGenerator(
586     const FieldDescriptor* descriptor, const Options& options)
587     : StringFieldGenerator(descriptor, options) {
588   inlined_ = false;
589 
590   SetCommonOneofFieldVariables(descriptor, &variables_);
591   variables_["field_name"] = UnderscoresToCamelCase(descriptor->name(), true);
592   variables_["oneof_index"] =
593       StrCat(descriptor->containing_oneof()->index());
594 }
595 
~StringOneofFieldGenerator()596 StringOneofFieldGenerator::~StringOneofFieldGenerator() {}
597 
GenerateInlineAccessorDefinitions(io::Printer * printer) const598 void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
599     io::Printer* printer) const {
600   Formatter format(printer, variables_);
601   format(
602       "inline const std::string& $classname$::$name$() const {\n"
603       "$annotate_accessor$"
604       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
605       "  return _internal_$name$();\n"
606       "}\n"
607       "inline void $classname$::set_$name$(const std::string& value) {\n"
608       "$annotate_accessor$"
609       "  _internal_set_$name$(value);\n"
610       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
611       "}\n"
612       "inline std::string* $classname$::mutable_$name$() {\n"
613       "$annotate_accessor$"
614       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
615       "  return _internal_mutable_$name$();\n"
616       "}\n");
617   if (SupportsArenas(descriptor_)) {
618     format(
619         "inline const std::string& $classname$::_internal_$name$() const {\n"
620         "  if (_internal_has_$name$()) {\n"
621         "    return $field_member$.Get();\n"
622         "  }\n"
623         "  return *$default_variable$;\n"
624         "}\n"
625         "inline void $classname$::_internal_set_$name$(const std::string& "
626         "value) {\n"
627         "  if (!_internal_has_$name$()) {\n"
628         "    clear_$oneof_name$();\n"
629         "    set_has_$name$();\n"
630         "    $field_member$.UnsafeSetDefault($default_variable$);\n"
631         "  }\n"
632         "  $field_member$.Set$lite$($default_variable$, value, GetArena());\n"
633         "}\n"
634         "inline void $classname$::set_$name$(std::string&& value) {\n"
635         "$annotate_accessor$"
636         "  // @@protoc_insertion_point(field_set:$full_name$)\n"
637         "  if (!_internal_has_$name$()) {\n"
638         "    clear_$oneof_name$();\n"
639         "    set_has_$name$();\n"
640         "    $field_member$.UnsafeSetDefault($default_variable$);\n"
641         "  }\n"
642         "  $field_member$.Set$lite$(\n"
643         "    $default_variable$, ::std::move(value), GetArena());\n"
644         "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
645         "}\n"
646         "inline void $classname$::set_$name$(const char* value) {\n"
647         "$annotate_accessor$"
648         "  $null_check$"
649         "  if (!_internal_has_$name$()) {\n"
650         "    clear_$oneof_name$();\n"
651         "    set_has_$name$();\n"
652         "    $field_member$.UnsafeSetDefault($default_variable$);\n"
653         "  }\n"
654         "  $field_member$.Set$lite$($default_variable$,\n"
655         "      $string_piece$(value), GetArena());\n"
656         "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
657         "}\n");
658     if (!options_.opensource_runtime) {
659       format(
660           "inline void $classname$::set_$name$(::StringPiece value) {\n"
661           "$annotate_accessor$"
662           "  if (!_internal_has_$name$()) {\n"
663           "    clear_$oneof_name$();\n"
664           "    set_has_$name$();\n"
665           "    $field_member$.UnsafeSetDefault($default_variable$);\n"
666           "  }\n"
667           "  $field_member$.Set$lite$($default_variable$, value,\n"
668           "      GetArena());\n"
669           "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
670           "}\n");
671     }
672     format(
673         "inline "
674         "void $classname$::set_$name$(const $pointer_type$* value,\n"
675         "                             size_t size) {\n"
676         "$annotate_accessor$"
677         "  if (!_internal_has_$name$()) {\n"
678         "    clear_$oneof_name$();\n"
679         "    set_has_$name$();\n"
680         "    $field_member$.UnsafeSetDefault($default_variable$);\n"
681         "  }\n"
682         "  $field_member$.Set$lite$(\n"
683         "      $default_variable$, $string_piece$(\n"
684         "      reinterpret_cast<const char*>(value), size),\n"
685         "      GetArena());\n"
686         "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
687         "}\n"
688         "inline std::string* $classname$::_internal_mutable_$name$() {\n"
689         "  if (!_internal_has_$name$()) {\n"
690         "    clear_$oneof_name$();\n"
691         "    set_has_$name$();\n"
692         "    $field_member$.UnsafeSetDefault($default_variable$);\n"
693         "  }\n"
694         "  return $field_member$.Mutable($default_variable$, GetArena());\n"
695         "}\n"
696         "inline std::string* $classname$::$release_name$() {\n"
697         "$annotate_accessor$"
698         "  // @@protoc_insertion_point(field_release:$full_name$)\n"
699         "  if (_internal_has_$name$()) {\n"
700         "    clear_has_$oneof_name$();\n"
701         "    return $field_member$.Release($default_variable$, GetArena());\n"
702         "  } else {\n"
703         "    return nullptr;\n"
704         "  }\n"
705         "}\n"
706         "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
707         "$annotate_accessor$"
708         "  if (has_$oneof_name$()) {\n"
709         "    clear_$oneof_name$();\n"
710         "  }\n"
711         "  if ($name$ != nullptr) {\n"
712         "    set_has_$name$();\n"
713         "    $field_member$.UnsafeSetDefault($name$);\n"
714         "    ::$proto_ns$::Arena* arena = GetArena();\n"
715         "    if (arena != nullptr) {\n"
716         "      arena->Own($name$);\n"
717         "    }\n"
718         "  }\n"
719         "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
720         "}\n");
721   } else {
722     // No-arena case.
723     format(
724         "inline const std::string& $classname$::_internal_$name$() const {\n"
725         "  if (_internal_has_$name$()) {\n"
726         "    return $field_member$.GetNoArena();\n"
727         "  }\n"
728         "  return *$default_variable$;\n"
729         "}\n"
730         "inline void $classname$::_internal_set_$name$(const std::string& "
731         "value) {\n"
732         "  if (!_internal_has_$name$()) {\n"
733         "    clear_$oneof_name$();\n"
734         "    set_has_$name$();\n"
735         "    $field_member$.UnsafeSetDefault($default_variable$);\n"
736         "  }\n"
737         "  $field_member$.SetNoArena($default_variable$, value);\n"
738         "}\n"
739         "inline void $classname$::set_$name$(std::string&& value) {\n"
740         "$annotate_accessor$"
741         "  // @@protoc_insertion_point(field_set:$full_name$)\n"
742         "  if (!_internal_has_$name$()) {\n"
743         "    clear_$oneof_name$();\n"
744         "    set_has_$name$();\n"
745         "    $field_member$.UnsafeSetDefault($default_variable$);\n"
746         "  }\n"
747         "  $field_member$.SetNoArena($default_variable$, ::std::move(value));\n"
748         "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
749         "}\n"
750         "inline void $classname$::set_$name$(const char* value) {\n"
751         "$annotate_accessor$"
752         "  $null_check$"
753         "  if (!_internal_has_$name$()) {\n"
754         "    clear_$oneof_name$();\n"
755         "    set_has_$name$();\n"
756         "    $field_member$.UnsafeSetDefault($default_variable$);\n"
757         "  }\n"
758         "  $field_member$.SetNoArena($default_variable$,\n"
759         "      $string_piece$(value));\n"
760         "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
761         "}\n");
762     if (!options_.opensource_runtime) {
763       format(
764           "inline void $classname$::set_$name$(::StringPiece value) {\n"
765           "$annotate_accessor$"
766           "  if (!_internal_has_$name$()) {\n"
767           "    clear_$oneof_name$();\n"
768           "    set_has_$name$();\n"
769           "    $field_member$.UnsafeSetDefault($default_variable$);\n"
770           "  }\n"
771           "  $field_member$.SetNoArena($default_variable$, value);\n"
772           "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
773           "}\n");
774     }
775     format(
776         "inline "
777         "void $classname$::set_$name$(const $pointer_type$* value, size_t "
778         "size) {\n"
779         "$annotate_accessor$"
780         "  if (!_internal_has_$name$()) {\n"
781         "    clear_$oneof_name$();\n"
782         "    set_has_$name$();\n"
783         "    $field_member$.UnsafeSetDefault($default_variable$);\n"
784         "  }\n"
785         "  $field_member$.SetNoArena($default_variable$, $string_piece$(\n"
786         "      reinterpret_cast<const char*>(value), size));\n"
787         "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
788         "}\n"
789         "inline std::string* $classname$::_internal_mutable_$name$() {\n"
790         "  if (!_internal_has_$name$()) {\n"
791         "    clear_$oneof_name$();\n"
792         "    set_has_$name$();\n"
793         "    $field_member$.UnsafeSetDefault($default_variable$);\n"
794         "  }\n"
795         "  return $field_member$.MutableNoArena($default_variable$);\n"
796         "}\n"
797         "inline std::string* $classname$::$release_name$() {\n"
798         "$annotate_accessor$"
799         "  // @@protoc_insertion_point(field_release:$full_name$)\n"
800         "  if (_internal_has_$name$()) {\n"
801         "    clear_has_$oneof_name$();\n"
802         "    return $field_member$.ReleaseNoArena($default_variable$);\n"
803         "  } else {\n"
804         "    return nullptr;\n"
805         "  }\n"
806         "}\n"
807         "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
808         "$annotate_accessor$"
809         "  if (has_$oneof_name$()) {\n"
810         "    clear_$oneof_name$();\n"
811         "  }\n"
812         "  if ($name$ != nullptr) {\n"
813         "    set_has_$name$();\n"
814         "    $field_member$.UnsafeSetDefault($name$);\n"
815         "  }\n"
816         "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
817         "}\n");
818   }
819 }
820 
GenerateClearingCode(io::Printer * printer) const821 void StringOneofFieldGenerator::GenerateClearingCode(
822     io::Printer* printer) const {
823   Formatter format(printer, variables_);
824   if (SupportsArenas(descriptor_)) {
825     format("$field_member$.Destroy($default_variable$, GetArena());\n");
826   } else {
827     format("$field_member$.DestroyNoArena($default_variable$);\n");
828   }
829 }
830 
GenerateMessageClearingCode(io::Printer * printer) const831 void StringOneofFieldGenerator::GenerateMessageClearingCode(
832     io::Printer* printer) const {
833   return GenerateClearingCode(printer);
834 }
835 
GenerateSwappingCode(io::Printer * printer) const836 void StringOneofFieldGenerator::GenerateSwappingCode(
837     io::Printer* printer) const {
838   // Don't print any swapping code. Swapping the union will swap this field.
839 }
840 
GenerateConstructorCode(io::Printer * printer) const841 void StringOneofFieldGenerator::GenerateConstructorCode(
842     io::Printer* printer) const {
843   Formatter format(printer, variables_);
844   format(
845       "$ns$::_$classname$_default_instance_.$name$_.UnsafeSetDefault(\n"
846       "    $default_variable$);\n");
847 }
848 
849 // ===================================================================
850 
RepeatedStringFieldGenerator(const FieldDescriptor * descriptor,const Options & options)851 RepeatedStringFieldGenerator::RepeatedStringFieldGenerator(
852     const FieldDescriptor* descriptor, const Options& options)
853     : FieldGenerator(descriptor, options) {
854   SetStringVariables(descriptor, &variables_, options);
855 }
856 
~RepeatedStringFieldGenerator()857 RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
858 
GeneratePrivateMembers(io::Printer * printer) const859 void RepeatedStringFieldGenerator::GeneratePrivateMembers(
860     io::Printer* printer) const {
861   Formatter format(printer, variables_);
862   format("::$proto_ns$::RepeatedPtrField<std::string> $name$_;\n");
863 }
864 
GenerateAccessorDeclarations(io::Printer * printer) const865 void RepeatedStringFieldGenerator::GenerateAccessorDeclarations(
866     io::Printer* printer) const {
867   Formatter format(printer, variables_);
868   // See comment above about unknown ctypes.
869   bool unknown_ctype = descriptor_->options().ctype() !=
870                        EffectiveStringCType(descriptor_, options_);
871 
872   if (unknown_ctype) {
873     format.Outdent();
874     format(
875         " private:\n"
876         "  // Hidden due to unknown ctype option.\n");
877     format.Indent();
878   }
879 
880   format(
881       "$deprecated_attr$const std::string& ${1$$name$$}$(int index) const;\n"
882       "$deprecated_attr$std::string* ${1$mutable_$name$$}$(int index);\n"
883       "$deprecated_attr$void ${1$set_$name$$}$(int index, const "
884       "std::string& value);\n"
885       "$deprecated_attr$void ${1$set_$name$$}$(int index, std::string&& "
886       "value);\n"
887       "$deprecated_attr$void ${1$set_$name$$}$(int index, const "
888       "char* value);\n",
889       descriptor_);
890   if (!options_.opensource_runtime) {
891     format(
892         "$deprecated_attr$void ${1$set_$name$$}$(int index, "
893         "StringPiece value);\n",
894         descriptor_);
895   }
896   format(
897       "$deprecated_attr$void ${1$set_$name$$}$("
898       "int index, const $pointer_type$* value, size_t size);\n"
899       "$deprecated_attr$std::string* ${1$add_$name$$}$();\n"
900       "$deprecated_attr$void ${1$add_$name$$}$(const std::string& value);\n"
901       "$deprecated_attr$void ${1$add_$name$$}$(std::string&& value);\n"
902       "$deprecated_attr$void ${1$add_$name$$}$(const char* value);\n",
903       descriptor_);
904   if (!options_.opensource_runtime) {
905     format(
906         "$deprecated_attr$void ${1$add_$name$$}$(StringPiece value);\n",
907         descriptor_);
908   }
909   format(
910       "$deprecated_attr$void ${1$add_$name$$}$(const $pointer_type$* "
911       "value, size_t size)"
912       ";\n"
913       "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField<std::string>& "
914       "${1$$name$$}$() "
915       "const;\n"
916       "$deprecated_attr$::$proto_ns$::RepeatedPtrField<std::string>* "
917       "${1$mutable_$name$$}$()"
918       ";\n"
919       "private:\n"
920       "const std::string& ${1$_internal_$name$$}$(int index) const;\n"
921       "std::string* _internal_add_$name$();\n"
922       "public:\n",
923       descriptor_);
924 
925   if (unknown_ctype) {
926     format.Outdent();
927     format(" public:\n");
928     format.Indent();
929   }
930 }
931 
GenerateInlineAccessorDefinitions(io::Printer * printer) const932 void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
933     io::Printer* printer) const {
934   Formatter format(printer, variables_);
935   format(
936       "inline std::string* $classname$::add_$name$() {\n"
937       "$annotate_accessor$"
938       "  // @@protoc_insertion_point(field_add_mutable:$full_name$)\n"
939       "  return _internal_add_$name$();\n"
940       "}\n");
941   if (options_.safe_boundary_check) {
942     format(
943         "inline const std::string& $classname$::_internal_$name$(int index) "
944         "const {\n"
945         "  return $name$_.InternalCheckedGet(\n"
946         "      index, ::$proto_ns$::internal::GetEmptyStringAlreadyInited());\n"
947         "}\n");
948   } else {
949     format(
950         "inline const std::string& $classname$::_internal_$name$(int index) "
951         "const {\n"
952         "  return $name$_.Get(index);\n"
953         "}\n");
954   }
955   format(
956       "inline const std::string& $classname$::$name$(int index) const {\n"
957       "$annotate_accessor$"
958       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
959       "  return _internal_$name$(index);\n"
960       "}\n"
961       "inline std::string* $classname$::mutable_$name$(int index) {\n"
962       "$annotate_accessor$"
963       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
964       "  return $name$_.Mutable(index);\n"
965       "}\n"
966       "inline void $classname$::set_$name$(int index, const std::string& "
967       "value) "
968       "{\n"
969       "$annotate_accessor$"
970       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
971       "  $name$_.Mutable(index)->assign(value);\n"
972       "}\n"
973       "inline void $classname$::set_$name$(int index, std::string&& value) {\n"
974       "$annotate_accessor$"
975       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
976       "  $name$_.Mutable(index)->assign(std::move(value));\n"
977       "}\n"
978       "inline void $classname$::set_$name$(int index, const char* value) {\n"
979       "$annotate_accessor$"
980       "  $null_check$"
981       "  $name$_.Mutable(index)->assign(value);\n"
982       "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
983       "}\n");
984   if (!options_.opensource_runtime) {
985     format(
986         "inline void "
987         "$classname$::set_$name$(int index, StringPiece value) {\n"
988         "$annotate_accessor$"
989         "  $name$_.Mutable(index)->assign(value.data(), value.size());\n"
990         "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
991         "}\n");
992   }
993   format(
994       "inline void "
995       "$classname$::set_$name$"
996       "(int index, const $pointer_type$* value, size_t size) {\n"
997       "$annotate_accessor$"
998       "  $name$_.Mutable(index)->assign(\n"
999       "    reinterpret_cast<const char*>(value), size);\n"
1000       "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
1001       "}\n"
1002       "inline std::string* $classname$::_internal_add_$name$() {\n"
1003       "  return $name$_.Add();\n"
1004       "}\n"
1005       "inline void $classname$::add_$name$(const std::string& value) {\n"
1006       "$annotate_accessor$"
1007       "  $name$_.Add()->assign(value);\n"
1008       "  // @@protoc_insertion_point(field_add:$full_name$)\n"
1009       "}\n"
1010       "inline void $classname$::add_$name$(std::string&& value) {\n"
1011       "$annotate_accessor$"
1012       "  $name$_.Add(std::move(value));\n"
1013       "  // @@protoc_insertion_point(field_add:$full_name$)\n"
1014       "}\n"
1015       "inline void $classname$::add_$name$(const char* value) {\n"
1016       "$annotate_accessor$"
1017       "  $null_check$"
1018       "  $name$_.Add()->assign(value);\n"
1019       "  // @@protoc_insertion_point(field_add_char:$full_name$)\n"
1020       "}\n");
1021   if (!options_.opensource_runtime) {
1022     format(
1023         "inline void $classname$::add_$name$(StringPiece value) {\n"
1024         "$annotate_accessor$"
1025         "  $name$_.Add()->assign(value.data(), value.size());\n"
1026         "  // @@protoc_insertion_point(field_add_string_piece:$full_name$)\n"
1027         "}\n");
1028   }
1029   format(
1030       "inline void "
1031       "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
1032       "$annotate_accessor$"
1033       "  $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
1034       "  // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
1035       "}\n"
1036       "inline const ::$proto_ns$::RepeatedPtrField<std::string>&\n"
1037       "$classname$::$name$() const {\n"
1038       "$annotate_accessor$"
1039       "  // @@protoc_insertion_point(field_list:$full_name$)\n"
1040       "  return $name$_;\n"
1041       "}\n"
1042       "inline ::$proto_ns$::RepeatedPtrField<std::string>*\n"
1043       "$classname$::mutable_$name$() {\n"
1044       "$annotate_accessor$"
1045       "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
1046       "  return &$name$_;\n"
1047       "}\n");
1048 }
1049 
GenerateClearingCode(io::Printer * printer) const1050 void RepeatedStringFieldGenerator::GenerateClearingCode(
1051     io::Printer* printer) const {
1052   Formatter format(printer, variables_);
1053   format("$name$_.Clear();\n");
1054 }
1055 
GenerateMergingCode(io::Printer * printer) const1056 void RepeatedStringFieldGenerator::GenerateMergingCode(
1057     io::Printer* printer) const {
1058   Formatter format(printer, variables_);
1059   format("$name$_.MergeFrom(from.$name$_);\n");
1060 }
1061 
GenerateSwappingCode(io::Printer * printer) const1062 void RepeatedStringFieldGenerator::GenerateSwappingCode(
1063     io::Printer* printer) const {
1064   Formatter format(printer, variables_);
1065   format("$name$_.InternalSwap(&other->$name$_);\n");
1066 }
1067 
GenerateConstructorCode(io::Printer * printer) const1068 void RepeatedStringFieldGenerator::GenerateConstructorCode(
1069     io::Printer* printer) const {
1070   // Not needed for repeated fields.
1071 }
1072 
GenerateCopyConstructorCode(io::Printer * printer) const1073 void RepeatedStringFieldGenerator::GenerateCopyConstructorCode(
1074     io::Printer* printer) const {
1075   Formatter format(printer, variables_);
1076   format("$name$_.CopyFrom(from.$name$_);");
1077 }
1078 
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const1079 void RepeatedStringFieldGenerator::GenerateSerializeWithCachedSizesToArray(
1080     io::Printer* printer) const {
1081   Formatter format(printer, variables_);
1082   format(
1083       "for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n"
1084       "  const auto& s = this->_internal_$name$(i);\n");
1085   // format("for (const std::string& s : this->$name$()) {\n");
1086   format.Indent();
1087   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
1088     GenerateUtf8CheckCodeForString(descriptor_, options_, false,
1089                                    "s.data(), static_cast<int>(s.length()),\n",
1090                                    format);
1091   }
1092   format.Outdent();
1093   format(
1094       "  target = stream->Write$declared_type$($number$, s, target);\n"
1095       "}\n");
1096 }
1097 
GenerateByteSize(io::Printer * printer) const1098 void RepeatedStringFieldGenerator::GenerateByteSize(
1099     io::Printer* printer) const {
1100   Formatter format(printer, variables_);
1101   format(
1102       "total_size += $tag_size$ *\n"
1103       "    ::$proto_ns$::internal::FromIntSize($name$_.size());\n"
1104       "for (int i = 0, n = $name$_.size(); i < n; i++) {\n"
1105       "  total_size += "
1106       "::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
1107       "    $name$_.Get(i));\n"
1108       "}\n");
1109 }
1110 
1111 }  // namespace cpp
1112 }  // namespace compiler
1113 }  // namespace protobuf
1114 }  // namespace google
1115