Initial import of v2.0.0beta
[protobuf.git] / src / google / protobuf / compiler / cpp / cpp_message_field.cc
blob501ca569061b167d52de808fa66c096f543952c3
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.
3 // http://code.google.com/p/protobuf/
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
17 // Author: kenton@google.com (Kenton Varda)
18 // Based on original Protocol Buffers design by
19 // Sanjay Ghemawat, Jeff Dean, and others.
21 #include <google/protobuf/compiler/cpp/cpp_message_field.h>
22 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
23 #include <google/protobuf/io/printer.h>
24 #include <google/protobuf/wire_format_inl.h>
25 #include <google/protobuf/stubs/strutil.h>
27 namespace google {
28 namespace protobuf {
29 namespace compiler {
30 namespace cpp {
32 using internal::WireFormat;
34 namespace {
36 // TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
37 // repeat code between this and the other field types.
38 void SetMessageVariables(const FieldDescriptor* descriptor,
39 map<string, string>* variables) {
40 (*variables)["name"] = FieldName(descriptor);
41 (*variables)["type"] = ClassName(descriptor->message_type(), true);
42 (*variables)["index"] = SimpleItoa(descriptor->index());
43 (*variables)["number"] = SimpleItoa(descriptor->number());
44 (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
45 (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
46 (*variables)["tag_size"] = SimpleItoa(
47 WireFormat::TagSize(descriptor->number(), descriptor->type()));
50 } // namespace
52 // ===================================================================
54 MessageFieldGenerator::
55 MessageFieldGenerator(const FieldDescriptor* descriptor)
56 : descriptor_(descriptor) {
57 SetMessageVariables(descriptor, &variables_);
60 MessageFieldGenerator::~MessageFieldGenerator() {}
62 void MessageFieldGenerator::
63 GeneratePrivateMembers(io::Printer* printer) const {
64 printer->Print(variables_, "$type$* $name$_;\n");
67 void MessageFieldGenerator::
68 GenerateAccessorDeclarations(io::Printer* printer) const {
69 printer->Print(variables_,
70 "inline const $type$& $name$() const;\n"
71 "inline $type$* mutable_$name$();\n");
74 void MessageFieldGenerator::
75 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
76 printer->Print(variables_,
77 "inline const $type$& $classname$::$name$() const {\n"
78 " return $name$_ != NULL ? *$name$_ : *default_instance_.$name$_;\n"
79 "}\n"
80 "inline $type$* $classname$::mutable_$name$() {\n"
81 " _set_bit($index$);\n"
82 " if ($name$_ == NULL) $name$_ = new $type$;\n"
83 " return $name$_;\n"
84 "}\n");
87 void MessageFieldGenerator::
88 GenerateClearingCode(io::Printer* printer) const {
89 printer->Print(variables_,
90 "if ($name$_ != NULL) $name$_->$type$::Clear();\n");
93 void MessageFieldGenerator::
94 GenerateMergingCode(io::Printer* printer) const {
95 printer->Print(variables_,
96 "mutable_$name$()->$type$::MergeFrom(from.$name$());\n");
99 void MessageFieldGenerator::
100 GenerateInitializer(io::Printer* printer) const {
101 printer->Print(variables_, ",\n$name$_(NULL)");
104 void MessageFieldGenerator::
105 GenerateMergeFromCodedStream(io::Printer* printer) const {
106 if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
107 printer->Print(variables_,
108 "DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(\n"
109 " input, mutable_$name$()));\n");
110 } else {
111 printer->Print(variables_,
112 "DO_(::google::protobuf::internal::WireFormat::ReadGroupNoVirtual("
113 "$number$, input, mutable_$name$()));\n");
117 void MessageFieldGenerator::
118 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
119 printer->Print(variables_,
120 "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$NoVirtual("
121 "$number$, this->$name$(), output));\n");
124 void MessageFieldGenerator::
125 GenerateByteSize(io::Printer* printer) const {
126 printer->Print(variables_,
127 "total_size += $tag_size$ +\n"
128 " ::google::protobuf::internal::WireFormat::$declared_type$SizeNoVirtual(\n"
129 " this->$name$());\n");
132 // ===================================================================
134 RepeatedMessageFieldGenerator::
135 RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor)
136 : descriptor_(descriptor) {
137 SetMessageVariables(descriptor, &variables_);
140 RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
142 void RepeatedMessageFieldGenerator::
143 GeneratePrivateMembers(io::Printer* printer) const {
144 printer->Print(variables_,
145 "::google::protobuf::RepeatedPtrField< $type$ > $name$_;\n");
148 void RepeatedMessageFieldGenerator::
149 GenerateAccessorDeclarations(io::Printer* printer) const {
150 printer->Print(variables_,
151 "inline const ::google::protobuf::RepeatedPtrField< $type$ >& $name$() const;\n"
152 "inline ::google::protobuf::RepeatedPtrField< $type$ >* mutable_$name$();\n"
153 "inline const $type$& $name$(int index) const;\n"
154 "inline $type$* mutable_$name$(int index);\n"
155 "inline $type$* add_$name$();\n");
158 void RepeatedMessageFieldGenerator::
159 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
160 printer->Print(variables_,
161 "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
162 "$classname$::$name$() const {\n"
163 " return $name$_;\n"
164 "}\n"
165 "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
166 "$classname$::mutable_$name$() {\n"
167 " return &$name$_;\n"
168 "}\n"
169 "inline const $type$& $classname$::$name$(int index) const {\n"
170 " return $name$_.Get(index);\n"
171 "}\n"
172 "inline $type$* $classname$::mutable_$name$(int index) {\n"
173 " return $name$_.Mutable(index);\n"
174 "}\n"
175 "inline $type$* $classname$::add_$name$() {\n"
176 " return $name$_.Add();\n"
177 "}\n");
180 void RepeatedMessageFieldGenerator::
181 GenerateClearingCode(io::Printer* printer) const {
182 printer->Print(variables_, "$name$_.Clear();\n");
185 void RepeatedMessageFieldGenerator::
186 GenerateMergingCode(io::Printer* printer) const {
187 printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
190 void RepeatedMessageFieldGenerator::
191 GenerateInitializer(io::Printer* printer) const {
192 // Not needed for repeated fields.
195 void RepeatedMessageFieldGenerator::
196 GenerateMergeFromCodedStream(io::Printer* printer) const {
197 if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
198 printer->Print(variables_,
199 "DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(\n"
200 " input, add_$name$()));\n");
201 } else {
202 printer->Print(variables_,
203 "DO_(::google::protobuf::internal::WireFormat::ReadGroupNoVirtual("
204 "$number$, input, add_$name$()));\n");
208 void RepeatedMessageFieldGenerator::
209 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
210 printer->Print(variables_,
211 "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$NoVirtual("
212 "$number$, this->$name$(i), output));\n");
215 void RepeatedMessageFieldGenerator::
216 GenerateByteSize(io::Printer* printer) const {
217 printer->Print(variables_,
218 "total_size += $tag_size$ * $name$_size();\n"
219 "for (int i = 0; i < $name$_size(); i++) {\n"
220 " total_size +=\n"
221 " ::google::protobuf::internal::WireFormat::$declared_type$SizeNoVirtual(\n"
222 " this->$name$(i));\n"
223 "}\n");
226 } // namespace cpp
227 } // namespace compiler
228 } // namespace protobuf
229 } // namespace google