1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.
3 // http://code.google.com/p/protobuf/
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
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>
32 using internal::WireFormat
;
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()));
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"
80 "inline $type$* $classname$::mutable_$name$() {\n"
81 " _set_bit($index$);\n"
82 " if ($name$_ == NULL) $name$_ = new $type$;\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");
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"
165 "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
166 "$classname$::mutable_$name$() {\n"
167 " return &$name$_;\n"
169 "inline const $type$& $classname$::$name$(int index) const {\n"
170 " return $name$_.Get(index);\n"
172 "inline $type$* $classname$::mutable_$name$(int index) {\n"
173 " return $name$_.Mutable(index);\n"
175 "inline $type$* $classname$::add_$name$() {\n"
176 " return $name$_.Add();\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");
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"
221 " ::google::protobuf::internal::WireFormat::$declared_type$SizeNoVirtual(\n"
222 " this->$name$(i));\n"
227 } // namespace compiler
228 } // namespace protobuf
229 } // namespace google