Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.cc

Issue 1842653006: Update //third_party/protobuf to version 3. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * 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.
18 //
19 // 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.
30
31 #include <google/protobuf/compiler/cpp/cpp_map_field.h>
32 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
33 #include <google/protobuf/io/printer.h>
34 #include <google/protobuf/wire_format.h>
35 #include <google/protobuf/stubs/strutil.h>
36
37 namespace google {
38 namespace protobuf {
39 namespace compiler {
40 namespace cpp {
41
42 bool IsProto3Field(const FieldDescriptor* field_descriptor) {
43 const FileDescriptor* file_descriptor = field_descriptor->file();
44 return file_descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3;
45 }
46
47 void SetMessageVariables(const FieldDescriptor* descriptor,
48 map<string, string>* variables,
49 const Options& options) {
50 SetCommonFieldVariables(descriptor, variables, options);
51 (*variables)["type"] = FieldMessageTypeName(descriptor);
52 (*variables)["stream_writer"] = (*variables)["declared_type"] +
53 (HasFastArraySerialization(descriptor->message_type()->file()) ?
54 "MaybeToArray" :
55 "");
56 (*variables)["full_name"] = descriptor->full_name();
57
58 const FieldDescriptor* key =
59 descriptor->message_type()->FindFieldByName("key");
60 const FieldDescriptor* val =
61 descriptor->message_type()->FindFieldByName("value");
62 (*variables)["key_cpp"] = PrimitiveTypeName(key->cpp_type());
63 switch (val->cpp_type()) {
64 case FieldDescriptor::CPPTYPE_MESSAGE:
65 (*variables)["val_cpp"] = FieldMessageTypeName(val);
66 (*variables)["wrapper"] = "EntryWrapper";
67 break;
68 case FieldDescriptor::CPPTYPE_ENUM:
69 (*variables)["val_cpp"] = ClassName(val->enum_type(), true);
70 (*variables)["wrapper"] = "EnumEntryWrapper";
71 break;
72 default:
73 (*variables)["val_cpp"] = PrimitiveTypeName(val->cpp_type());
74 (*variables)["wrapper"] = "EntryWrapper";
75 }
76 (*variables)["key_wire_type"] =
77 "::google::protobuf::internal::WireFormatLite::TYPE_" +
78 ToUpper(DeclaredTypeMethodName(key->type()));
79 (*variables)["val_wire_type"] =
80 "::google::protobuf::internal::WireFormatLite::TYPE_" +
81 ToUpper(DeclaredTypeMethodName(val->type()));
82 (*variables)["map_classname"] = ClassName(descriptor->message_type(), false);
83 (*variables)["number"] = SimpleItoa(descriptor->number());
84 (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
85
86 if (HasDescriptorMethods(descriptor->file())) {
87 (*variables)["lite"] = "";
88 } else {
89 (*variables)["lite"] = "Lite";
90 }
91
92 if (!IsProto3Field(descriptor) &&
93 val->type() == FieldDescriptor::TYPE_ENUM) {
94 const EnumValueDescriptor* default_value = val->default_value_enum();
95 (*variables)["default_enum_value"] = Int32ToString(default_value->number());
96 } else {
97 (*variables)["default_enum_value"] = "0";
98 }
99 }
100
101 MapFieldGenerator::
102 MapFieldGenerator(const FieldDescriptor* descriptor,
103 const Options& options)
104 : descriptor_(descriptor),
105 dependent_field_(options.proto_h && IsFieldDependent(descriptor)) {
106 SetMessageVariables(descriptor, &variables_, options);
107 }
108
109 MapFieldGenerator::~MapFieldGenerator() {}
110
111 void MapFieldGenerator::
112 GeneratePrivateMembers(io::Printer* printer) const {
113 printer->Print(variables_,
114 "typedef ::google::protobuf::internal::MapEntryLite<\n"
115 " $key_cpp$, $val_cpp$,\n"
116 " $key_wire_type$,\n"
117 " $val_wire_type$,\n"
118 " $default_enum_value$ >\n"
119 " $map_classname$;\n"
120 "::google::protobuf::internal::MapField$lite$<\n"
121 " $key_cpp$, $val_cpp$,\n"
122 " $key_wire_type$,\n"
123 " $val_wire_type$,\n"
124 " $default_enum_value$ > $name$_;\n");
125 }
126
127 void MapFieldGenerator::
128 GenerateAccessorDeclarations(io::Printer* printer) const {
129 printer->Print(variables_,
130 "const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
131 " $name$() const$deprecation$;\n"
132 "::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n"
133 " mutable_$name$()$deprecation$;\n");
134 }
135
136 void MapFieldGenerator::
137 GenerateInlineAccessorDefinitions(io::Printer* printer,
138 bool is_inline) const {
139 map<string, string> variables(variables_);
140 variables["inline"] = is_inline ? "inline" : "";
141 printer->Print(variables,
142 "$inline$ const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
143 "$classname$::$name$() const {\n"
144 " // @@protoc_insertion_point(field_map:$full_name$)\n"
145 " return $name$_.GetMap();\n"
146 "}\n"
147 "$inline$ ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n"
148 "$classname$::mutable_$name$() {\n"
149 " // @@protoc_insertion_point(field_mutable_map:$full_name$)\n"
150 " return $name$_.MutableMap();\n"
151 "}\n");
152 }
153
154 void MapFieldGenerator::
155 GenerateClearingCode(io::Printer* printer) const {
156 map<string, string> variables(variables_);
157 variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
158 printer->Print(variables, "$this_message$$name$_.Clear();\n");
159 }
160
161 void MapFieldGenerator::
162 GenerateMergingCode(io::Printer* printer) const {
163 printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
164 }
165
166 void MapFieldGenerator::
167 GenerateSwappingCode(io::Printer* printer) const {
168 printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
169 }
170
171 void MapFieldGenerator::
172 GenerateConstructorCode(io::Printer* printer) const {
173 if (HasDescriptorMethods(descriptor_->file())) {
174 printer->Print(variables_,
175 "$name$_.SetAssignDescriptorCallback(\n"
176 " protobuf_AssignDescriptorsOnce);\n"
177 "$name$_.SetEntryDescriptor(\n"
178 " &$type$_descriptor_);\n");
179 }
180 }
181
182 void MapFieldGenerator::
183 GenerateMergeFromCodedStream(io::Printer* printer) const {
184 const FieldDescriptor* value_field =
185 descriptor_->message_type()->FindFieldByName("value");
186 printer->Print(variables_,
187 "::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry()) ;\n");
188
189 if (IsProto3Field(descriptor_) ||
190 value_field->type() != FieldDescriptor::TYPE_ENUM) {
191 printer->Print(variables_,
192 "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( \n"
193 " input, entry.get()));\n");
194 switch (value_field->cpp_type()) {
195 case FieldDescriptor::CPPTYPE_MESSAGE:
196 printer->Print(variables_,
197 "(*mutable_$name$())[entry->key()].Swap("
198 "entry->mutable_value());\n");
199 break;
200 case FieldDescriptor::CPPTYPE_ENUM:
201 printer->Print(variables_,
202 "(*mutable_$name$())[entry->key()] =\n"
203 " static_cast< $val_cpp$ >(*entry->mutable_value());\n");
204 break;
205 default:
206 printer->Print(variables_,
207 "(*mutable_$name$())[entry->key()] = *entry->mutable_value();\n");
208 break;
209 }
210 } else {
211 printer->Print(variables_,
212 "{\n"
213 " ::std::string data;\n"
214 " DO_(::google::protobuf::internal::WireFormatLite::ReadString(input, & data));\n"
215 " DO_(entry->ParseFromString(data));\n"
216 " if ($val_cpp$_IsValid(*entry->mutable_value())) {\n"
217 " (*mutable_$name$())[entry->key()] =\n"
218 " static_cast< $val_cpp$ >(*entry->mutable_value());\n"
219 " } else {\n");
220 if (HasDescriptorMethods(descriptor_->file())) {
221 printer->Print(variables_,
222 " mutable_unknown_fields()"
223 "->AddLengthDelimited($number$, data);\n");
224 } else {
225 printer->Print(variables_,
226 " unknown_fields_stream.WriteVarint32($tag$);\n"
227 " unknown_fields_stream.WriteVarint32(data.size());\n"
228 " unknown_fields_stream.WriteString(data);\n");
229 }
230
231
232 printer->Print(variables_,
233 " }\n"
234 "}\n");
235 }
236
237 const FieldDescriptor* key_field =
238 descriptor_->message_type()->FindFieldByName("key");
239 if (key_field->type() == FieldDescriptor::TYPE_STRING) {
240 GenerateUtf8CheckCodeForString(
241 key_field, true, variables_,
242 "entry->key().data(), entry->key().length(),\n", printer);
243 }
244 if (value_field->type() == FieldDescriptor::TYPE_STRING) {
245 GenerateUtf8CheckCodeForString(
246 value_field, true, variables_,
247 "entry->mutable_value()->data(),\n"
248 "entry->mutable_value()->length(),\n", printer);
249 }
250
251 // If entry is allocated by arena, its desctructor should be avoided.
252 if (SupportsArenas(descriptor_)) {
253 printer->Print(variables_,
254 "if (entry->GetArena() != NULL) entry.release();\n");
255 }
256 }
257
258 void MapFieldGenerator::
259 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
260 printer->Print(variables_,
261 "{\n"
262 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
263 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
264 " it = this->$name$().begin();\n"
265 " it != this->$name$().end(); ++it) {\n");
266
267 // If entry is allocated by arena, its desctructor should be avoided.
268 if (SupportsArenas(descriptor_)) {
269 printer->Print(variables_,
270 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
271 " entry.release();\n"
272 " }\n");
273 }
274
275 printer->Print(variables_,
276 " entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
277 " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n "
278 " $number$, *entry, output);\n");
279
280 printer->Indent();
281 printer->Indent();
282
283 const FieldDescriptor* key_field =
284 descriptor_->message_type()->FindFieldByName("key");
285 const FieldDescriptor* value_field =
286 descriptor_->message_type()->FindFieldByName("value");
287 if (key_field->type() == FieldDescriptor::TYPE_STRING) {
288 GenerateUtf8CheckCodeForString(
289 key_field, false, variables_,
290 "it->first.data(), it->first.length(),\n", printer);
291 }
292 if (value_field->type() == FieldDescriptor::TYPE_STRING) {
293 GenerateUtf8CheckCodeForString(
294 value_field, false, variables_,
295 "it->second.data(), it->second.length(),\n", printer);
296 }
297
298 printer->Outdent();
299 printer->Outdent();
300
301 printer->Print(
302 " }\n");
303
304 // If entry is allocated by arena, its desctructor should be avoided.
305 if (SupportsArenas(descriptor_)) {
306 printer->Print(variables_,
307 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
308 " entry.release();\n"
309 " }\n");
310 }
311
312 printer->Print("}\n");
313 }
314
315 void MapFieldGenerator::
316 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
317 printer->Print(variables_,
318 "{\n"
319 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
320 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
321 " it = this->$name$().begin();\n"
322 " it != this->$name$().end(); ++it) {\n");
323
324 // If entry is allocated by arena, its desctructor should be avoided.
325 if (SupportsArenas(descriptor_)) {
326 printer->Print(variables_,
327 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
328 " entry.release();\n"
329 " }\n");
330 }
331
332 printer->Print(variables_,
333 " entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
334 " target = ::google::protobuf::internal::WireFormatLite::\n"
335 " Write$declared_type$NoVirtualToArray(\n"
336 " $number$, *entry, target);\n");
337
338 printer->Indent();
339 printer->Indent();
340
341 const FieldDescriptor* key_field =
342 descriptor_->message_type()->FindFieldByName("key");
343 const FieldDescriptor* value_field =
344 descriptor_->message_type()->FindFieldByName("value");
345 if (key_field->type() == FieldDescriptor::TYPE_STRING) {
346 GenerateUtf8CheckCodeForString(
347 key_field, false, variables_,
348 "it->first.data(), it->first.length(),\n", printer);
349 }
350 if (value_field->type() == FieldDescriptor::TYPE_STRING) {
351 GenerateUtf8CheckCodeForString(
352 value_field, false, variables_,
353 "it->second.data(), it->second.length(),\n", printer);
354 }
355
356 printer->Outdent();
357 printer->Outdent();
358 printer->Print(
359 " }\n");
360
361 // If entry is allocated by arena, its desctructor should be avoided.
362 if (SupportsArenas(descriptor_)) {
363 printer->Print(variables_,
364 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
365 " entry.release();\n"
366 " }\n");
367 }
368
369 printer->Print("}\n");
370 }
371
372 void MapFieldGenerator::
373 GenerateByteSize(io::Printer* printer) const {
374 printer->Print(variables_,
375 "total_size += $tag_size$ * this->$name$_size();\n"
376 "{\n"
377 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
378 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
379 " it = this->$name$().begin();\n"
380 " it != this->$name$().end(); ++it) {\n");
381
382 // If entry is allocated by arena, its desctructor should be avoided.
383 if (SupportsArenas(descriptor_)) {
384 printer->Print(variables_,
385 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
386 " entry.release();\n"
387 " }\n");
388 }
389
390 printer->Print(variables_,
391 " entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
392 " total_size += ::google::protobuf::internal::WireFormatLite::\n"
393 " $declared_type$SizeNoVirtual(*entry);\n"
394 " }\n");
395
396 // If entry is allocated by arena, its desctructor should be avoided.
397 if (SupportsArenas(descriptor_)) {
398 printer->Print(variables_,
399 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
400 " entry.release();\n"
401 " }\n");
402 }
403
404 printer->Print("}\n");
405 }
406
407 } // namespace cpp
408 } // namespace compiler
409 } // namespace protobuf
410 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698