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