Initial import of v2.0.0beta
[protobuf.git] / src / google / protobuf / compiler / cpp / cpp_string_field.cc
blobde59ac8735a7aafae25b27652fef4e971fea705a
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_string_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/descriptor.pb.h>
26 #include <google/protobuf/stubs/strutil.h>
28 namespace google {
29 namespace protobuf {
30 namespace compiler {
31 namespace cpp {
33 using internal::WireFormat;
35 namespace {
37 // TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
38 // repeat code between this and the other field types.
39 void SetStringVariables(const FieldDescriptor* descriptor,
40 map<string, string>* variables) {
41 (*variables)["name"] = FieldName(descriptor);
42 (*variables)["default"] =
43 "\"" + CEscape(descriptor->default_value_string()) + "\"";
44 (*variables)["index"] = SimpleItoa(descriptor->index());
45 (*variables)["number"] = SimpleItoa(descriptor->number());
46 (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
47 (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
48 (*variables)["tag_size"] = SimpleItoa(
49 WireFormat::TagSize(descriptor->number(), descriptor->type()));
52 } // namespace
54 // ===================================================================
56 StringFieldGenerator::
57 StringFieldGenerator(const FieldDescriptor* descriptor)
58 : descriptor_(descriptor) {
59 SetStringVariables(descriptor, &variables_);
62 StringFieldGenerator::~StringFieldGenerator() {}
64 void StringFieldGenerator::
65 GeneratePrivateMembers(io::Printer* printer) const {
66 printer->Print(variables_,
67 "::std::string* $name$_;\n"
68 "static const ::std::string _default_$name$_;\n");
71 void StringFieldGenerator::
72 GenerateAccessorDeclarations(io::Printer* printer) const {
73 // If we're using StringFieldGenerator for a field with a ctype, it's
74 // because that ctype isn't actually implemented. In particular, this is
75 // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
76 // We aren't releasing Cord because it has too many Google-specific
77 // dependencies and we aren't releasing StringPiece because it's hardly
78 // useful outside of Google and because it would get confusing to have
79 // multiple instances of the StringPiece class in different libraries (PCRE
80 // already includes it for their C++ bindings, which came from Google).
82 // In any case, we make all the accessors private while still actually
83 // using a string to represent the field internally. This way, we can
84 // guarantee that if we do ever implement the ctype, it won't break any
85 // existing users who might be -- for whatever reason -- already using .proto
86 // files that applied the ctype. The field can still be accessed via the
87 // reflection interface since the reflection interface is independent of
88 // the string's underlying representation.
89 if (descriptor_->options().has_ctype()) {
90 printer->Outdent();
91 printer->Print(
92 " private:\n"
93 " // Hidden due to unknown ctype option.\n");
94 printer->Indent();
97 printer->Print(variables_,
98 "inline const ::std::string& $name$() const;\n"
99 "inline void set_$name$(const ::std::string& value);\n"
100 "inline void set_$name$(const char* value);\n");
102 printer->Print(variables_,
103 "inline ::std::string* mutable_$name$();\n");
105 if (descriptor_->options().has_ctype()) {
106 printer->Outdent();
107 printer->Print(" public:\n");
108 printer->Indent();
112 void StringFieldGenerator::
113 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
114 printer->Print(variables_,
115 "inline const ::std::string& $classname$::$name$() const {\n"
116 " return *$name$_;\n"
117 "}\n"
118 "inline void $classname$::set_$name$(const ::std::string& value) {\n"
119 " _set_bit($index$);\n"
120 " if ($name$_ == &_default_$name$_) {\n"
121 " $name$_ = new ::std::string;\n"
122 " }\n"
123 " $name$_->assign(value);\n"
124 "}\n"
125 "inline void $classname$::set_$name$(const char* value) {\n"
126 " _set_bit($index$);\n"
127 " if ($name$_ == &_default_$name$_) {\n"
128 " $name$_ = new ::std::string;\n"
129 " }\n"
130 " $name$_->assign(value);\n"
131 "}\n");
132 printer->Print(variables_,
133 "inline ::std::string* $classname$::mutable_$name$() {\n"
134 " _set_bit($index$);\n"
135 " if ($name$_ == &_default_$name$_) {\n");
136 if (descriptor_->has_default_value()) {
137 printer->Print(variables_,
138 " $name$_ = new ::std::string(_default_$name$_);\n");
139 } else {
140 printer->Print(variables_,
141 " $name$_ = new ::std::string;\n");
143 printer->Print(variables_,
144 " }\n"
145 " return $name$_;\n"
146 "}\n");
149 void StringFieldGenerator::
150 GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
151 if (descriptor_->has_default_value()) {
152 printer->Print(variables_,
153 "const ::std::string $classname$::_default_$name$_($default$);");
154 } else {
155 printer->Print(variables_,
156 "const ::std::string $classname$::_default_$name$_;");
160 void StringFieldGenerator::
161 GenerateClearingCode(io::Printer* printer) const {
162 if (descriptor_->has_default_value()) {
163 printer->Print(variables_,
164 "if ($name$_ != &_default_$name$_) {\n"
165 " $name$_->assign(_default_$name$_);\n"
166 "}\n");
167 } else {
168 printer->Print(variables_,
169 "if ($name$_ != &_default_$name$_) {\n"
170 " $name$_->clear();\n"
171 "}\n");
175 void StringFieldGenerator::
176 GenerateMergingCode(io::Printer* printer) const {
177 printer->Print(variables_, "set_$name$(from.$name$());\n");
180 void StringFieldGenerator::
181 GenerateInitializer(io::Printer* printer) const {
182 printer->Print(variables_,
183 ",\n$name$_(const_cast< ::std::string*>(&_default_$name$_))");
186 void StringFieldGenerator::
187 GenerateDestructorCode(io::Printer* printer) const {
188 printer->Print(variables_,
189 "if ($name$_ != &_default_$name$_) {\n"
190 " delete $name$_;\n"
191 "}\n");
194 void StringFieldGenerator::
195 GenerateMergeFromCodedStream(io::Printer* printer) const {
196 printer->Print(variables_,
197 "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$("
198 "input, mutable_$name$()));\n");
201 void StringFieldGenerator::
202 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
203 printer->Print(variables_,
204 "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$("
205 "$number$, this->$name$(), output));\n");
208 void StringFieldGenerator::
209 GenerateByteSize(io::Printer* printer) const {
210 printer->Print(variables_,
211 "total_size += $tag_size$ +\n"
212 " ::google::protobuf::internal::WireFormat::$declared_type$Size(this->$name$());\n");
215 // ===================================================================
217 RepeatedStringFieldGenerator::
218 RepeatedStringFieldGenerator(const FieldDescriptor* descriptor)
219 : descriptor_(descriptor) {
220 SetStringVariables(descriptor, &variables_);
223 RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
225 void RepeatedStringFieldGenerator::
226 GeneratePrivateMembers(io::Printer* printer) const {
227 printer->Print(variables_,
228 "::google::protobuf::RepeatedPtrField< ::std::string> $name$_;\n");
231 void RepeatedStringFieldGenerator::
232 GenerateAccessorDeclarations(io::Printer* printer) const {
233 // See comment above about unknown ctypes.
234 if (descriptor_->options().has_ctype()) {
235 printer->Outdent();
236 printer->Print(
237 " private:\n"
238 " // Hidden due to unknown ctype option.\n");
239 printer->Indent();
242 printer->Print(variables_,
243 "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const;\n"
244 "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$();\n"
245 "inline const ::std::string& $name$(int index) const;\n"
246 "inline ::std::string* mutable_$name$(int index);\n"
247 "inline void set_$name$(int index, const ::std::string& value);\n"
248 "inline void set_$name$(int index, const char* value);\n"
249 "inline ::std::string* add_$name$();\n"
250 "inline void add_$name$(const ::std::string& value);\n"
251 "inline void add_$name$(const char* value);\n");
253 if (descriptor_->options().has_ctype()) {
254 printer->Outdent();
255 printer->Print(" public:\n");
256 printer->Indent();
260 void RepeatedStringFieldGenerator::
261 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
262 printer->Print(variables_,
263 "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
264 "$classname$::$name$() const {\n"
265 " return $name$_;\n"
266 "}\n"
267 "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
268 "$classname$::mutable_$name$() {\n"
269 " return &$name$_;\n"
270 "}\n"
271 "inline const ::std::string& $classname$::$name$(int index) const {\n"
272 " return $name$_.Get(index);\n"
273 "}\n"
274 "inline ::std::string* $classname$::mutable_$name$(int index) {\n"
275 " return $name$_.Mutable(index);\n"
276 "}\n"
277 "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
278 " $name$_.Mutable(index)->assign(value);\n"
279 "}\n"
280 "inline void $classname$::set_$name$(int index, const char* value) {\n"
281 " $name$_.Mutable(index)->assign(value);\n"
282 "}\n"
283 "inline ::std::string* $classname$::add_$name$() {\n"
284 " return $name$_.Add();\n"
285 "}\n"
286 "inline void $classname$::add_$name$(const ::std::string& value) {\n"
287 " $name$_.Add()->assign(value);\n"
288 "}\n"
289 "inline void $classname$::add_$name$(const char* value) {\n"
290 " $name$_.Add()->assign(value);\n"
291 "}\n");
294 void RepeatedStringFieldGenerator::
295 GenerateClearingCode(io::Printer* printer) const {
296 printer->Print(variables_, "$name$_.Clear();\n");
299 void RepeatedStringFieldGenerator::
300 GenerateMergingCode(io::Printer* printer) const {
301 printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
304 void RepeatedStringFieldGenerator::
305 GenerateInitializer(io::Printer* printer) const {
306 // Not needed for repeated fields.
309 void RepeatedStringFieldGenerator::
310 GenerateMergeFromCodedStream(io::Printer* printer) const {
311 printer->Print(variables_,
312 "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$(\n"
313 " input, add_$name$()));\n");
316 void RepeatedStringFieldGenerator::
317 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
318 printer->Print(variables_,
319 "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$("
320 "$number$, this->$name$(i), output));\n");
323 void RepeatedStringFieldGenerator::
324 GenerateByteSize(io::Printer* printer) const {
325 printer->Print(variables_,
326 "total_size += $tag_size$ * $name$_size();\n"
327 "for (int i = 0; i < $name$_size(); i++) {\n"
328 " total_size += ::google::protobuf::internal::WireFormat::$declared_type$Size(\n"
329 " this->$name$(i));\n"
330 "}\n");
333 } // namespace cpp
334 } // namespace compiler
335 } // namespace protobuf
336 } // namespace google