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/io/printer.h>
38 #include <google/protobuf/descriptor.pb.h>
39 #include <google/protobuf/stubs/strutil.h>
40 
41 namespace google {
42 namespace protobuf {
43 namespace compiler {
44 namespace cpp {
45 
46 namespace {
47 
SetStringVariables(const FieldDescriptor * descriptor,map<string,string> * variables,const Options & options)48 void SetStringVariables(const FieldDescriptor* descriptor,
49                         map<string, string>* variables,
50                         const Options& options) {
51   SetCommonFieldVariables(descriptor, variables, options);
52   (*variables)["default"] = DefaultValue(descriptor);
53   (*variables)["default_length"] =
54       SimpleItoa(descriptor->default_value_string().length());
55   (*variables)["default_variable"] = descriptor->default_value_string().empty()
56       ? "&::google::protobuf::internal::GetEmptyStringAlreadyInited()"
57       : "_default_" + FieldName(descriptor) + "_";
58   (*variables)["pointer_type"] =
59       descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
60   // NOTE: Escaped here to unblock proto1->proto2 migration.
61   // TODO(liujisi): Extend this to apply for other conflicting methods.
62   (*variables)["release_name"] =
63       SafeFunctionName(descriptor->containing_type(),
64                        descriptor, "release_");
65   (*variables)["full_name"] = descriptor->full_name();
66 }
67 
68 }  // namespace
69 
70 // ===================================================================
71 
72 StringFieldGenerator::
StringFieldGenerator(const FieldDescriptor * descriptor,const Options & options)73 StringFieldGenerator(const FieldDescriptor* descriptor,
74                      const Options& options)
75   : descriptor_(descriptor) {
76   SetStringVariables(descriptor, &variables_, options);
77 }
78 
~StringFieldGenerator()79 StringFieldGenerator::~StringFieldGenerator() {}
80 
81 void StringFieldGenerator::
GeneratePrivateMembers(io::Printer * printer) const82 GeneratePrivateMembers(io::Printer* printer) const {
83   printer->Print(variables_, "::std::string* $name$_;\n");
84 }
85 
86 void StringFieldGenerator::
GenerateStaticMembers(io::Printer * printer) const87 GenerateStaticMembers(io::Printer* printer) const {
88   if (!descriptor_->default_value_string().empty()) {
89     printer->Print(variables_, "static ::std::string* $default_variable$;\n");
90   }
91 }
92 
93 void StringFieldGenerator::
GenerateAccessorDeclarations(io::Printer * printer) const94 GenerateAccessorDeclarations(io::Printer* printer) const {
95   // If we're using StringFieldGenerator for a field with a ctype, it's
96   // because that ctype isn't actually implemented.  In particular, this is
97   // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
98   // We aren't releasing Cord because it has too many Google-specific
99   // dependencies and we aren't releasing StringPiece because it's hardly
100   // useful outside of Google and because it would get confusing to have
101   // multiple instances of the StringPiece class in different libraries (PCRE
102   // already includes it for their C++ bindings, which came from Google).
103   //
104   // In any case, we make all the accessors private while still actually
105   // using a string to represent the field internally.  This way, we can
106   // guarantee that if we do ever implement the ctype, it won't break any
107   // existing users who might be -- for whatever reason -- already using .proto
108   // files that applied the ctype.  The field can still be accessed via the
109   // reflection interface since the reflection interface is independent of
110   // the string's underlying representation.
111   if (descriptor_->options().ctype() != FieldOptions::STRING) {
112     printer->Outdent();
113     printer->Print(
114       " private:\n"
115       "  // Hidden due to unknown ctype option.\n");
116     printer->Indent();
117   }
118 
119   printer->Print(variables_,
120     "inline const ::std::string& $name$() const$deprecation$;\n"
121     "inline void set_$name$(const ::std::string& value)$deprecation$;\n"
122     "inline void set_$name$(const char* value)$deprecation$;\n"
123     "inline void set_$name$(const $pointer_type$* value, size_t size)"
124                  "$deprecation$;\n"
125     "inline ::std::string* mutable_$name$()$deprecation$;\n"
126     "inline ::std::string* $release_name$()$deprecation$;\n"
127     "inline void set_allocated_$name$(::std::string* $name$)$deprecation$;\n");
128 
129 
130   if (descriptor_->options().ctype() != FieldOptions::STRING) {
131     printer->Outdent();
132     printer->Print(" public:\n");
133     printer->Indent();
134   }
135 }
136 
137 void StringFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer * printer) const138 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
139   printer->Print(variables_,
140     "inline const ::std::string& $classname$::$name$() const {\n"
141     "  // @@protoc_insertion_point(field_get:$full_name$)\n"
142     "  return *$name$_;\n"
143     "}\n"
144     "inline void $classname$::set_$name$(const ::std::string& value) {\n"
145     "  set_has_$name$();\n"
146     "  if ($name$_ == $default_variable$) {\n"
147     "    $name$_ = new ::std::string;\n"
148     "  }\n"
149     "  $name$_->assign(value);\n"
150     "  // @@protoc_insertion_point(field_set:$full_name$)\n"
151     "}\n"
152     "inline void $classname$::set_$name$(const char* value) {\n"
153     "  set_has_$name$();\n"
154     "  if ($name$_ == $default_variable$) {\n"
155     "    $name$_ = new ::std::string;\n"
156     "  }\n"
157     "  $name$_->assign(value);\n"
158     "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
159     "}\n"
160     "inline "
161     "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
162     "  set_has_$name$();\n"
163     "  if ($name$_ == $default_variable$) {\n"
164     "    $name$_ = new ::std::string;\n"
165     "  }\n"
166     "  $name$_->assign(reinterpret_cast<const char*>(value), size);\n"
167     "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
168     "}\n"
169     "inline ::std::string* $classname$::mutable_$name$() {\n"
170     "  set_has_$name$();\n"
171     "  if ($name$_ == $default_variable$) {\n");
172   if (descriptor_->default_value_string().empty()) {
173     printer->Print(variables_,
174       "    $name$_ = new ::std::string;\n");
175   } else {
176     printer->Print(variables_,
177       "    $name$_ = new ::std::string(*$default_variable$);\n");
178   }
179   printer->Print(variables_,
180     "  }\n"
181     "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
182     "  return $name$_;\n"
183     "}\n"
184     "inline ::std::string* $classname$::$release_name$() {\n"
185     "  clear_has_$name$();\n"
186     "  if ($name$_ == $default_variable$) {\n"
187     "    return NULL;\n"
188     "  } else {\n"
189     "    ::std::string* temp = $name$_;\n"
190     "    $name$_ = const_cast< ::std::string*>($default_variable$);\n"
191     "    return temp;\n"
192     "  }\n"
193     "}\n"
194     "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
195     "  if ($name$_ != $default_variable$) {\n"
196     "    delete $name$_;\n"
197     "  }\n"
198     "  if ($name$) {\n"
199     "    set_has_$name$();\n"
200     "    $name$_ = $name$;\n"
201     "  } else {\n"
202     "    clear_has_$name$();\n"
203     "    $name$_ = const_cast< ::std::string*>($default_variable$);\n"
204     "  }\n"
205     "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
206     "}\n");
207 }
208 
209 void StringFieldGenerator::
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const210 GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
211   if (!descriptor_->default_value_string().empty()) {
212     // Initialized in GenerateDefaultInstanceAllocator.
213     printer->Print(variables_,
214       "::std::string* $classname$::$default_variable$ = NULL;\n");
215   }
216 }
217 
218 void StringFieldGenerator::
GenerateClearingCode(io::Printer * printer) const219 GenerateClearingCode(io::Printer* printer) const {
220   if (descriptor_->default_value_string().empty()) {
221     printer->Print(variables_,
222       "if ($name$_ != $default_variable$) {\n"
223       "  $name$_->clear();\n"
224       "}\n");
225   } else {
226     printer->Print(variables_,
227       "if ($name$_ != $default_variable$) {\n"
228       "  $name$_->assign(*$default_variable$);\n"
229       "}\n");
230   }
231 }
232 
233 void StringFieldGenerator::
GenerateMergingCode(io::Printer * printer) const234 GenerateMergingCode(io::Printer* printer) const {
235   printer->Print(variables_, "set_$name$(from.$name$());\n");
236 }
237 
238 void StringFieldGenerator::
GenerateSwappingCode(io::Printer * printer) const239 GenerateSwappingCode(io::Printer* printer) const {
240   printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
241 }
242 
243 void StringFieldGenerator::
GenerateConstructorCode(io::Printer * printer) const244 GenerateConstructorCode(io::Printer* printer) const {
245   printer->Print(variables_,
246     "$name$_ = const_cast< ::std::string*>($default_variable$);\n");
247 }
248 
249 void StringFieldGenerator::
GenerateDestructorCode(io::Printer * printer) const250 GenerateDestructorCode(io::Printer* printer) const {
251   printer->Print(variables_,
252     "if ($name$_ != $default_variable$) {\n"
253     "  delete $name$_;\n"
254     "}\n");
255 }
256 
257 void StringFieldGenerator::
GenerateDefaultInstanceAllocator(io::Printer * printer) const258 GenerateDefaultInstanceAllocator(io::Printer* printer) const {
259   if (!descriptor_->default_value_string().empty()) {
260     printer->Print(variables_,
261       "$classname$::$default_variable$ =\n"
262       "    new ::std::string($default$, $default_length$);\n");
263   }
264 }
265 
266 void StringFieldGenerator::
GenerateShutdownCode(io::Printer * printer) const267 GenerateShutdownCode(io::Printer* printer) const {
268   if (!descriptor_->default_value_string().empty()) {
269     printer->Print(variables_,
270       "delete $classname$::$default_variable$;\n");
271   }
272 }
273 
274 void StringFieldGenerator::
GenerateMergeFromCodedStream(io::Printer * printer) const275 GenerateMergeFromCodedStream(io::Printer* printer) const {
276   printer->Print(variables_,
277     "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
278     "      input, this->mutable_$name$()));\n");
279   if (HasUtf8Verification(descriptor_->file()) &&
280       descriptor_->type() == FieldDescriptor::TYPE_STRING) {
281     printer->Print(variables_,
282       "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
283       "  this->$name$().data(), this->$name$().length(),\n"
284       "  ::google::protobuf::internal::WireFormat::PARSE,\n"
285       "  \"$name$\");\n");
286   }
287 }
288 
289 void StringFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer * printer) const290 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
291   if (HasUtf8Verification(descriptor_->file()) &&
292       descriptor_->type() == FieldDescriptor::TYPE_STRING) {
293     printer->Print(variables_,
294       "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
295       "  this->$name$().data(), this->$name$().length(),\n"
296       "  ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
297       "  \"$name$\");\n");
298   }
299   printer->Print(variables_,
300     "::google::protobuf::internal::WireFormatLite::Write$declared_type$MaybeAliased(\n"
301     "  $number$, this->$name$(), output);\n");
302 }
303 
304 void StringFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const305 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
306   if (HasUtf8Verification(descriptor_->file()) &&
307       descriptor_->type() == FieldDescriptor::TYPE_STRING) {
308     printer->Print(variables_,
309       "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
310       "  this->$name$().data(), this->$name$().length(),\n"
311       "  ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
312       "  \"$name$\");\n");
313   }
314   printer->Print(variables_,
315     "target =\n"
316     "  ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray(\n"
317     "    $number$, this->$name$(), target);\n");
318 }
319 
320 void StringFieldGenerator::
GenerateByteSize(io::Printer * printer) const321 GenerateByteSize(io::Printer* printer) const {
322   printer->Print(variables_,
323     "total_size += $tag_size$ +\n"
324     "  ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
325     "    this->$name$());\n");
326 }
327 
328 // ===================================================================
329 
330 StringOneofFieldGenerator::
StringOneofFieldGenerator(const FieldDescriptor * descriptor,const Options & options)331 StringOneofFieldGenerator(const FieldDescriptor* descriptor,
332                           const Options& options)
333   : StringFieldGenerator(descriptor, options) {
334   SetCommonOneofFieldVariables(descriptor, &variables_);
335 }
336 
~StringOneofFieldGenerator()337 StringOneofFieldGenerator::~StringOneofFieldGenerator() {}
338 
339 void StringOneofFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer * printer) const340 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
341   printer->Print(variables_,
342     "inline const ::std::string& $classname$::$name$() const {\n"
343     "  if (has_$name$()) {\n"
344     "    return *$oneof_prefix$$name$_;\n"
345     "  }\n");
346   if (descriptor_->default_value_string().empty()) {
347     printer->Print(variables_,
348       "  return ::google::protobuf::internal::GetEmptyStringAlreadyInited();\n");
349   } else {
350     printer->Print(variables_,
351       "  return *$default_variable$;\n");
352   }
353   printer->Print(variables_,
354     "}\n"
355     "inline void $classname$::set_$name$(const ::std::string& value) {\n"
356     "  if (!has_$name$()) {\n"
357     "    clear_$oneof_name$();\n"
358     "    set_has_$name$();\n"
359     "    $oneof_prefix$$name$_ = new ::std::string;\n"
360     "  }\n"
361     "  $oneof_prefix$$name$_->assign(value);\n"
362     "}\n"
363     "inline void $classname$::set_$name$(const char* value) {\n"
364     "  if (!has_$name$()) {\n"
365     "    clear_$oneof_name$();\n"
366     "    set_has_$name$();\n"
367     "    $oneof_prefix$$name$_ = new ::std::string;\n"
368     "  }\n"
369     "  $oneof_prefix$$name$_->assign(value);\n"
370     "}\n"
371     "inline "
372     "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
373     "  if (!has_$name$()) {\n"
374     "    clear_$oneof_name$();\n"
375     "    set_has_$name$();\n"
376     "    $oneof_prefix$$name$_ = new ::std::string;\n"
377     "  }\n"
378     "  $oneof_prefix$$name$_->assign(\n"
379     "      reinterpret_cast<const char*>(value), size);\n"
380     "}\n"
381     "inline ::std::string* $classname$::mutable_$name$() {\n"
382     "  if (!has_$name$()) {\n"
383     "    clear_$oneof_name$();\n"
384     "    set_has_$name$();\n");
385   if (descriptor_->default_value_string().empty()) {
386     printer->Print(variables_,
387       "    $oneof_prefix$$name$_ = new ::std::string;\n");
388   } else {
389     printer->Print(variables_,
390       "    $oneof_prefix$$name$_ = new ::std::string(*$default_variable$);\n");
391   }
392   printer->Print(variables_,
393     "  }\n"
394     "  return $oneof_prefix$$name$_;\n"
395     "}\n"
396     "inline ::std::string* $classname$::$release_name$() {\n"
397     "  if (has_$name$()) {\n"
398     "    clear_has_$oneof_name$();\n"
399     "    ::std::string* temp = $oneof_prefix$$name$_;\n"
400     "    $oneof_prefix$$name$_ = NULL;\n"
401     "    return temp;\n"
402     "  } else {\n"
403     "    return NULL;\n"
404     "  }\n"
405     "}\n"
406     "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
407     "  clear_$oneof_name$();\n"
408     "  if ($name$) {\n"
409     "    set_has_$name$();\n"
410     "    $oneof_prefix$$name$_ = $name$;\n"
411     "  }\n"
412     "}\n");
413 }
414 
415 void StringOneofFieldGenerator::
GenerateClearingCode(io::Printer * printer) const416 GenerateClearingCode(io::Printer* printer) const {
417     printer->Print(variables_,
418       "delete $oneof_prefix$$name$_;\n");
419 }
420 
421 void StringOneofFieldGenerator::
GenerateSwappingCode(io::Printer * printer) const422 GenerateSwappingCode(io::Printer* printer) const {
423   // Don't print any swapping code. Swapping the union will swap this field.
424 }
425 
426 void StringOneofFieldGenerator::
GenerateConstructorCode(io::Printer * printer) const427 GenerateConstructorCode(io::Printer* printer) const {
428   if (!descriptor_->default_value_string().empty()) {
429     printer->Print(variables_,
430       "  $classname$_default_oneof_instance_->$name$_ = "
431       "$classname$::$default_variable$;\n");
432   } else {
433     printer->Print(variables_,
434       "  $classname$_default_oneof_instance_->$name$_ = "
435       "$default_variable$;\n");
436   }
437 }
438 
439 void StringOneofFieldGenerator::
GenerateDestructorCode(io::Printer * printer) const440 GenerateDestructorCode(io::Printer* printer) const {
441   printer->Print(variables_,
442     "if (has_$name$()) {\n"
443     "  delete $oneof_prefix$$name$_;\n"
444     "}\n");
445 }
446 
447 // ===================================================================
448 
449 RepeatedStringFieldGenerator::
RepeatedStringFieldGenerator(const FieldDescriptor * descriptor,const Options & options)450 RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
451                              const Options& options)
452   : descriptor_(descriptor) {
453   SetStringVariables(descriptor, &variables_, options);
454 }
455 
~RepeatedStringFieldGenerator()456 RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
457 
458 void RepeatedStringFieldGenerator::
GeneratePrivateMembers(io::Printer * printer) const459 GeneratePrivateMembers(io::Printer* printer) const {
460   printer->Print(variables_,
461     "::google::protobuf::RepeatedPtrField< ::std::string> $name$_;\n");
462 }
463 
464 void RepeatedStringFieldGenerator::
GenerateAccessorDeclarations(io::Printer * printer) const465 GenerateAccessorDeclarations(io::Printer* printer) const {
466   // See comment above about unknown ctypes.
467   if (descriptor_->options().ctype() != FieldOptions::STRING) {
468     printer->Outdent();
469     printer->Print(
470       " private:\n"
471       "  // Hidden due to unknown ctype option.\n");
472     printer->Indent();
473   }
474 
475   printer->Print(variables_,
476     "inline const ::std::string& $name$(int index) const$deprecation$;\n"
477     "inline ::std::string* mutable_$name$(int index)$deprecation$;\n"
478     "inline void set_$name$(int index, const ::std::string& value)$deprecation$;\n"
479     "inline void set_$name$(int index, const char* value)$deprecation$;\n"
480     "inline "
481     "void set_$name$(int index, const $pointer_type$* value, size_t size)"
482                  "$deprecation$;\n"
483     "inline ::std::string* add_$name$()$deprecation$;\n"
484     "inline void add_$name$(const ::std::string& value)$deprecation$;\n"
485     "inline void add_$name$(const char* value)$deprecation$;\n"
486     "inline void add_$name$(const $pointer_type$* value, size_t size)"
487                  "$deprecation$;\n");
488 
489   printer->Print(variables_,
490     "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const"
491                  "$deprecation$;\n"
492     "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()"
493                  "$deprecation$;\n");
494 
495   if (descriptor_->options().ctype() != FieldOptions::STRING) {
496     printer->Outdent();
497     printer->Print(" public:\n");
498     printer->Indent();
499   }
500 }
501 
502 void RepeatedStringFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer * printer) const503 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
504   printer->Print(variables_,
505     "inline const ::std::string& $classname$::$name$(int index) const {\n"
506     "  // @@protoc_insertion_point(field_get:$full_name$)\n"
507     "  return $name$_.$cppget$(index);\n"
508     "}\n"
509     "inline ::std::string* $classname$::mutable_$name$(int index) {\n"
510     "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
511     "  return $name$_.Mutable(index);\n"
512     "}\n"
513     "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
514     "  // @@protoc_insertion_point(field_set:$full_name$)\n"
515     "  $name$_.Mutable(index)->assign(value);\n"
516     "}\n"
517     "inline void $classname$::set_$name$(int index, const char* value) {\n"
518     "  $name$_.Mutable(index)->assign(value);\n"
519     "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
520     "}\n"
521     "inline void "
522     "$classname$::set_$name$"
523     "(int index, const $pointer_type$* value, size_t size) {\n"
524     "  $name$_.Mutable(index)->assign(\n"
525     "    reinterpret_cast<const char*>(value), size);\n"
526     "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
527     "}\n"
528     "inline ::std::string* $classname$::add_$name$() {\n"
529     "  return $name$_.Add();\n"
530     "}\n"
531     "inline void $classname$::add_$name$(const ::std::string& value) {\n"
532     "  $name$_.Add()->assign(value);\n"
533     "  // @@protoc_insertion_point(field_add:$full_name$)\n"
534     "}\n"
535     "inline void $classname$::add_$name$(const char* value) {\n"
536     "  $name$_.Add()->assign(value);\n"
537     "  // @@protoc_insertion_point(field_add_char:$full_name$)\n"
538     "}\n"
539     "inline void "
540     "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
541     "  $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
542     "  // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
543     "}\n");
544   printer->Print(variables_,
545     "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
546     "$classname$::$name$() const {\n"
547     "  // @@protoc_insertion_point(field_list:$full_name$)\n"
548     "  return $name$_;\n"
549     "}\n"
550     "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
551     "$classname$::mutable_$name$() {\n"
552     "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
553     "  return &$name$_;\n"
554     "}\n");
555 }
556 
557 void RepeatedStringFieldGenerator::
GenerateClearingCode(io::Printer * printer) const558 GenerateClearingCode(io::Printer* printer) const {
559   printer->Print(variables_, "$name$_.Clear();\n");
560 }
561 
562 void RepeatedStringFieldGenerator::
GenerateMergingCode(io::Printer * printer) const563 GenerateMergingCode(io::Printer* printer) const {
564   printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
565 }
566 
567 void RepeatedStringFieldGenerator::
GenerateSwappingCode(io::Printer * printer) const568 GenerateSwappingCode(io::Printer* printer) const {
569   printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
570 }
571 
572 void RepeatedStringFieldGenerator::
GenerateConstructorCode(io::Printer * printer) const573 GenerateConstructorCode(io::Printer* printer) const {
574   // Not needed for repeated fields.
575 }
576 
577 void RepeatedStringFieldGenerator::
GenerateMergeFromCodedStream(io::Printer * printer) const578 GenerateMergeFromCodedStream(io::Printer* printer) const {
579   printer->Print(variables_,
580     "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
581     "      input, this->add_$name$()));\n");
582   if (HasUtf8Verification(descriptor_->file()) &&
583       descriptor_->type() == FieldDescriptor::TYPE_STRING) {
584     printer->Print(variables_,
585       "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
586       "  this->$name$(this->$name$_size() - 1).data(),\n"
587       "  this->$name$(this->$name$_size() - 1).length(),\n"
588       "  ::google::protobuf::internal::WireFormat::PARSE,\n"
589       "  \"$name$\");\n");
590   }
591 }
592 
593 void RepeatedStringFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer * printer) const594 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
595   printer->Print(variables_,
596     "for (int i = 0; i < this->$name$_size(); i++) {\n");
597   if (HasUtf8Verification(descriptor_->file()) &&
598       descriptor_->type() == FieldDescriptor::TYPE_STRING) {
599     printer->Print(variables_,
600       "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
601       "  this->$name$(i).data(), this->$name$(i).length(),\n"
602       "  ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
603       "  \"$name$\");\n");
604   }
605   printer->Print(variables_,
606     "  ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
607     "    $number$, this->$name$(i), output);\n"
608     "}\n");
609 }
610 
611 void RepeatedStringFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const612 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
613   printer->Print(variables_,
614     "for (int i = 0; i < this->$name$_size(); i++) {\n");
615   if (HasUtf8Verification(descriptor_->file()) &&
616       descriptor_->type() == FieldDescriptor::TYPE_STRING) {
617     printer->Print(variables_,
618       "  ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
619       "    this->$name$(i).data(), this->$name$(i).length(),\n"
620       "    ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
621       "    \"$name$\");\n");
622   }
623   printer->Print(variables_,
624     "  target = ::google::protobuf::internal::WireFormatLite::\n"
625     "    Write$declared_type$ToArray($number$, this->$name$(i), target);\n"
626     "}\n");
627 }
628 
629 void RepeatedStringFieldGenerator::
GenerateByteSize(io::Printer * printer) const630 GenerateByteSize(io::Printer* printer) const {
631   printer->Print(variables_,
632     "total_size += $tag_size$ * this->$name$_size();\n"
633     "for (int i = 0; i < this->$name$_size(); i++) {\n"
634     "  total_size += ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
635     "    this->$name$(i));\n"
636     "}\n");
637 }
638 
639 }  // namespace cpp
640 }  // namespace compiler
641 }  // namespace protobuf
642 }  // namespace google
643