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