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