blob: 23e75b87d42c5c5ef7213f8f7e9222fc7e980ccf [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.
temporal40ee5512008-07-10 02:12:20 +00003// http://code.google.com/p/protobuf/
4//
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_message_field.h>
36#include <google/protobuf/compiler/cpp/cpp_helpers.h>
37#include <google/protobuf/io/printer.h>
temporal40ee5512008-07-10 02:12:20 +000038#include <google/protobuf/stubs/strutil.h>
39
40namespace google {
41namespace protobuf {
42namespace compiler {
43namespace cpp {
44
temporal40ee5512008-07-10 02:12:20 +000045namespace {
46
temporal40ee5512008-07-10 02:12:20 +000047void SetMessageVariables(const FieldDescriptor* descriptor,
48 map<string, string>* variables) {
kenton@google.com80b1d622009-07-29 01:13:20 +000049 SetCommonFieldVariables(descriptor, variables);
kenton@google.comfccb1462009-12-18 02:11:36 +000050 (*variables)["type"] = FieldMessageTypeName(descriptor);
51 (*variables)["stream_writer"] = (*variables)["declared_type"] +
52 (HasFastArraySerialization(descriptor->message_type()->file()) ?
53 "MaybeToArray" :
54 "");
temporal40ee5512008-07-10 02:12:20 +000055}
56
57} // namespace
58
59// ===================================================================
60
61MessageFieldGenerator::
62MessageFieldGenerator(const FieldDescriptor* descriptor)
63 : descriptor_(descriptor) {
64 SetMessageVariables(descriptor, &variables_);
65}
66
67MessageFieldGenerator::~MessageFieldGenerator() {}
68
69void MessageFieldGenerator::
70GeneratePrivateMembers(io::Printer* printer) const {
71 printer->Print(variables_, "$type$* $name$_;\n");
72}
73
74void MessageFieldGenerator::
75GenerateAccessorDeclarations(io::Printer* printer) const {
76 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +000077 "inline const $type$& $name$() const$deprecation$;\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +000078 "inline $type$* mutable_$name$()$deprecation$;\n"
79 "inline $type$* release_$name$()$deprecation$;\n");
temporal40ee5512008-07-10 02:12:20 +000080}
81
82void MessageFieldGenerator::
83GenerateInlineAccessorDefinitions(io::Printer* printer) const {
84 printer->Print(variables_,
85 "inline const $type$& $classname$::$name$() const {\n"
kenton@google.com24bf56f2008-09-24 20:31:01 +000086 " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n"
temporal40ee5512008-07-10 02:12:20 +000087 "}\n"
88 "inline $type$* $classname$::mutable_$name$() {\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +000089 " set_has_$name$();\n"
temporal40ee5512008-07-10 02:12:20 +000090 " if ($name$_ == NULL) $name$_ = new $type$;\n"
91 " return $name$_;\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +000092 "}\n"
93 "inline $type$* $classname$::release_$name$() {\n"
94 " clear_has_$name$();\n"
95 " $type$* temp = $name$_;\n"
96 " $name$_ = NULL;\n"
97 " return temp;\n"
temporal40ee5512008-07-10 02:12:20 +000098 "}\n");
99}
100
101void MessageFieldGenerator::
102GenerateClearingCode(io::Printer* printer) const {
103 printer->Print(variables_,
104 "if ($name$_ != NULL) $name$_->$type$::Clear();\n");
105}
106
107void MessageFieldGenerator::
108GenerateMergingCode(io::Printer* printer) const {
109 printer->Print(variables_,
110 "mutable_$name$()->$type$::MergeFrom(from.$name$());\n");
111}
112
113void MessageFieldGenerator::
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000114GenerateSwappingCode(io::Printer* printer) const {
115 printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
116}
117
118void MessageFieldGenerator::
kenton@google.comd37d46d2009-04-25 02:53:47 +0000119GenerateConstructorCode(io::Printer* printer) const {
120 printer->Print(variables_, "$name$_ = NULL;\n");
temporal40ee5512008-07-10 02:12:20 +0000121}
122
123void MessageFieldGenerator::
124GenerateMergeFromCodedStream(io::Printer* printer) const {
125 if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
126 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +0000127 "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
temporal40ee5512008-07-10 02:12:20 +0000128 " input, mutable_$name$()));\n");
129 } else {
130 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +0000131 "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n"
132 " $number$, input, mutable_$name$()));\n");
temporal40ee5512008-07-10 02:12:20 +0000133 }
134}
135
136void MessageFieldGenerator::
137GenerateSerializeWithCachedSizes(io::Printer* printer) const {
138 printer->Print(variables_,
kenton@google.comfccb1462009-12-18 02:11:36 +0000139 "::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
kenton@google.com80b1d622009-07-29 01:13:20 +0000140 " $number$, this->$name$(), output);\n");
kenton@google.comd37d46d2009-04-25 02:53:47 +0000141}
142
143void MessageFieldGenerator::
144GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
145 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +0000146 "target = ::google::protobuf::internal::WireFormatLite::\n"
147 " Write$declared_type$NoVirtualToArray(\n"
148 " $number$, this->$name$(), target);\n");
temporal40ee5512008-07-10 02:12:20 +0000149}
150
151void MessageFieldGenerator::
152GenerateByteSize(io::Printer* printer) const {
153 printer->Print(variables_,
154 "total_size += $tag_size$ +\n"
kenton@google.com80b1d622009-07-29 01:13:20 +0000155 " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
temporal40ee5512008-07-10 02:12:20 +0000156 " this->$name$());\n");
157}
158
159// ===================================================================
160
161RepeatedMessageFieldGenerator::
162RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor)
163 : descriptor_(descriptor) {
164 SetMessageVariables(descriptor, &variables_);
165}
166
167RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
168
169void RepeatedMessageFieldGenerator::
170GeneratePrivateMembers(io::Printer* printer) const {
171 printer->Print(variables_,
172 "::google::protobuf::RepeatedPtrField< $type$ > $name$_;\n");
173}
174
175void RepeatedMessageFieldGenerator::
176GenerateAccessorDeclarations(io::Printer* printer) const {
177 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +0000178 "inline const $type$& $name$(int index) const$deprecation$;\n"
179 "inline $type$* mutable_$name$(int index)$deprecation$;\n"
180 "inline $type$* add_$name$()$deprecation$;\n");
kenton@google.comfccb1462009-12-18 02:11:36 +0000181 printer->Print(variables_,
182 "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
183 " $name$() const$deprecation$;\n"
184 "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
185 " mutable_$name$()$deprecation$;\n");
temporal40ee5512008-07-10 02:12:20 +0000186}
187
188void RepeatedMessageFieldGenerator::
189GenerateInlineAccessorDefinitions(io::Printer* printer) const {
190 printer->Print(variables_,
temporal40ee5512008-07-10 02:12:20 +0000191 "inline const $type$& $classname$::$name$(int index) const {\n"
192 " return $name$_.Get(index);\n"
193 "}\n"
194 "inline $type$* $classname$::mutable_$name$(int index) {\n"
195 " return $name$_.Mutable(index);\n"
196 "}\n"
197 "inline $type$* $classname$::add_$name$() {\n"
198 " return $name$_.Add();\n"
199 "}\n");
kenton@google.comfccb1462009-12-18 02:11:36 +0000200 printer->Print(variables_,
201 "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
202 "$classname$::$name$() const {\n"
203 " return $name$_;\n"
204 "}\n"
205 "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
206 "$classname$::mutable_$name$() {\n"
207 " return &$name$_;\n"
208 "}\n");
temporal40ee5512008-07-10 02:12:20 +0000209}
210
211void RepeatedMessageFieldGenerator::
212GenerateClearingCode(io::Printer* printer) const {
213 printer->Print(variables_, "$name$_.Clear();\n");
214}
215
216void RepeatedMessageFieldGenerator::
217GenerateMergingCode(io::Printer* printer) const {
218 printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
219}
220
221void RepeatedMessageFieldGenerator::
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000222GenerateSwappingCode(io::Printer* printer) const {
223 printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
224}
225
226void RepeatedMessageFieldGenerator::
kenton@google.comd37d46d2009-04-25 02:53:47 +0000227GenerateConstructorCode(io::Printer* printer) const {
228 // Not needed for repeated fields.
temporal40ee5512008-07-10 02:12:20 +0000229}
230
231void RepeatedMessageFieldGenerator::
232GenerateMergeFromCodedStream(io::Printer* printer) const {
233 if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
234 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +0000235 "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
236 " input, add_$name$()));\n");
temporal40ee5512008-07-10 02:12:20 +0000237 } else {
238 printer->Print(variables_,
kenton@google.com80b1d622009-07-29 01:13:20 +0000239 "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n"
240 " $number$, input, add_$name$()));\n");
temporal40ee5512008-07-10 02:12:20 +0000241 }
242}
243
244void RepeatedMessageFieldGenerator::
245GenerateSerializeWithCachedSizes(io::Printer* printer) const {
246 printer->Print(variables_,
kenton@google.com2d6daa72009-01-22 01:27:00 +0000247 "for (int i = 0; i < this->$name$_size(); i++) {\n"
kenton@google.comfccb1462009-12-18 02:11:36 +0000248 " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
kenton@google.com80b1d622009-07-29 01:13:20 +0000249 " $number$, this->$name$(i), output);\n"
kenton@google.comd37d46d2009-04-25 02:53:47 +0000250 "}\n");
251}
252
253void RepeatedMessageFieldGenerator::
254GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
255 printer->Print(variables_,
256 "for (int i = 0; i < this->$name$_size(); i++) {\n"
kenton@google.com80b1d622009-07-29 01:13:20 +0000257 " target = ::google::protobuf::internal::WireFormatLite::\n"
258 " Write$declared_type$NoVirtualToArray(\n"
259 " $number$, this->$name$(i), target);\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000260 "}\n");
temporal40ee5512008-07-10 02:12:20 +0000261}
262
263void RepeatedMessageFieldGenerator::
264GenerateByteSize(io::Printer* printer) const {
265 printer->Print(variables_,
kenton@google.com2d6daa72009-01-22 01:27:00 +0000266 "total_size += $tag_size$ * this->$name$_size();\n"
267 "for (int i = 0; i < this->$name$_size(); i++) {\n"
temporal40ee5512008-07-10 02:12:20 +0000268 " total_size +=\n"
kenton@google.com80b1d622009-07-29 01:13:20 +0000269 " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
temporal40ee5512008-07-10 02:12:20 +0000270 " this->$name$(i));\n"
271 "}\n");
272}
273
274} // namespace cpp
275} // namespace compiler
276} // namespace protobuf
277} // namespace google