Line data Source code
1 : // Protocol Buffers - Google's data interchange format
2 : // Copyright 2008 Google Inc. All rights reserved.
3 : // https://developers.google.com/protocol-buffers/
4 : //
5 : // Redistribution and use in source and binary forms, with or without
6 : // modification, are permitted provided that the following conditions are
7 : // met:
8 : //
9 : // * Redistributions of source code must retain the above copyright
10 : // notice, this list of conditions and the following disclaimer.
11 : // * Redistributions in binary form must reproduce the above
12 : // copyright notice, this list of conditions and the following disclaimer
13 : // in the documentation and/or other materials provided with the
14 : // distribution.
15 : // * Neither the name of Google Inc. nor the names of its
16 : // contributors may be used to endorse or promote products derived from
17 : // this software without specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 :
31 : // Author: kenton@google.com (Kenton Varda)
32 : // Based on original Protocol Buffers design by
33 : // Sanjay Ghemawat, Jeff Dean, and others.
34 :
35 : #include <google/protobuf/compiler/cpp/cpp_string_field.h>
36 : #include <google/protobuf/compiler/cpp/cpp_helpers.h>
37 : #include <google/protobuf/io/printer.h>
38 : #include <google/protobuf/descriptor.pb.h>
39 : #include <google/protobuf/stubs/strutil.h>
40 :
41 : namespace google {
42 : namespace protobuf {
43 : namespace compiler {
44 : namespace cpp {
45 :
46 : namespace {
47 :
48 8379 : void SetStringVariables(const FieldDescriptor* descriptor,
49 : map<string, string>* variables,
50 : const Options& options) {
51 1197 : SetCommonFieldVariables(descriptor, variables, options);
52 3591 : (*variables)["default"] = DefaultValue(descriptor);
53 3591 : (*variables)["default_length"] =
54 1197 : SimpleItoa(descriptor->default_value_string().length());
55 : string default_variable_string =
56 1197 : descriptor->default_value_string().empty()
57 : ? "&::google::protobuf::internal::GetEmptyStringAlreadyInited()"
58 3249 : : "_default_" + FieldName(descriptor) + "_";
59 2394 : (*variables)["default_variable"] = default_variable_string;
60 3762 : (*variables)["default_value_init"] =
61 1197 : descriptor->default_value_string().empty()
62 1026 : ? "" : "*" + default_variable_string;
63 2394 : (*variables)["pointer_type"] =
64 1197 : descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
65 : // NOTE: Escaped here to unblock proto1->proto2 migration.
66 : // TODO(liujisi): Extend this to apply for other conflicting methods.
67 5985 : (*variables)["release_name"] =
68 : SafeFunctionName(descriptor->containing_type(),
69 : descriptor, "release_");
70 2394 : (*variables)["full_name"] = descriptor->full_name();
71 :
72 2394 : (*variables)["string_piece"] = "::std::string";
73 1197 : }
74 :
75 : } // namespace
76 :
77 : // ===================================================================
78 :
79 1159 : StringFieldGenerator::
80 : StringFieldGenerator(const FieldDescriptor* descriptor,
81 : const Options& options)
82 2318 : : descriptor_(descriptor) {
83 1159 : SetStringVariables(descriptor, &variables_, options);
84 1159 : }
85 :
86 3453 : StringFieldGenerator::~StringFieldGenerator() {}
87 :
88 1154 : void StringFieldGenerator::
89 : GeneratePrivateMembers(io::Printer* printer) const {
90 : // N.B. that we continue to use |ArenaStringPtr| instead of |string*| for
91 : // string fields, even when SupportArenas(descriptor_) == false. Why?
92 : // The simple answer is to avoid unmaintainable complexity. The reflection
93 : // code assumes ArenaStringPtrs. These are *almost* in-memory-compatible with
94 : // string*, except for the pointer tags and related ownership semantics. We
95 : // could modify the runtime code to use string* for the not-supporting-arenas
96 : // case, but this would require a way to detect which type of class was
97 : // generated (adding overhead and complexity to GeneratedMessageReflection)
98 : // and littering the runtime code paths with conditionals. It's simpler to
99 : // stick with this but use lightweight accessors that assume arena == NULL.
100 : // There should be very little overhead anyway because it's just a tagged
101 : // pointer in-memory.
102 1154 : printer->Print(variables_, "::google::protobuf::internal::ArenaStringPtr $name$_;\n");
103 1154 : }
104 :
105 1132 : void StringFieldGenerator::
106 : GenerateStaticMembers(io::Printer* printer) const {
107 2264 : if (!descriptor_->default_value_string().empty()) {
108 1026 : printer->Print(variables_, "static ::std::string* $default_variable$;\n");
109 : }
110 1132 : }
111 :
112 1132 : void StringFieldGenerator::
113 : GenerateAccessorDeclarations(io::Printer* printer) const {
114 : // If we're using StringFieldGenerator for a field with a ctype, it's
115 : // because that ctype isn't actually implemented. In particular, this is
116 : // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
117 : // We aren't releasing Cord because it has too many Google-specific
118 : // dependencies and we aren't releasing StringPiece because it's hardly
119 : // useful outside of Google and because it would get confusing to have
120 : // multiple instances of the StringPiece class in different libraries (PCRE
121 : // already includes it for their C++ bindings, which came from Google).
122 : //
123 : // In any case, we make all the accessors private while still actually
124 : // using a string to represent the field internally. This way, we can
125 : // guarantee that if we do ever implement the ctype, it won't break any
126 : // existing users who might be -- for whatever reason -- already using .proto
127 : // files that applied the ctype. The field can still be accessed via the
128 : // reflection interface since the reflection interface is independent of
129 : // the string's underlying representation.
130 :
131 : bool unknown_ctype =
132 2264 : descriptor_->options().ctype() != EffectiveStringCType(descriptor_);
133 :
134 1132 : if (unknown_ctype) {
135 28 : printer->Outdent();
136 : printer->Print(
137 : " private:\n"
138 28 : " // Hidden due to unknown ctype option.\n");
139 28 : printer->Indent();
140 : }
141 :
142 : printer->Print(variables_,
143 : "const ::std::string& $name$() const$deprecation$;\n"
144 : "void set_$name$(const ::std::string& value)$deprecation$;\n"
145 : "void set_$name$(const char* value)$deprecation$;\n"
146 : "void set_$name$(const $pointer_type$* value, size_t size)"
147 : "$deprecation$;\n"
148 : "::std::string* mutable_$name$()$deprecation$;\n"
149 : "::std::string* $release_name$()$deprecation$;\n"
150 1132 : "void set_allocated_$name$(::std::string* $name$)$deprecation$;\n");
151 2264 : if (SupportsArenas(descriptor_)) {
152 : printer->Print(variables_,
153 : "::std::string* unsafe_arena_release_$name$()$deprecation$;\n"
154 : "void unsafe_arena_set_allocated_$name$(\n"
155 48 : " ::std::string* $name$)$deprecation$;\n");
156 : }
157 :
158 :
159 1132 : if (unknown_ctype) {
160 28 : printer->Outdent();
161 28 : printer->Print(" public:\n");
162 28 : printer->Indent();
163 : }
164 1132 : }
165 :
166 2216 : void StringFieldGenerator::
167 : GenerateInlineAccessorDefinitions(io::Printer* printer,
168 : bool is_inline) const {
169 2216 : map<string, string> variables(variables_);
170 4432 : variables["inline"] = is_inline ? "inline" : "";
171 4432 : if (SupportsArenas(descriptor_)) {
172 : printer->Print(variables,
173 : "$inline$ const ::std::string& $classname$::$name$() const {\n"
174 : " // @@protoc_insertion_point(field_get:$full_name$)\n"
175 : " return $name$_.Get($default_variable$);\n"
176 : "}\n"
177 : "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n"
178 : " $set_hasbit$\n"
179 : " $name$_.Set($default_variable$, value, GetArenaNoVirtual());\n"
180 : " // @@protoc_insertion_point(field_set:$full_name$)\n"
181 : "}\n"
182 : "$inline$ void $classname$::set_$name$(const char* value) {\n"
183 : " $set_hasbit$\n"
184 : " $name$_.Set($default_variable$, $string_piece$(value),\n"
185 : " GetArenaNoVirtual());\n"
186 : " // @@protoc_insertion_point(field_set_char:$full_name$)\n"
187 : "}\n"
188 : "$inline$ "
189 : "void $classname$::set_$name$(const $pointer_type$* value,\n"
190 : " size_t size) {\n"
191 : " $set_hasbit$\n"
192 : " $name$_.Set($default_variable$, $string_piece$(\n"
193 : " reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());\n"
194 : " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
195 : "}\n"
196 : "$inline$ ::std::string* $classname$::mutable_$name$() {\n"
197 : " $set_hasbit$\n"
198 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
199 : " return $name$_.Mutable($default_variable$, GetArenaNoVirtual());\n"
200 : "}\n"
201 : "$inline$ ::std::string* $classname$::$release_name$() {\n"
202 : " $clear_hasbit$\n"
203 : " return $name$_.Release($default_variable$, GetArenaNoVirtual());\n"
204 : "}\n"
205 : "$inline$ ::std::string* $classname$::unsafe_arena_release_$name$() {\n"
206 : " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
207 : " $clear_hasbit$\n"
208 : " return $name$_.UnsafeArenaRelease($default_variable$,\n"
209 : " GetArenaNoVirtual());\n"
210 : "}\n"
211 : "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
212 : " if ($name$ != NULL) {\n"
213 : " $set_hasbit$\n"
214 : " } else {\n"
215 : " $clear_hasbit$\n"
216 : " }\n"
217 : " $name$_.SetAllocated($default_variable$, $name$,\n"
218 : " GetArenaNoVirtual());\n"
219 : " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
220 : "}\n"
221 : "$inline$ void $classname$::unsafe_arena_set_allocated_$name$(\n"
222 : " ::std::string* $name$) {\n"
223 : " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
224 : " if ($name$ != NULL) {\n"
225 : " $set_hasbit$\n"
226 : " } else {\n"
227 : " $clear_hasbit$\n"
228 : " }\n"
229 : " $name$_.UnsafeArenaSetAllocated($default_variable$,\n"
230 : " $name$, GetArenaNoVirtual());\n"
231 : " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
232 68 : "}\n");
233 : } else {
234 : // No-arena case.
235 : printer->Print(variables,
236 : "$inline$ const ::std::string& $classname$::$name$() const {\n"
237 : " // @@protoc_insertion_point(field_get:$full_name$)\n"
238 : " return $name$_.GetNoArena($default_variable$);\n"
239 : "}\n"
240 : "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n"
241 : " $set_hasbit$\n"
242 : " $name$_.SetNoArena($default_variable$, value);\n"
243 : " // @@protoc_insertion_point(field_set:$full_name$)\n"
244 : "}\n"
245 : "$inline$ void $classname$::set_$name$(const char* value) {\n"
246 : " $set_hasbit$\n"
247 : " $name$_.SetNoArena($default_variable$, $string_piece$(value));\n"
248 : " // @@protoc_insertion_point(field_set_char:$full_name$)\n"
249 : "}\n"
250 : "$inline$ "
251 : "void $classname$::set_$name$(const $pointer_type$* value, "
252 : "size_t size) {\n"
253 : " $set_hasbit$\n"
254 : " $name$_.SetNoArena($default_variable$,\n"
255 : " $string_piece$(reinterpret_cast<const char*>(value), size));\n"
256 : " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
257 : "}\n"
258 : "$inline$ ::std::string* $classname$::mutable_$name$() {\n"
259 : " $set_hasbit$\n"
260 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
261 : " return $name$_.MutableNoArena($default_variable$);\n"
262 : "}\n"
263 : "$inline$ ::std::string* $classname$::$release_name$() {\n"
264 : " $clear_hasbit$\n"
265 : " return $name$_.ReleaseNoArena($default_variable$);\n"
266 : "}\n"
267 : "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
268 : " if ($name$ != NULL) {\n"
269 : " $set_hasbit$\n"
270 : " } else {\n"
271 : " $clear_hasbit$\n"
272 : " }\n"
273 : " $name$_.SetAllocatedNoArena($default_variable$, $name$);\n"
274 : " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
275 2148 : "}\n");
276 : }
277 2216 : }
278 :
279 1132 : void StringFieldGenerator::
280 : GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
281 2264 : if (!descriptor_->default_value_string().empty()) {
282 : // Initialized in GenerateDefaultInstanceAllocator.
283 : printer->Print(variables_,
284 1026 : "::std::string* $classname$::$default_variable$ = NULL;\n");
285 : }
286 1132 : }
287 :
288 2324 : void StringFieldGenerator::
289 : GenerateClearingCode(io::Printer* printer) const {
290 : // Two-dimension specialization here: supporting arenas or not, and default
291 : // value is the empty string or not. Complexity here ensures the minimal
292 : // number of branches / amount of extraneous code at runtime (given that the
293 : // below methods are inlined one-liners)!
294 6870 : if (SupportsArenas(descriptor_)) {
295 204 : if (descriptor_->default_value_string().empty()) {
296 : printer->Print(variables_,
297 60 : "$name$_.ClearToEmpty($default_variable$, GetArenaNoVirtual());\n");
298 : } else {
299 : printer->Print(variables_,
300 42 : "$name$_.ClearToDefault($default_variable$, GetArenaNoVirtual());\n");
301 : }
302 : } else {
303 4444 : if (descriptor_->default_value_string().empty()) {
304 : printer->Print(variables_,
305 198 : "$name$_.ClearToEmptyNoArena($default_variable$);\n");
306 : } else {
307 : printer->Print(variables_,
308 2024 : "$name$_.ClearToDefaultNoArena($default_variable$);\n");
309 : }
310 : }
311 2324 : }
312 :
313 131 : void StringFieldGenerator::
314 : GenerateMergingCode(io::Printer* printer) const {
315 262 : if (SupportsArenas(descriptor_) || descriptor_->containing_oneof() != NULL) {
316 : // TODO(gpike): improve this
317 57 : printer->Print(variables_, "set_$name$(from.$name$());\n");
318 : } else {
319 : printer->Print(variables_,
320 : "$set_hasbit$\n"
321 74 : "$name$_.AssignWithDefault($default_variable$, from.$name$_);\n");
322 : }
323 131 : }
324 :
325 108 : void StringFieldGenerator::
326 : GenerateSwappingCode(io::Printer* printer) const {
327 108 : printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
328 108 : }
329 :
330 1108 : void StringFieldGenerator::
331 : GenerateConstructorCode(io::Printer* printer) const {
332 : printer->Print(variables_,
333 1108 : "$name$_.UnsafeSetDefault($default_variable$);\n");
334 1108 : }
335 :
336 1108 : void StringFieldGenerator::
337 : GenerateDestructorCode(io::Printer* printer) const {
338 2216 : if (SupportsArenas(descriptor_)) {
339 : printer->Print(variables_,
340 34 : "$name$_.Destroy($default_variable$, GetArenaNoVirtual());\n");
341 : } else {
342 : printer->Print(variables_,
343 1074 : "$name$_.DestroyNoArena($default_variable$);\n");
344 : }
345 1108 : }
346 :
347 1159 : void StringFieldGenerator::
348 : GenerateDefaultInstanceAllocator(io::Printer* printer) const {
349 2318 : if (!descriptor_->default_value_string().empty()) {
350 : printer->Print(variables_,
351 : "$classname$::$default_variable$ =\n"
352 1026 : " new ::std::string($default$, $default_length$);\n");
353 : }
354 1159 : }
355 :
356 1132 : void StringFieldGenerator::
357 : GenerateShutdownCode(io::Printer* printer) const {
358 2264 : if (!descriptor_->default_value_string().empty()) {
359 : printer->Print(variables_,
360 1026 : "delete $classname$::$default_variable$;\n");
361 : }
362 1132 : }
363 :
364 108 : void StringFieldGenerator::
365 : GenerateMergeFromCodedStream(io::Printer* printer) const {
366 : printer->Print(variables_,
367 : "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
368 108 : " input, this->mutable_$name$()));\n");
369 :
370 108 : if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
371 : GenerateUtf8CheckCodeForString(
372 : descriptor_, true, variables_,
373 90 : "this->$name$().data(), this->$name$().length(),\n", printer);
374 : }
375 108 : }
376 :
377 131 : void StringFieldGenerator::
378 : GenerateSerializeWithCachedSizes(io::Printer* printer) const {
379 131 : if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
380 : GenerateUtf8CheckCodeForString(
381 : descriptor_, false, variables_,
382 106 : "this->$name$().data(), this->$name$().length(),\n", printer);
383 : }
384 : printer->Print(variables_,
385 : "::google::protobuf::internal::WireFormatLite::Write$declared_type$MaybeAliased(\n"
386 131 : " $number$, this->$name$(), output);\n");
387 131 : }
388 :
389 121 : void StringFieldGenerator::
390 : GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
391 121 : if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
392 : GenerateUtf8CheckCodeForString(
393 : descriptor_, false, variables_,
394 99 : "this->$name$().data(), this->$name$().length(),\n", printer);
395 : }
396 : printer->Print(variables_,
397 : "target =\n"
398 : " ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray(\n"
399 121 : " $number$, this->$name$(), target);\n");
400 121 : }
401 :
402 132 : void StringFieldGenerator::
403 : GenerateByteSize(io::Printer* printer) const {
404 : printer->Print(variables_,
405 : "total_size += $tag_size$ +\n"
406 : " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
407 132 : " this->$name$());\n");
408 132 : }
409 :
410 : // ===================================================================
411 :
412 24 : StringOneofFieldGenerator::
413 : StringOneofFieldGenerator(const FieldDescriptor* descriptor,
414 : const Options& options)
415 : : StringFieldGenerator(descriptor, options),
416 24 : dependent_field_(options.proto_h) {
417 24 : SetCommonOneofFieldVariables(descriptor, &variables_);
418 24 : }
419 :
420 48 : StringOneofFieldGenerator::~StringOneofFieldGenerator() {}
421 :
422 48 : void StringOneofFieldGenerator::
423 : GenerateInlineAccessorDefinitions(io::Printer* printer,
424 : bool is_inline) const {
425 48 : map<string, string> variables(variables_);
426 96 : variables["inline"] = is_inline ? "inline" : "";
427 96 : if (SupportsArenas(descriptor_)) {
428 : printer->Print(variables,
429 : "$inline$ const ::std::string& $classname$::$name$() const {\n"
430 : " // @@protoc_insertion_point(field_get:$full_name$)\n"
431 : " if (has_$name$()) {\n"
432 : " return $oneof_prefix$$name$_.Get($default_variable$);\n"
433 : " }\n"
434 : " return *$default_variable$;\n"
435 : "}\n"
436 : "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n"
437 : " if (!has_$name$()) {\n"
438 : " clear_$oneof_name$();\n"
439 : " set_has_$name$();\n"
440 : " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
441 : " }\n"
442 : " $oneof_prefix$$name$_.Set($default_variable$, value,\n"
443 : " GetArenaNoVirtual());\n"
444 : " // @@protoc_insertion_point(field_set:$full_name$)\n"
445 : "}\n"
446 : "$inline$ void $classname$::set_$name$(const char* value) {\n"
447 : " if (!has_$name$()) {\n"
448 : " clear_$oneof_name$();\n"
449 : " set_has_$name$();\n"
450 : " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
451 : " }\n"
452 : " $oneof_prefix$$name$_.Set($default_variable$,\n"
453 : " $string_piece$(value), GetArenaNoVirtual());\n"
454 : " // @@protoc_insertion_point(field_set_char:$full_name$)\n"
455 : "}\n"
456 : "$inline$ "
457 : "void $classname$::set_$name$(const $pointer_type$* value,\n"
458 : " size_t size) {\n"
459 : " if (!has_$name$()) {\n"
460 : " clear_$oneof_name$();\n"
461 : " set_has_$name$();\n"
462 : " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
463 : " }\n"
464 : " $oneof_prefix$$name$_.Set($default_variable$, $string_piece$(\n"
465 : " reinterpret_cast<const char*>(value), size),\n"
466 : " GetArenaNoVirtual());\n"
467 : " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
468 : "}\n"
469 : "$inline$ ::std::string* $classname$::mutable_$name$() {\n"
470 : " if (!has_$name$()) {\n"
471 : " clear_$oneof_name$();\n"
472 : " set_has_$name$();\n"
473 : " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
474 : " }\n"
475 : " return $oneof_prefix$$name$_.Mutable($default_variable$,\n"
476 : " GetArenaNoVirtual());\n"
477 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
478 : "}\n"
479 : "$inline$ ::std::string* $classname$::$release_name$() {\n"
480 : " if (has_$name$()) {\n"
481 : " clear_has_$oneof_name$();\n"
482 : " return $oneof_prefix$$name$_.Release($default_variable$,\n"
483 : " GetArenaNoVirtual());\n"
484 : " } else {\n"
485 : " return NULL;\n"
486 : " }\n"
487 : "}\n"
488 : "$inline$ ::std::string* $classname$::unsafe_arena_release_$name$() {\n"
489 : " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
490 : " if (has_$name$()) {\n"
491 : " clear_has_$oneof_name$();\n"
492 : " return $oneof_prefix$$name$_.UnsafeArenaRelease(\n"
493 : " $default_variable$, GetArenaNoVirtual());\n"
494 : " } else {\n"
495 : " return NULL;\n"
496 : " }\n"
497 : "}\n"
498 : "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
499 : " if (!has_$name$()) {\n"
500 : " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
501 : " }\n"
502 : " clear_$oneof_name$();\n"
503 : " if ($name$ != NULL) {\n"
504 : " set_has_$name$();\n"
505 : " $oneof_prefix$$name$_.SetAllocated($default_variable$, $name$,\n"
506 : " GetArenaNoVirtual());\n"
507 : " }\n"
508 : " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
509 : "}\n"
510 : "$inline$ void $classname$::unsafe_arena_set_allocated_$name$("
511 : "::std::string* $name$) {\n"
512 : " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
513 : " if (!has_$name$()) {\n"
514 : " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
515 : " }\n"
516 : " clear_$oneof_name$();\n"
517 : " if ($name$) {\n"
518 : " set_has_$name$();\n"
519 : " $oneof_prefix$$name$_.UnsafeArenaSetAllocated($default_variable$, "
520 : "$name$, GetArenaNoVirtual());\n"
521 : " }\n"
522 : " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
523 28 : "}\n");
524 : } else {
525 : // No-arena case.
526 : printer->Print(variables,
527 : "$inline$ const ::std::string& $classname$::$name$() const {\n"
528 : " // @@protoc_insertion_point(field_get:$full_name$)\n"
529 : " if (has_$name$()) {\n"
530 : " return $oneof_prefix$$name$_.GetNoArena($default_variable$);\n"
531 : " }\n"
532 : " return *$default_variable$;\n"
533 : "}\n"
534 : "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n"
535 : " // @@protoc_insertion_point(field_set:$full_name$)\n"
536 : " if (!has_$name$()) {\n"
537 : " clear_$oneof_name$();\n"
538 : " set_has_$name$();\n"
539 : " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
540 : " }\n"
541 : " $oneof_prefix$$name$_.SetNoArena($default_variable$, value);\n"
542 : " // @@protoc_insertion_point(field_set:$full_name$)\n"
543 : "}\n"
544 : "$inline$ void $classname$::set_$name$(const char* value) {\n"
545 : " if (!has_$name$()) {\n"
546 : " clear_$oneof_name$();\n"
547 : " set_has_$name$();\n"
548 : " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
549 : " }\n"
550 : " $oneof_prefix$$name$_.SetNoArena($default_variable$,\n"
551 : " $string_piece$(value));\n"
552 : " // @@protoc_insertion_point(field_set_char:$full_name$)\n"
553 : "}\n"
554 : "$inline$ "
555 : "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
556 : " if (!has_$name$()) {\n"
557 : " clear_$oneof_name$();\n"
558 : " set_has_$name$();\n"
559 : " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
560 : " }\n"
561 : " $oneof_prefix$$name$_.SetNoArena($default_variable$, $string_piece$(\n"
562 : " reinterpret_cast<const char*>(value), size));\n"
563 : " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
564 : "}\n"
565 : "$inline$ ::std::string* $classname$::mutable_$name$() {\n"
566 : " if (!has_$name$()) {\n"
567 : " clear_$oneof_name$();\n"
568 : " set_has_$name$();\n"
569 : " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
570 : " }\n"
571 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
572 : " return $oneof_prefix$$name$_.MutableNoArena($default_variable$);\n"
573 : "}\n"
574 : "$inline$ ::std::string* $classname$::$release_name$() {\n"
575 : " if (has_$name$()) {\n"
576 : " clear_has_$oneof_name$();\n"
577 : " return $oneof_prefix$$name$_.ReleaseNoArena($default_variable$);\n"
578 : " } else {\n"
579 : " return NULL;\n"
580 : " }\n"
581 : "}\n"
582 : "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
583 : " if (!has_$name$()) {\n"
584 : " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
585 : " }\n"
586 : " clear_$oneof_name$();\n"
587 : " if ($name$ != NULL) {\n"
588 : " set_has_$name$();\n"
589 : " $oneof_prefix$$name$_.SetAllocatedNoArena($default_variable$,\n"
590 : " $name$);\n"
591 : " }\n"
592 : " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
593 20 : "}\n");
594 : }
595 48 : }
596 :
597 72 : void StringOneofFieldGenerator::
598 : GenerateClearingCode(io::Printer* printer) const {
599 72 : map<string, string> variables(variables_);
600 72 : if (dependent_field_) {
601 0 : variables["this_message"] = DependentBaseDownCast();
602 : // This clearing code may be in the dependent base class. If the default
603 : // value is an empty string, then the $default_variable$ is a global
604 : // singleton. If the default is not empty, we need to down-cast to get the
605 : // default value's global singleton instance. See SetStringVariables() for
606 : // possible values of default_variable.
607 0 : if (!descriptor_->default_value_string().empty()) {
608 0 : variables["default_variable"] =
609 0 : DependentBaseDownCast() + variables["default_variable"];
610 : }
611 : } else {
612 144 : variables["this_message"] = "";
613 : }
614 144 : if (SupportsArenas(descriptor_)) {
615 : printer->Print(variables,
616 : "$this_message$$oneof_prefix$$name$_.Destroy($default_variable$,\n"
617 42 : " $this_message$GetArenaNoVirtual());\n");
618 : } else {
619 : printer->Print(variables,
620 : "$this_message$$oneof_prefix$$name$_."
621 30 : "DestroyNoArena($default_variable$);\n");
622 : }
623 72 : }
624 :
625 23 : void StringOneofFieldGenerator::
626 : GenerateSwappingCode(io::Printer* printer) const {
627 : // Don't print any swapping code. Swapping the union will swap this field.
628 23 : }
629 :
630 22 : void StringOneofFieldGenerator::
631 : GenerateConstructorCode(io::Printer* printer) const {
632 : printer->Print(variables_,
633 : " $classname$_default_oneof_instance_->$name$_.UnsafeSetDefault("
634 22 : "$default_variable$);\n");
635 22 : }
636 :
637 0 : void StringOneofFieldGenerator::
638 : GenerateDestructorCode(io::Printer* printer) const {
639 0 : if (SupportsArenas(descriptor_)) {
640 : printer->Print(variables_,
641 : "if (has_$name$()) {\n"
642 : " $oneof_prefix$$name$_.Destroy($default_variable$,\n"
643 : " GetArenaNoVirtual());\n"
644 0 : "}\n");
645 : } else {
646 : printer->Print(variables_,
647 : "if (has_$name$()) {\n"
648 : " $oneof_prefix$$name$_.DestroyNoArena($default_variable$);\n"
649 0 : "}\n");
650 : }
651 0 : }
652 :
653 23 : void StringOneofFieldGenerator::
654 : GenerateMergeFromCodedStream(io::Printer* printer) const {
655 : printer->Print(variables_,
656 : "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
657 23 : " input, this->mutable_$name$()));\n");
658 :
659 23 : if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
660 : GenerateUtf8CheckCodeForString(
661 : descriptor_, true, variables_,
662 16 : "this->$name$().data(), this->$name$().length(),\n", printer);
663 : }
664 23 : }
665 :
666 :
667 : // ===================================================================
668 :
669 38 : RepeatedStringFieldGenerator::
670 : RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
671 : const Options& options)
672 76 : : descriptor_(descriptor) {
673 38 : SetStringVariables(descriptor, &variables_, options);
674 38 : }
675 :
676 114 : RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
677 :
678 38 : void RepeatedStringFieldGenerator::
679 : GeneratePrivateMembers(io::Printer* printer) const {
680 : printer->Print(variables_,
681 38 : "::google::protobuf::RepeatedPtrField< ::std::string> $name$_;\n");
682 38 : }
683 :
684 38 : void RepeatedStringFieldGenerator::
685 : GenerateAccessorDeclarations(io::Printer* printer) const {
686 : // See comment above about unknown ctypes.
687 : bool unknown_ctype =
688 76 : descriptor_->options().ctype() != EffectiveStringCType(descriptor_);
689 :
690 38 : if (unknown_ctype) {
691 15 : printer->Outdent();
692 : printer->Print(
693 : " private:\n"
694 15 : " // Hidden due to unknown ctype option.\n");
695 15 : printer->Indent();
696 : }
697 :
698 : printer->Print(variables_,
699 : "const ::std::string& $name$(int index) const$deprecation$;\n"
700 : "::std::string* mutable_$name$(int index)$deprecation$;\n"
701 : "void set_$name$(int index, const ::std::string& value)$deprecation$;\n"
702 : "void set_$name$(int index, const char* value)$deprecation$;\n"
703 : ""
704 : "void set_$name$(int index, const $pointer_type$* value, size_t size)"
705 : "$deprecation$;\n"
706 : "::std::string* add_$name$()$deprecation$;\n"
707 : "void add_$name$(const ::std::string& value)$deprecation$;\n"
708 : "void add_$name$(const char* value)$deprecation$;\n"
709 : "void add_$name$(const $pointer_type$* value, size_t size)"
710 38 : "$deprecation$;\n");
711 :
712 : printer->Print(variables_,
713 : "const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const"
714 : "$deprecation$;\n"
715 : "::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()"
716 38 : "$deprecation$;\n");
717 :
718 38 : if (unknown_ctype) {
719 15 : printer->Outdent();
720 15 : printer->Print(" public:\n");
721 15 : printer->Indent();
722 : }
723 38 : }
724 :
725 76 : void RepeatedStringFieldGenerator::
726 : GenerateInlineAccessorDefinitions(io::Printer* printer,
727 : bool is_inline) const {
728 76 : map<string, string> variables(variables_);
729 152 : variables["inline"] = is_inline ? "inline" : "";
730 : printer->Print(variables,
731 : "$inline$ const ::std::string& $classname$::$name$(int index) const {\n"
732 : " // @@protoc_insertion_point(field_get:$full_name$)\n"
733 : " return $name$_.$cppget$(index);\n"
734 : "}\n"
735 : "$inline$ ::std::string* $classname$::mutable_$name$(int index) {\n"
736 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
737 : " return $name$_.Mutable(index);\n"
738 : "}\n"
739 : "$inline$ void $classname$::set_$name$(int index, const ::std::string& value) {\n"
740 : " // @@protoc_insertion_point(field_set:$full_name$)\n"
741 : " $name$_.Mutable(index)->assign(value);\n"
742 : "}\n"
743 : "$inline$ void $classname$::set_$name$(int index, const char* value) {\n"
744 : " $name$_.Mutable(index)->assign(value);\n"
745 : " // @@protoc_insertion_point(field_set_char:$full_name$)\n"
746 : "}\n"
747 : "$inline$ void "
748 : "$classname$::set_$name$"
749 : "(int index, const $pointer_type$* value, size_t size) {\n"
750 : " $name$_.Mutable(index)->assign(\n"
751 : " reinterpret_cast<const char*>(value), size);\n"
752 : " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
753 : "}\n"
754 : "$inline$ ::std::string* $classname$::add_$name$() {\n"
755 : " return $name$_.Add();\n"
756 : "}\n"
757 : "$inline$ void $classname$::add_$name$(const ::std::string& value) {\n"
758 : " $name$_.Add()->assign(value);\n"
759 : " // @@protoc_insertion_point(field_add:$full_name$)\n"
760 : "}\n"
761 : "$inline$ void $classname$::add_$name$(const char* value) {\n"
762 : " $name$_.Add()->assign(value);\n"
763 : " // @@protoc_insertion_point(field_add_char:$full_name$)\n"
764 : "}\n"
765 : "$inline$ void "
766 : "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
767 : " $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
768 : " // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
769 76 : "}\n");
770 : printer->Print(variables,
771 : "$inline$ const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
772 : "$classname$::$name$() const {\n"
773 : " // @@protoc_insertion_point(field_list:$full_name$)\n"
774 : " return $name$_;\n"
775 : "}\n"
776 : "$inline$ ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
777 : "$classname$::mutable_$name$() {\n"
778 : " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
779 : " return &$name$_;\n"
780 76 : "}\n");
781 76 : }
782 :
783 114 : void RepeatedStringFieldGenerator::
784 : GenerateClearingCode(io::Printer* printer) const {
785 114 : printer->Print(variables_, "$name$_.Clear();\n");
786 114 : }
787 :
788 38 : void RepeatedStringFieldGenerator::
789 : GenerateMergingCode(io::Printer* printer) const {
790 38 : printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
791 38 : }
792 :
793 38 : void RepeatedStringFieldGenerator::
794 : GenerateSwappingCode(io::Printer* printer) const {
795 38 : printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n");
796 38 : }
797 :
798 38 : void RepeatedStringFieldGenerator::
799 : GenerateConstructorCode(io::Printer* printer) const {
800 : // Not needed for repeated fields.
801 38 : }
802 :
803 38 : void RepeatedStringFieldGenerator::
804 : GenerateMergeFromCodedStream(io::Printer* printer) const {
805 : printer->Print(variables_,
806 : "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
807 38 : " input, this->add_$name$()));\n");
808 38 : if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
809 : GenerateUtf8CheckCodeForString(
810 : descriptor_, true, variables_,
811 : "this->$name$(this->$name$_size() - 1).data(),\n"
812 : "this->$name$(this->$name$_size() - 1).length(),\n",
813 30 : printer);
814 : }
815 38 : }
816 :
817 38 : void RepeatedStringFieldGenerator::
818 : GenerateSerializeWithCachedSizes(io::Printer* printer) const {
819 : printer->Print(variables_,
820 38 : "for (int i = 0; i < this->$name$_size(); i++) {\n");
821 38 : printer->Indent();
822 38 : if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
823 : GenerateUtf8CheckCodeForString(
824 : descriptor_, false, variables_,
825 30 : "this->$name$(i).data(), this->$name$(i).length(),\n", printer);
826 : }
827 38 : printer->Outdent();
828 : printer->Print(variables_,
829 : " ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
830 : " $number$, this->$name$(i), output);\n"
831 38 : "}\n");
832 38 : }
833 :
834 34 : void RepeatedStringFieldGenerator::
835 : GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
836 : printer->Print(variables_,
837 34 : "for (int i = 0; i < this->$name$_size(); i++) {\n");
838 34 : printer->Indent();
839 34 : if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
840 : GenerateUtf8CheckCodeForString(
841 : descriptor_, false, variables_,
842 27 : "this->$name$(i).data(), this->$name$(i).length(),\n", printer);
843 : }
844 34 : printer->Outdent();
845 : printer->Print(variables_,
846 : " target = ::google::protobuf::internal::WireFormatLite::\n"
847 : " Write$declared_type$ToArray($number$, this->$name$(i), target);\n"
848 34 : "}\n");
849 34 : }
850 :
851 38 : void RepeatedStringFieldGenerator::
852 : GenerateByteSize(io::Printer* printer) const {
853 : printer->Print(variables_,
854 : "total_size += $tag_size$ * this->$name$_size();\n"
855 : "for (int i = 0; i < this->$name$_size(); i++) {\n"
856 : " total_size += ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
857 : " this->$name$(i));\n"
858 38 : "}\n");
859 38 : }
860 :
861 : } // namespace cpp
862 : } // namespace compiler
863 : } // namespace protobuf
864 : } // namespace google
|