blob: 749897032ebb5ec97e94b8e4dd0e92a3bb792db4 [file] [log] [blame]
temporal40ee5512008-07-10 02:12:20 +00001// Protocol Buffers - Google's data interchange format
kenton@google.com24bf56f2008-09-24 20:31:01 +00002// Copyright 2008 Google Inc. All rights reserved.
Feng Xiaoe4288622014-10-01 16:26:23 -07003// https://developers.google.com/protocol-buffers/
temporal40ee5512008-07-10 02:12:20 +00004//
kenton@google.com24bf56f2008-09-24 20:31:01 +00005// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
temporal40ee5512008-07-10 02:12:20 +00008//
kenton@google.com24bf56f2008-09-24 20:31:01 +00009// * 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.
temporal40ee5512008-07-10 02:12:20 +000018//
kenton@google.com24bf56f2008-09-24 20:31:01 +000019// 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.
temporal40ee5512008-07-10 02:12:20 +000030
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_enum_field.h>
36#include <google/protobuf/compiler/cpp/cpp_helpers.h>
37#include <google/protobuf/io/printer.h>
kenton@google.com80b1d622009-07-29 01:13:20 +000038#include <google/protobuf/descriptor.pb.h>
temporal40ee5512008-07-10 02:12:20 +000039#include <google/protobuf/stubs/strutil.h>
40
41namespace google {
42namespace protobuf {
43namespace compiler {
44namespace cpp {
45
temporal40ee5512008-07-10 02:12:20 +000046namespace {
47
temporal40ee5512008-07-10 02:12:20 +000048void SetEnumVariables(const FieldDescriptor* descriptor,
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000049 map<string, string>* variables,
50 const Options& options) {
51 SetCommonFieldVariables(descriptor, variables, options);
temporal40ee5512008-07-10 02:12:20 +000052 const EnumValueDescriptor* default_value = descriptor->default_value_enum();
temporal40ee5512008-07-10 02:12:20 +000053 (*variables)["type"] = ClassName(descriptor->enum_type(), true);
jieluo@google.com4de8f552014-07-18 00:47:59 +000054 (*variables)["default"] = Int32ToString(default_value->number());
55 (*variables)["full_name"] = descriptor->full_name();
temporal40ee5512008-07-10 02:12:20 +000056}
57
58} // namespace
59
60// ===================================================================
61
62EnumFieldGenerator::
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000063EnumFieldGenerator(const FieldDescriptor* descriptor,
64 const Options& options)
temporal40ee5512008-07-10 02:12:20 +000065 : descriptor_(descriptor) {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000066 SetEnumVariables(descriptor, &variables_, options);
temporal40ee5512008-07-10 02:12:20 +000067}
68
69EnumFieldGenerator::~EnumFieldGenerator() {}
70
71void EnumFieldGenerator::
72GeneratePrivateMembers(io::Printer* printer) const {
73 printer->Print(variables_, "int $name$_;\n");
74}
75
76void EnumFieldGenerator::
77GenerateAccessorDeclarations(io::Printer* printer) const {
78 printer->Print(variables_,
Jisi Liu885b6122015-02-28 14:51:22 -080079 "$type$ $name$() const$deprecation$;\n"
80 "void set_$name$($type$ value)$deprecation$;\n");
temporal40ee5512008-07-10 02:12:20 +000081}
82
83void EnumFieldGenerator::
Jisi Liu885b6122015-02-28 14:51:22 -080084GenerateInlineAccessorDefinitions(io::Printer* printer,
85 bool is_inline) const {
86 map<string, string> variables(variables_);
87 variables["inline"] = is_inline ? "inline" : "";
88 printer->Print(variables,
89 "$inline$ $type$ $classname$::$name$() const {\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +000090 " // @@protoc_insertion_point(field_get:$full_name$)\n"
temporal40ee5512008-07-10 02:12:20 +000091 " return static_cast< $type$ >($name$_);\n"
92 "}\n"
Jisi Liu885b6122015-02-28 14:51:22 -080093 "$inline$ void $classname$::set_$name$($type$ value) {\n");
Feng Xiao6ef984a2014-11-10 17:34:54 -080094 if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
Jisi Liu885b6122015-02-28 14:51:22 -080095 printer->Print(variables,
Feng Xiao6ef984a2014-11-10 17:34:54 -080096 " assert($type$_IsValid(value));\n");
97 }
Jisi Liu885b6122015-02-28 14:51:22 -080098 printer->Print(variables,
Feng Xiao6ef984a2014-11-10 17:34:54 -080099 " $set_hasbit$\n"
temporal40ee5512008-07-10 02:12:20 +0000100 " $name$_ = value;\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000101 " // @@protoc_insertion_point(field_set:$full_name$)\n"
temporal40ee5512008-07-10 02:12:20 +0000102 "}\n");
103}
104
105void EnumFieldGenerator::
106GenerateClearingCode(io::Printer* printer) const {
107 printer->Print(variables_, "$name$_ = $default$;\n");
108}
109
110void EnumFieldGenerator::
111GenerateMergingCode(io::Printer* printer) const {
112 printer->Print(variables_, "set_$name$(from.$name$());\n");
113}
114
115void EnumFieldGenerator::
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000116GenerateSwappingCode(io::Printer* printer) const {
117 printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
118}
119
120void EnumFieldGenerator::
kenton@google.comd37d46d2009-04-25 02:53:47 +0000121GenerateConstructorCode(io::Printer* printer) const {
122 printer->Print(variables_, "$name$_ = $default$;\n");
temporal40ee5512008-07-10 02:12:20 +0000123}
124
125void EnumFieldGenerator::
126GenerateMergeFromCodedStream(io::Printer* printer) const {
127 printer->Print(variables_,
128 "int value;\n"
kenton@google.comfccb1462009-12-18 02:11:36 +0000129 "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
130 " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800131 " input, &value)));\n");
132 if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000133 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800134 "set_$name$(static_cast< $type$ >(value));\n");
jieluo@google.com4de8f552014-07-18 00:47:59 +0000135 } else {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800136 printer->Print(variables_,
137 "if ($type$_IsValid(value)) {\n"
138 " set_$name$(static_cast< $type$ >(value));\n");
139 if (UseUnknownFieldSet(descriptor_->file())) {
140 printer->Print(variables_,
141 "} else {\n"
142 " mutable_unknown_fields()->AddVarint($number$, value);\n");
143 } else {
144 printer->Print(
145 "} else {\n"
146 " unknown_fields_stream.WriteVarint32(tag);\n"
147 " unknown_fields_stream.WriteVarint32(value);\n");
148 }
149 printer->Print(variables_,
150 "}\n");
kenton@google.com80b1d622009-07-29 01:13:20 +0000151 }
temporal40ee5512008-07-10 02:12:20 +0000152}
153
154void EnumFieldGenerator::
155GenerateSerializeWithCachedSizes(io::Printer* printer) const {
156 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +0000157 "::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
158 " $number$, this->$name$(), output);\n");
kenton@google.comd37d46d2009-04-25 02:53:47 +0000159}
160
161void EnumFieldGenerator::
162GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
163 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +0000164 "target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
165 " $number$, this->$name$(), target);\n");
temporal40ee5512008-07-10 02:12:20 +0000166}
167
168void EnumFieldGenerator::
169GenerateByteSize(io::Printer* printer) const {
170 printer->Print(variables_,
171 "total_size += $tag_size$ +\n"
kenton@google.com80b1d622009-07-29 01:13:20 +0000172 " ::google::protobuf::internal::WireFormatLite::EnumSize(this->$name$());\n");
temporal40ee5512008-07-10 02:12:20 +0000173}
174
175// ===================================================================
176
jieluo@google.com4de8f552014-07-18 00:47:59 +0000177EnumOneofFieldGenerator::
178EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
179 const Options& options)
180 : EnumFieldGenerator(descriptor, options) {
181 SetCommonOneofFieldVariables(descriptor, &variables_);
182}
183
184EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {}
185
186void EnumOneofFieldGenerator::
Jisi Liu885b6122015-02-28 14:51:22 -0800187GenerateInlineAccessorDefinitions(io::Printer* printer,
188 bool is_inline) const {
189 map<string, string> variables(variables_);
190 variables["inline"] = is_inline ? "inline" : "";
191 printer->Print(variables,
192 "$inline$ $type$ $classname$::$name$() const {\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800193 " // @@protoc_insertion_point(field_get:$full_name$)\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000194 " if (has_$name$()) {\n"
195 " return static_cast< $type$ >($oneof_prefix$$name$_);\n"
196 " }\n"
197 " return static_cast< $type$ >($default$);\n"
198 "}\n"
Jisi Liu885b6122015-02-28 14:51:22 -0800199 "$inline$ void $classname$::set_$name$($type$ value) {\n");
Feng Xiao6ef984a2014-11-10 17:34:54 -0800200 if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
Jisi Liu885b6122015-02-28 14:51:22 -0800201 printer->Print(variables,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800202 " assert($type$_IsValid(value));\n");
203 }
Jisi Liu885b6122015-02-28 14:51:22 -0800204 printer->Print(variables,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000205 " if (!has_$name$()) {\n"
206 " clear_$oneof_name$();\n"
207 " set_has_$name$();\n"
208 " }\n"
209 " $oneof_prefix$$name$_ = value;\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800210 " // @@protoc_insertion_point(field_set:$full_name$)\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000211 "}\n");
212}
213
214void EnumOneofFieldGenerator::
215GenerateClearingCode(io::Printer* printer) const {
216 printer->Print(variables_, "$oneof_prefix$$name$_ = $default$;\n");
217}
218
219void EnumOneofFieldGenerator::
220GenerateSwappingCode(io::Printer* printer) const {
221 // Don't print any swapping code. Swapping the union will swap this field.
222}
223
224void EnumOneofFieldGenerator::
225GenerateConstructorCode(io::Printer* printer) const {
226 printer->Print(variables_,
227 " $classname$_default_oneof_instance_->$name$_ = $default$;\n");
228}
229
230// ===================================================================
231
temporal40ee5512008-07-10 02:12:20 +0000232RepeatedEnumFieldGenerator::
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000233RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
234 const Options& options)
temporal40ee5512008-07-10 02:12:20 +0000235 : descriptor_(descriptor) {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000236 SetEnumVariables(descriptor, &variables_, options);
temporal40ee5512008-07-10 02:12:20 +0000237}
238
239RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
240
241void RepeatedEnumFieldGenerator::
242GeneratePrivateMembers(io::Printer* printer) const {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000243 printer->Print(variables_,
244 "::google::protobuf::RepeatedField<int> $name$_;\n");
jieluo@google.com4de8f552014-07-18 00:47:59 +0000245 if (descriptor_->options().packed()
246 && HasGeneratedMethods(descriptor_->file())) {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000247 printer->Print(variables_,
248 "mutable int _$name$_cached_byte_size_;\n");
249 }
temporal40ee5512008-07-10 02:12:20 +0000250}
251
252void RepeatedEnumFieldGenerator::
253GenerateAccessorDeclarations(io::Printer* printer) const {
254 printer->Print(variables_,
Jisi Liu885b6122015-02-28 14:51:22 -0800255 "$type$ $name$(int index) const$deprecation$;\n"
256 "void set_$name$(int index, $type$ value)$deprecation$;\n"
257 "void add_$name$($type$ value)$deprecation$;\n");
kenton@google.comfccb1462009-12-18 02:11:36 +0000258 printer->Print(variables_,
Jisi Liu885b6122015-02-28 14:51:22 -0800259 "const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n"
260 "::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n");
temporal40ee5512008-07-10 02:12:20 +0000261}
262
263void RepeatedEnumFieldGenerator::
Jisi Liu885b6122015-02-28 14:51:22 -0800264GenerateInlineAccessorDefinitions(io::Printer* printer,
265 bool is_inline) const {
266 map<string, string> variables(variables_);
267 variables["inline"] = is_inline ? "inline" : "";
268 printer->Print(variables,
269 "$inline$ $type$ $classname$::$name$(int index) const {\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000270 " // @@protoc_insertion_point(field_get:$full_name$)\n"
temporal40ee5512008-07-10 02:12:20 +0000271 " return static_cast< $type$ >($name$_.Get(index));\n"
272 "}\n"
Jisi Liu885b6122015-02-28 14:51:22 -0800273 "$inline$ void $classname$::set_$name$(int index, $type$ value) {\n");
Feng Xiao6ef984a2014-11-10 17:34:54 -0800274 if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
Jisi Liu885b6122015-02-28 14:51:22 -0800275 printer->Print(variables,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800276 " assert($type$_IsValid(value));\n");
277 }
Jisi Liu885b6122015-02-28 14:51:22 -0800278 printer->Print(variables,
temporal40ee5512008-07-10 02:12:20 +0000279 " $name$_.Set(index, value);\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000280 " // @@protoc_insertion_point(field_set:$full_name$)\n"
temporal40ee5512008-07-10 02:12:20 +0000281 "}\n"
Jisi Liu885b6122015-02-28 14:51:22 -0800282 "$inline$ void $classname$::add_$name$($type$ value) {\n");
Feng Xiao6ef984a2014-11-10 17:34:54 -0800283 if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
Jisi Liu885b6122015-02-28 14:51:22 -0800284 printer->Print(variables,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800285 " assert($type$_IsValid(value));\n");
286 }
Jisi Liu885b6122015-02-28 14:51:22 -0800287 printer->Print(variables,
temporal40ee5512008-07-10 02:12:20 +0000288 " $name$_.Add(value);\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000289 " // @@protoc_insertion_point(field_add:$full_name$)\n"
temporal40ee5512008-07-10 02:12:20 +0000290 "}\n");
Jisi Liu885b6122015-02-28 14:51:22 -0800291 printer->Print(variables,
292 "$inline$ const ::google::protobuf::RepeatedField<int>&\n"
kenton@google.comfccb1462009-12-18 02:11:36 +0000293 "$classname$::$name$() const {\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000294 " // @@protoc_insertion_point(field_list:$full_name$)\n"
kenton@google.comfccb1462009-12-18 02:11:36 +0000295 " return $name$_;\n"
296 "}\n"
Jisi Liu885b6122015-02-28 14:51:22 -0800297 "$inline$ ::google::protobuf::RepeatedField<int>*\n"
kenton@google.comfccb1462009-12-18 02:11:36 +0000298 "$classname$::mutable_$name$() {\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000299 " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
kenton@google.comfccb1462009-12-18 02:11:36 +0000300 " return &$name$_;\n"
301 "}\n");
temporal40ee5512008-07-10 02:12:20 +0000302}
303
304void RepeatedEnumFieldGenerator::
305GenerateClearingCode(io::Printer* printer) const {
306 printer->Print(variables_, "$name$_.Clear();\n");
307}
308
309void RepeatedEnumFieldGenerator::
310GenerateMergingCode(io::Printer* printer) const {
311 printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
312}
313
314void RepeatedEnumFieldGenerator::
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000315GenerateSwappingCode(io::Printer* printer) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800316 printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n");
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000317}
318
319void RepeatedEnumFieldGenerator::
kenton@google.comd37d46d2009-04-25 02:53:47 +0000320GenerateConstructorCode(io::Printer* printer) const {
321 // Not needed for repeated fields.
temporal40ee5512008-07-10 02:12:20 +0000322}
323
324void RepeatedEnumFieldGenerator::
325GenerateMergeFromCodedStream(io::Printer* printer) const {
kenton@google.comfccb1462009-12-18 02:11:36 +0000326 // Don't use ReadRepeatedPrimitive here so that the enum can be validated.
327 printer->Print(variables_,
328 "int value;\n"
329 "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
330 " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800331 " input, &value)));\n");
332 if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
kenton@google.comfccb1462009-12-18 02:11:36 +0000333 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800334 "add_$name$(static_cast< $type$ >(value));\n");
jieluo@google.com4de8f552014-07-18 00:47:59 +0000335 } else {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800336 printer->Print(variables_,
337 "if ($type$_IsValid(value)) {\n"
338 " add_$name$(static_cast< $type$ >(value));\n");
339 if (UseUnknownFieldSet(descriptor_->file())) {
340 printer->Print(variables_,
341 "} else {\n"
342 " mutable_unknown_fields()->AddVarint($number$, value);\n");
343 } else {
344 printer->Print(
345 "} else {\n"
346 " unknown_fields_stream.WriteVarint32(tag);\n"
347 " unknown_fields_stream.WriteVarint32(value);\n");
348 }
349 printer->Print("}\n");
kenton@google.comfccb1462009-12-18 02:11:36 +0000350 }
kenton@google.comfccb1462009-12-18 02:11:36 +0000351}
352
353void RepeatedEnumFieldGenerator::
354GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
355 if (!descriptor_->options().packed()) {
Jisi Liu885b6122015-02-28 14:51:22 -0800356 // This path is rarely executed, so we use a non-inlined implementation.
Feng Xiao6ef984a2014-11-10 17:34:54 -0800357 if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
358 printer->Print(variables_,
Jisi Liu885b6122015-02-28 14:51:22 -0800359 "DO_((::google::protobuf::internal::"
360 "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n"
361 " input,\n"
362 " $number$,\n"
363 " NULL,\n"
364 " NULL,\n"
365 " this->mutable_$name$())));\n");
366 } else if (UseUnknownFieldSet(descriptor_->file())) {
367 printer->Print(variables_,
368 "DO_((::google::protobuf::internal::WireFormat::ReadPackedEnumPreserveUnknowns(\n"
369 " input,\n"
370 " $number$,\n"
371 " $type$_IsValid,\n"
372 " mutable_unknown_fields(),\n"
373 " this->mutable_$name$())));\n");
Feng Xiao6ef984a2014-11-10 17:34:54 -0800374 } else {
375 printer->Print(variables_,
Jisi Liu885b6122015-02-28 14:51:22 -0800376 "DO_((::google::protobuf::internal::"
377 "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n"
378 " input,\n"
379 " $number$,\n"
380 " $type$_IsValid,\n"
381 " &unknown_fields_stream,\n"
382 " this->mutable_$name$())));\n");
Feng Xiao6ef984a2014-11-10 17:34:54 -0800383 }
kenton@google.comfccb1462009-12-18 02:11:36 +0000384 } else {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000385 printer->Print(variables_,
386 "::google::protobuf::uint32 length;\n"
387 "DO_(input->ReadVarint32(&length));\n"
388 "::google::protobuf::io::CodedInputStream::Limit limit = "
389 "input->PushLimit(length);\n"
390 "while (input->BytesUntilLimit() > 0) {\n"
391 " int value;\n"
kenton@google.comfccb1462009-12-18 02:11:36 +0000392 " DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
393 " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800394 " input, &value)));\n");
395 if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
396 printer->Print(variables_,
397 " add_$name$(static_cast< $type$ >(value));\n");
398 } else {
399 printer->Print(variables_,
kenton@google.com2d6daa72009-01-22 01:27:00 +0000400 " if ($type$_IsValid(value)) {\n"
401 " add_$name$(static_cast< $type$ >(value));\n"
Jisi Liu885b6122015-02-28 14:51:22 -0800402 " } else {\n");
403 if (UseUnknownFieldSet(descriptor_->file())) {
404 printer->Print(variables_,
405 " mutable_unknown_fields()->AddVarint($number$, value);\n");
406 } else {
407 printer->Print(variables_,
408 " unknown_fields_stream.WriteVarint32(tag);\n"
409 " unknown_fields_stream.WriteVarint32(value);\n");
410 }
411 printer->Print(
Feng Xiao6ef984a2014-11-10 17:34:54 -0800412 " }\n");
413 }
414 printer->Print(variables_,
kenton@google.com2d6daa72009-01-22 01:27:00 +0000415 "}\n"
416 "input->PopLimit(limit);\n");
kenton@google.com2d6daa72009-01-22 01:27:00 +0000417 }
temporal40ee5512008-07-10 02:12:20 +0000418}
419
420void RepeatedEnumFieldGenerator::
421GenerateSerializeWithCachedSizes(io::Printer* printer) const {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000422 if (descriptor_->options().packed()) {
423 // Write the tag and the size.
424 printer->Print(variables_,
425 "if (this->$name$_size() > 0) {\n"
kenton@google.com80b1d622009-07-29 01:13:20 +0000426 " ::google::protobuf::internal::WireFormatLite::WriteTag(\n"
427 " $number$,\n"
428 " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
429 " output);\n"
kenton@google.comd37d46d2009-04-25 02:53:47 +0000430 " output->WriteVarint32(_$name$_cached_byte_size_);\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000431 "}\n");
432 }
temporal40ee5512008-07-10 02:12:20 +0000433 printer->Print(variables_,
kenton@google.com2d6daa72009-01-22 01:27:00 +0000434 "for (int i = 0; i < this->$name$_size(); i++) {\n");
435 if (descriptor_->options().packed()) {
436 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +0000437 " ::google::protobuf::internal::WireFormatLite::WriteEnumNoTag(\n"
438 " this->$name$(i), output);\n");
kenton@google.com2d6daa72009-01-22 01:27:00 +0000439 } else {
440 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +0000441 " ::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
442 " $number$, this->$name$(i), output);\n");
kenton@google.comd37d46d2009-04-25 02:53:47 +0000443 }
444 printer->Print("}\n");
445}
446
447void RepeatedEnumFieldGenerator::
448GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
449 if (descriptor_->options().packed()) {
450 // Write the tag and the size.
451 printer->Print(variables_,
452 "if (this->$name$_size() > 0) {\n"
kenton@google.com80b1d622009-07-29 01:13:20 +0000453 " target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
454 " $number$,\n"
455 " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
456 " target);\n"
kenton@google.comd37d46d2009-04-25 02:53:47 +0000457 " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray("
kenton@google.com80b1d622009-07-29 01:13:20 +0000458 " _$name$_cached_byte_size_, target);\n"
kenton@google.comd37d46d2009-04-25 02:53:47 +0000459 "}\n");
460 }
461 printer->Print(variables_,
462 "for (int i = 0; i < this->$name$_size(); i++) {\n");
463 if (descriptor_->options().packed()) {
464 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +0000465 " target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n"
466 " this->$name$(i), target);\n");
kenton@google.comd37d46d2009-04-25 02:53:47 +0000467 } else {
468 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +0000469 " target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
470 " $number$, this->$name$(i), target);\n");
kenton@google.com2d6daa72009-01-22 01:27:00 +0000471 }
472 printer->Print("}\n");
temporal40ee5512008-07-10 02:12:20 +0000473}
474
475void RepeatedEnumFieldGenerator::
476GenerateByteSize(io::Printer* printer) const {
477 printer->Print(variables_,
kenton@google.com2d6daa72009-01-22 01:27:00 +0000478 "{\n"
479 " int data_size = 0;\n");
480 printer->Indent();
481 printer->Print(variables_,
482 "for (int i = 0; i < this->$name$_size(); i++) {\n"
kenton@google.com80b1d622009-07-29 01:13:20 +0000483 " data_size += ::google::protobuf::internal::WireFormatLite::EnumSize(\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000484 " this->$name$(i));\n"
485 "}\n");
486
487 if (descriptor_->options().packed()) {
488 printer->Print(variables_,
489 "if (data_size > 0) {\n"
kenton@google.com80b1d622009-07-29 01:13:20 +0000490 " total_size += $tag_size$ +\n"
491 " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000492 "}\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000493 "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000494 "_$name$_cached_byte_size_ = data_size;\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000495 "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000496 "total_size += data_size;\n");
497 } else {
498 printer->Print(variables_,
499 "total_size += $tag_size$ * this->$name$_size() + data_size;\n");
500 }
501 printer->Outdent();
502 printer->Print("}\n");
temporal40ee5512008-07-10 02:12:20 +0000503}
504
505} // namespace cpp
506} // namespace compiler
507} // namespace protobuf
508} // namespace google