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